vendor: 2,248 bytes, lines 1-79
1/*! 2 * jQuery JavaScript Library v3.7.1 3 * https://jquery.com/ 4 * 5 * Copyright OpenJS Foundation and other contributors 6 * Released under the MIT license 7 * https://jquery.org/license 8 * 9 * Date: 2023-08-28T13:37Z 10 */ 11( function( global, factory ) { 12 13 "use strict"; 14 15 if ( typeof module === "object" && typeof module.exports === "object" ) { 16 17 // For CommonJS and CommonJS-like environments where a proper `window` 18 // is present, execute the factory and get jQuery. 19 // For environments that do not have a `window` with a `document` 20 // (such as Node.js), expose a factory as module.exports. 21 // This accentuates the need for the creation of a real `window`. 22 // e.g. var jQuery = require("jquery")(window); 23 // See ticket trac-14549 for more info. 24 module.exports = global.document ? 25 factory( global, true ) : 26 function( w ) { 27 if ( !w.document ) { 28 throw new Error( "jQuery requires a window with a document" ); 29 } 30 return factory( w ); 31 }; 32 } else { 33 factory( global ); 34 } 35 36// Pass this if window is not defined yet 37} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 38 39// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 40// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 41// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 42// enough that all such attempts are guarded in a try block. 43"use strict"; 44 45var arr = []; 46 47var getProto = Object.getPrototypeOf; 48 49var slice = arr.slice; 50 51var flat = arr.flat ? function( array ) { 52 return arr.flat.call( array ); 53} : function( array ) { 54 return arr.concat.apply( [], array ); 55}; 56 57 58var push = arr.push; 59 60var indexOf = arr.indexOf; 61 62var class2type = {}; 63 64var toString = class2type.toString; 65 66var hasOwn = class2type.hasOwnProperty; 67 68var fnToString = hasOwn.toString; 69 70var ObjectFunctionString = fnToString.call( Object ); 71 72var support = {}; 73 74var isFunction = function isFunction( obj ) { 75 76 // Support: Chrome <=57, Firefox <=52 77 // In some browsers, typeof returns "function" for HTML <object> elements 78 // (i.e., `typeof document.createElement( "object" ) === "function"`). 79 // We don't want to classify *any* DOM node as a function.
vendor: 10,176 bytes, lines 80-508
80 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 81 // Plus for old WebKit, typeof returns "function" for HTML collections 82 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) 83 return typeof obj === "function" && typeof obj.nodeType !== "number" && 84 typeof obj.item !== "function"; 85 }; 86 87 88var isWindow = function isWindow( obj ) { 89 return obj != null && obj === obj.window; 90 }; 91 92 93var document = window.document; 94 95 96 97 var preservedScriptAttributes = { 98 type: true, 99 src: true, 100 nonce: true, 101 noModule: true 102 }; 103 104 function DOMEval( code, node, doc ) { 105 doc = doc || document; 106 107 var i, val, 108 script = doc.createElement( "script" ); 109 110 script.text = code; 111 if ( node ) { 112 for ( i in preservedScriptAttributes ) { 113 114 // Support: Firefox 64+, Edge 18+ 115 // Some browsers don't support the "nonce" property on scripts. 116 // On the other hand, just using `getAttribute` is not enough as 117 // the `nonce` attribute is reset to an empty string whenever it 118 // becomes browsing-context connected. 119 // See https://github.com/whatwg/html/issues/2369 120 // See https://html.spec.whatwg.org/#nonce-attributes 121 // The `node.getAttribute` check was added for the sake of 122 // `jQuery.globalEval` so that it can fake a nonce-containing node 123 // via an object. 124 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 125 if ( val ) { 126 script.setAttribute( i, val ); 127 } 128 } 129 } 130 doc.head.appendChild( script ).parentNode.removeChild( script ); 131 } 132 133 134function toType( obj ) { 135 if ( obj == null ) { 136 return obj + ""; 137 } 138 139 // Support: Android <=2.3 only (functionish RegExp) 140 return typeof obj === "object" || typeof obj === "function" ? 141 class2type[ toString.call( obj ) ] || "object" : 142 typeof obj; 143} 144/* global Symbol */ 145// Defining this global in .eslintrc.json would create a danger of using the global 146// unguarded in another place, it seems safer to define global only for this module 147 148 149 150var version = "3.7.1", 151 152 rhtmlSuffix = /HTML$/i, 153 154 // Define a local copy of jQuery 155 jQuery = function( selector, context ) { 156 157 // The jQuery object is actually just the init constructor 'enhanced' 158 // Need init if jQuery is called (just allow error to be thrown if not included) 159 return new jQuery.fn.init( selector, context ); 160 }; 161 162jQuery.fn = jQuery.prototype = { 163 164 // The current version of jQuery being used 165 jquery: version, 166 167 constructor: jQuery, 168 169 // The default length of a jQuery object is 0 170 length: 0, 171 172 toArray: function() { 173 return slice.call( this ); 174 }, 175 176 // Get the Nth element in the matched element set OR 177 // Get the whole matched element set as a clean array 178 get: function( num ) { 179 180 // Return all the elements in a clean array 181 if ( num == null ) { 182 return slice.call( this ); 183 } 184 185 // Return just the one element from the set 186 return num < 0 ? this[ num + this.length ] : this[ num ]; 187 }, 188 189 // Take an array of elements and push it onto the stack 190 // (returning the new matched element set) 191 pushStack: function( elems ) { 192 193 // Build a new jQuery matched element set 194 var ret = jQuery.merge( this.constructor(), elems ); 195 196 // Add the old object onto the stack (as a reference) 197 ret.prevObject = this; 198 199 // Return the newly-formed element set 200 return ret; 201 }, 202 203 // Execute a callback for every element in the matched set. 204 each: function( callback ) { 205 return jQuery.each( this, callback ); 206 }, 207 208 map: function( callback ) { 209 return this.pushStack( jQuery.map( this, function( elem, i ) { 210 return callback.call( elem, i, elem ); 211 } ) ); 212 }, 213 214 slice: function() { 215 return this.pushStack( slice.apply( this, arguments ) ); 216 }, 217 218 first: function() { 219 return this.eq( 0 ); 220 }, 221 222 last: function() { 223 return this.eq( -1 ); 224 }, 225 226 even: function() { 227 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 228 return ( i + 1 ) % 2; 229 } ) ); 230 }, 231 232 odd: function() { 233 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 234 return i % 2; 235 } ) ); 236 }, 237 238 eq: function( i ) { 239 var len = this.length, 240 j = +i + ( i < 0 ? len : 0 ); 241 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 242 }, 243 244 end: function() { 245 return this.prevObject || this.constructor(); 246 }, 247 248 // For internal use only. 249 // Behaves like an Array's method, not like a jQuery method. 250 push: push, 251 sort: arr.sort, 252 splice: arr.splice 253}; 254 255jQuery.extend = jQuery.fn.extend = function() { 256 var options, name, src, copy, copyIsArray, clone, 257 target = arguments[ 0 ] || {}, 258 i = 1, 259 length = arguments.length, 260 deep = false; 261 262 // Handle a deep copy situation 263 if ( typeof target === "boolean" ) { 264 deep = target; 265 266 // Skip the boolean and the target 267 target = arguments[ i ] || {}; 268 i++; 269 } 270 271 // Handle case when target is a string or something (possible in deep copy) 272 if ( typeof target !== "object" && !isFunction( target ) ) { 273 target = {}; 274 } 275 276 // Extend jQuery itself if only one argument is passed 277 if ( i === length ) { 278 target = this; 279 i--; 280 } 281 282 for ( ; i < length; i++ ) { 283 284 // Only deal with non-null/undefined values 285 if ( ( options = arguments[ i ] ) != null ) { 286 287 // Extend the base object 288 for ( name in options ) { 289 copy = options[ name ]; 290 291 // Prevent Object.prototype pollution 292 // Prevent never-ending loop 293 if ( name === "__proto__" || target === copy ) { 294 continue; 295 } 296 297 // Recurse if we're merging plain objects or arrays 298 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 299 ( copyIsArray = Array.isArray( copy ) ) ) ) { 300 src = target[ name ]; 301 302 // Ensure proper type for the source value 303 if ( copyIsArray && !Array.isArray( src ) ) { 304 clone = []; 305 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 306 clone = {}; 307 } else { 308 clone = src; 309 } 310 copyIsArray = false; 311 312 // Never move original objects, clone them 313 target[ name ] = jQuery.extend( deep, clone, copy ); 314 315 // Don't bring in undefined values 316 } else if ( copy !== undefined ) { 317 target[ name ] = copy; 318 } 319 } 320 } 321 } 322 323 // Return the modified object 324 return target; 325}; 326 327jQuery.extend( { 328 329 // Unique for each copy of jQuery on the page 330 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 331 332 // Assume jQuery is ready without the ready module 333 isReady: true, 334 335 error: function( msg ) { 336 throw new Error( msg ); 337 }, 338 339 noop: function() {}, 340 341 isPlainObject: function( obj ) { 342 var proto, Ctor; 343 344 // Detect obvious negatives 345 // Use toString instead of jQuery.type to catch host objects 346 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 347 return false; 348 } 349 350 proto = getProto( obj ); 351 352 // Objects with no prototype (e.g., `Object.create( null )`) are plain 353 if ( !proto ) { 354 return true; 355 } 356 357 // Objects with prototype are plain iff they were constructed by a global Object function 358 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 359 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 360 }, 361 362 isEmptyObject: function( obj ) { 363 var name; 364 365 for ( name in obj ) { 366 return false; 367 } 368 return true; 369 }, 370 371 // Evaluates a script in a provided context; falls back to the global one 372 // if not specified. 373 globalEval: function( code, options, doc ) { 374 DOMEval( code, { nonce: options && options.nonce }, doc ); 375 }, 376 377 each: function( obj, callback ) { 378 var length, i = 0; 379 380 if ( isArrayLike( obj ) ) { 381 length = obj.length; 382 for ( ; i < length; i++ ) { 383 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 384 break; 385 } 386 } 387 } else { 388 for ( i in obj ) { 389 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 390 break; 391 } 392 } 393 } 394 395 return obj; 396 }, 397 398 399 // Retrieve the text value of an array of DOM nodes 400 text: function( elem ) { 401 var node, 402 ret = "", 403 i = 0, 404 nodeType = elem.nodeType; 405 406 if ( !nodeType ) { 407 408 // If no nodeType, this is expected to be an array 409 while ( ( node = elem[ i++ ] ) ) { 410 411 // Do not traverse comment nodes 412 ret += jQuery.text( node ); 413 } 414 } 415 if ( nodeType === 1 || nodeType === 11 ) { 416 return elem.textContent; 417 } 418 if ( nodeType === 9 ) { 419 return elem.documentElement.textContent; 420 } 421 if ( nodeType === 3 || nodeType === 4 ) { 422 return elem.nodeValue; 423 } 424 425 // Do not include comment or processing instruction nodes 426 427 return ret; 428 }, 429 430 // results is for internal usage only 431 makeArray: function( arr, results ) { 432 var ret = results || []; 433 434 if ( arr != null ) { 435 if ( isArrayLike( Object( arr ) ) ) { 436 jQuery.merge( ret, 437 typeof arr === "string" ? 438 [ arr ] : arr 439 ); 440 } else { 441 push.call( ret, arr ); 442 } 443 } 444 445 return ret; 446 }, 447 448 inArray: function( elem, arr, i ) { 449 return arr == null ? -1 : indexOf.call( arr, elem, i ); 450 }, 451 452 isXMLDoc: function( elem ) { 453 var namespace = elem && elem.namespaceURI, 454 docElem = elem && ( elem.ownerDocument || elem ).documentElement; 455 456 // Assume HTML when documentElement doesn't yet exist, such as inside 457 // document fragments. 458 return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" ); 459 }, 460 461 // Support: Android <=4.0 only, PhantomJS 1 only 462 // push.apply(_, arraylike) throws on ancient WebKit 463 merge: function( first, second ) { 464 var len = +second.length, 465 j = 0, 466 i = first.length; 467 468 for ( ; j < len; j++ ) { 469 first[ i++ ] = second[ j ]; 470 } 471 472 first.length = i; 473 474 return first; 475 }, 476 477 grep: function( elems, callback, invert ) { 478 var callbackInverse, 479 matches = [], 480 i = 0, 481 length = elems.length, 482 callbackExpect = !invert; 483 484 // Go through the array, only saving the items 485 // that pass the validator function 486 for ( ; i < length; i++ ) { 487 callbackInverse = !callback( elems[ i ], i ); 488 if ( callbackInverse !== callbackExpect ) { 489 matches.push( elems[ i ] ); 490 } 491 } 492 493 return matches; 494 }, 495 496 // arg is for internal usage only 497 map: function( elems, callback, arg ) { 498 var length, value, 499 i = 0, 500 ret = []; 501 502 // Go through the array, translating each of the items to their new values 503 if ( isArrayLike( elems ) ) { 504 length = elems.length; 505 for ( ; i < length; i++ ) { 506 value = callback( elems[ i ], i, arg ); 507 508 if ( value != null ) {
vendor: 17,514 bytes, lines 509-1130
509 ret.push( value ); 510 } 511 } 512 513 // Go through every key on the object, 514 } else { 515 for ( i in elems ) { 516 value = callback( elems[ i ], i, arg ); 517 518 if ( value != null ) { 519 ret.push( value ); 520 } 521 } 522 } 523 524 // Flatten any nested arrays 525 return flat( ret ); 526 }, 527 528 // A global GUID counter for objects 529 guid: 1, 530 531 // jQuery.support is not used in Core but other projects attach their 532 // properties to it so it needs to exist. 533 support: support 534} ); 535 536if ( typeof Symbol === "function" ) { 537 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 538} 539 540// Populate the class2type map 541jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 542 function( _i, name ) { 543 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 544 } ); 545 546function isArrayLike( obj ) { 547 548 // Support: real iOS 8.2 only (not reproducible in simulator) 549 // `in` check used to prevent JIT error (gh-2145) 550 // hasOwn isn't used here due to false negatives 551 // regarding Nodelist length in IE 552 var length = !!obj && "length" in obj && obj.length, 553 type = toType( obj ); 554 555 if ( isFunction( obj ) || isWindow( obj ) ) { 556 return false; 557 } 558 559 return type === "array" || length === 0 || 560 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 561} 562 563 564function nodeName( elem, name ) { 565 566 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 567 568} 569var pop = arr.pop; 570 571 572var sort = arr.sort; 573 574 575var splice = arr.splice; 576 577 578var whitespace = "[\\x20\\t\\r\\n\\f]"; 579 580 581var rtrimCSS = new RegExp( 582 "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", 583 "g" 584); 585 586 587 588 589// Note: an element does not contain itself 590jQuery.contains = function( a, b ) { 591 var bup = b && b.parentNode; 592 593 return a === bup || !!( bup && bup.nodeType === 1 && ( 594 595 // Support: IE 9 - 11+ 596 // IE doesn't have `contains` on SVG. 597 a.contains ? 598 a.contains( bup ) : 599 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 600 ) ); 601}; 602 603 604 605 606// CSS string/identifier serialization 607// https://drafts.csswg.org/cssom/#common-serializing-idioms 608var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 609 610function fcssescape( ch, asCodePoint ) { 611 if ( asCodePoint ) { 612 613 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 614 if ( ch === "\0" ) { 615 return "\uFFFD"; 616 } 617 618 // Control characters and (dependent upon position) numbers get escaped as code points 619 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 620 } 621 622 // Other potentially-special ASCII characters get backslash-escaped 623 return "\\" + ch; 624} 625 626jQuery.escapeSelector = function( sel ) { 627 return ( sel + "" ).replace( rcssescape, fcssescape ); 628}; 629 630 631 632 633var preferredDoc = document, 634 pushNative = push; 635 636( function() { 637 638var i, 639 Expr, 640 outermostContext, 641 sortInput, 642 hasDuplicate, 643 push = pushNative, 644 645 // Local document vars 646 document, 647 documentElement, 648 documentIsHTML, 649 rbuggyQSA, 650 matches, 651 652 // Instance-specific data 653 expando = jQuery.expando, 654 dirruns = 0, 655 done = 0, 656 classCache = createCache(), 657 tokenCache = createCache(), 658 compilerCache = createCache(), 659 nonnativeSelectorCache = createCache(), 660 sortOrder = function( a, b ) { 661 if ( a === b ) { 662 hasDuplicate = true; 663 } 664 return 0; 665 }, 666 667 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" + 668 "loop|multiple|open|readonly|required|scoped", 669 670 // Regular expressions 671 672 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 673 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 674 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 675 676 // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors 677 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 678 679 // Operator (capture 2) 680 "*([*^$|!~]?=)" + whitespace + 681 682 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 683 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 684 whitespace + "*\\]", 685 686 pseudos = ":(" + identifier + ")(?:\\((" + 687 688 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 689 // 1. quoted (capture 3; capture 4 or capture 5) 690 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 691 692 // 2. simple (capture 6) 693 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 694 695 // 3. anything else (capture 2) 696 ".*" + 697 ")\\)|)", 698 699 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 700 rwhitespace = new RegExp( whitespace + "+", "g" ), 701 702 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 703 rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + 704 whitespace + "*" ), 705 rdescend = new RegExp( whitespace + "|>" ), 706 707 rpseudo = new RegExp( pseudos ), 708 ridentifier = new RegExp( "^" + identifier + "$" ), 709 710 matchExpr = { 711 ID: new RegExp( "^#(" + identifier + ")" ), 712 CLASS: new RegExp( "^\\.(" + identifier + ")" ), 713 TAG: new RegExp( "^(" + identifier + "|[*])" ), 714 ATTR: new RegExp( "^" + attributes ), 715 PSEUDO: new RegExp( "^" + pseudos ), 716 CHILD: new RegExp( 717 "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 718 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 719 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 720 bool: new RegExp( "^(?:" + booleans + ")$", "i" ), 721 722 // For use in libraries implementing .is() 723 // We use this for POS matching in `select` 724 needsContext: new RegExp( "^" + whitespace + 725 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 726 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 727 }, 728 729 rinputs = /^(?:input|select|textarea|button)$/i, 730 rheader = /^h\d$/i, 731 732 // Easily-parseable/retrievable ID or TAG or CLASS selectors 733 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 734 735 rsibling = /[+~]/, 736 737 // CSS escapes 738 // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters 739 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + 740 "?|\\\\([^\\r\\n\\f])", "g" ), 741 funescape = function( escape, nonHex ) { 742 var high = "0x" + escape.slice( 1 ) - 0x10000; 743 744 if ( nonHex ) { 745 746 // Strip the backslash prefix from a non-hex escape sequence 747 return nonHex; 748 } 749 750 // Replace a hexadecimal escape sequence with the encoded Unicode code point 751 // Support: IE <=11+ 752 // For values outside the Basic Multilingual Plane (BMP), manually construct a 753 // surrogate pair 754 return high < 0 ? 755 String.fromCharCode( high + 0x10000 ) : 756 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 757 }, 758 759 // Used for iframes; see `setDocument`. 760 // Support: IE 9 - 11+, Edge 12 - 18+ 761 // Removing the function wrapper causes a "Permission Denied" 762 // error in IE/Edge. 763 unloadHandler = function() { 764 setDocument(); 765 }, 766 767 inDisabledFieldset = addCombinator( 768 function( elem ) { 769 return elem.disabled === true && nodeName( elem, "fieldset" ); 770 }, 771 { dir: "parentNode", next: "legend" } 772 ); 773 774// Support: IE <=9 only 775// Accessing document.activeElement can throw unexpectedly 776// https://bugs.jquery.com/ticket/13393 777function safeActiveElement() { 778 try { 779 return document.activeElement; 780 } catch ( err ) { } 781} 782 783// Optimize for push.apply( _, NodeList ) 784try { 785 push.apply( 786 ( arr = slice.call( preferredDoc.childNodes ) ), 787 preferredDoc.childNodes 788 ); 789 790 // Support: Android <=4.0 791 // Detect silently failing push.apply 792 // eslint-disable-next-line no-unused-expressions 793 arr[ preferredDoc.childNodes.length ].nodeType; 794} catch ( e ) { 795 push = { 796 apply: function( target, els ) { 797 pushNative.apply( target, slice.call( els ) ); 798 }, 799 call: function( target ) { 800 pushNative.apply( target, slice.call( arguments, 1 ) ); 801 } 802 }; 803} 804 805function find( selector, context, results, seed ) { 806 var m, i, elem, nid, match, groups, newSelector, 807 newContext = context && context.ownerDocument, 808 809 // nodeType defaults to 9, since context defaults to document 810 nodeType = context ? context.nodeType : 9; 811 812 results = results || []; 813 814 // Return early from calls with invalid selector or context 815 if ( typeof selector !== "string" || !selector || 816 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 817 818 return results; 819 } 820 821 // Try to shortcut find operations (as opposed to filters) in HTML documents 822 if ( !seed ) { 823 setDocument( context ); 824 context = context || document; 825 826 if ( documentIsHTML ) { 827 828 // If the selector is sufficiently simple, try using a "get*By*" DOM method 829 // (excepting DocumentFragment context, where the methods don't exist) 830 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 831 832 // ID selector 833 if ( ( m = match[ 1 ] ) ) { 834 835 // Document context 836 if ( nodeType === 9 ) { 837 if ( ( elem = context.getElementById( m ) ) ) { 838 839 // Support: IE 9 only 840 // getElementById can match elements by name instead of ID 841 if ( elem.id === m ) { 842 push.call( results, elem ); 843 return results; 844 } 845 } else { 846 return results; 847 } 848 849 // Element context 850 } else { 851 852 // Support: IE 9 only 853 // getElementById can match elements by name instead of ID 854 if ( newContext && ( elem = newContext.getElementById( m ) ) && 855 find.contains( context, elem ) && 856 elem.id === m ) { 857 858 push.call( results, elem ); 859 return results; 860 } 861 } 862 863 // Type selector 864 } else if ( match[ 2 ] ) { 865 push.apply( results, context.getElementsByTagName( selector ) ); 866 return results; 867 868 // Class selector 869 } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) { 870 push.apply( results, context.getElementsByClassName( m ) ); 871 return results; 872 } 873 } 874 875 // Take advantage of querySelectorAll 876 if ( !nonnativeSelectorCache[ selector + " " ] && 877 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) { 878 879 newSelector = selector; 880 newContext = context; 881 882 // qSA considers elements outside a scoping root when evaluating child or 883 // descendant combinators, which is not what we want. 884 // In such cases, we work around the behavior by prefixing every selector in the 885 // list with an ID selector referencing the scope context. 886 // The technique has to be used as well when a leading combinator is used 887 // as such selectors are not recognized by querySelectorAll. 888 // Thanks to Andrew Dupont for this technique. 889 if ( nodeType === 1 && 890 ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { 891 892 // Expand context for sibling selectors 893 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 894 context; 895 896 // We can use :scope instead of the ID hack if the browser 897 // supports it & if we're not changing the context. 898 // Support: IE 11+, Edge 17 - 18+ 899 // IE/Edge sometimes throw a "Permission denied" error when 900 // strict-comparing two documents; shallow comparisons work. 901 // eslint-disable-next-line eqeqeq 902 if ( newContext != context || !support.scope ) { 903 904 // Capture the context ID, setting it first if necessary 905 if ( ( nid = context.getAttribute( "id" ) ) ) { 906 nid = jQuery.escapeSelector( nid ); 907 } else { 908 context.setAttribute( "id", ( nid = expando ) ); 909 } 910 } 911 912 // Prefix every selector in the list 913 groups = tokenize( selector ); 914 i = groups.length; 915 while ( i-- ) { 916 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 917 toSelector( groups[ i ] ); 918 } 919 newSelector = groups.join( "," ); 920 } 921 922 try { 923 push.apply( results, 924 newContext.querySelectorAll( newSelector ) 925 ); 926 return results; 927 } catch ( qsaError ) { 928 nonnativeSelectorCache( selector, true ); 929 } finally { 930 if ( nid === expando ) { 931 context.removeAttribute( "id" ); 932 } 933 } 934 } 935 } 936 } 937 938 // All others 939 return select( selector.replace( rtrimCSS, "$1" ), context, results, seed ); 940} 941 942/** 943 * Create key-value caches of limited size 944 * @returns {function(string, object)} Returns the Object data after storing it on itself with 945 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 946 * deleting the oldest entry 947 */ 948function createCache() { 949 var keys = []; 950 951 function cache( key, value ) { 952 953 // Use (key + " ") to avoid collision with native prototype properties 954 // (see https://github.com/jquery/sizzle/issues/157) 955 if ( keys.push( key + " " ) > Expr.cacheLength ) { 956 957 // Only keep the most recent entries 958 delete cache[ keys.shift() ]; 959 } 960 return ( cache[ key + " " ] = value ); 961 } 962 return cache; 963} 964 965/** 966 * Mark a function for special use by jQuery selector module 967 * @param {Function} fn The function to mark 968 */ 969function markFunction( fn ) { 970 fn[ expando ] = true; 971 return fn; 972} 973 974/** 975 * Support testing using an element 976 * @param {Function} fn Passed the created element and returns a boolean result 977 */ 978function assert( fn ) { 979 var el = document.createElement( "fieldset" ); 980 981 try { 982 return !!fn( el ); 983 } catch ( e ) { 984 return false; 985 } finally { 986 987 // Remove from its parent by default 988 if ( el.parentNode ) { 989 el.parentNode.removeChild( el ); 990 } 991 992 // release memory in IE 993 el = null; 994 } 995} 996 997/** 998 * Returns a function to use in pseudos for input types 999 * @param {String} type 1000 */ 1001function createInputPseudo( type ) { 1002 return function( elem ) { 1003 return nodeName( elem, "input" ) && elem.type === type; 1004 }; 1005} 1006 1007/** 1008 * Returns a function to use in pseudos for buttons 1009 * @param {String} type 1010 */ 1011function createButtonPseudo( type ) { 1012 return function( elem ) { 1013 return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) && 1014 elem.type === type; 1015 }; 1016} 1017 1018/** 1019 * Returns a function to use in pseudos for :enabled/:disabled 1020 * @param {Boolean} disabled true for :disabled; false for :enabled 1021 */ 1022function createDisabledPseudo( disabled ) { 1023 1024 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 1025 return function( elem ) { 1026 1027 // Only certain elements can match :enabled or :disabled 1028 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 1029 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 1030 if ( "form" in elem ) { 1031 1032 // Check for inherited disabledness on relevant non-disabled elements: 1033 // * listed form-associated elements in a disabled fieldset 1034 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 1035 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 1036 // * option elements in a disabled optgroup 1037 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 1038 // All such elements have a "form" property. 1039 if ( elem.parentNode && elem.disabled === false ) { 1040 1041 // Option elements defer to a parent optgroup if present 1042 if ( "label" in elem ) { 1043 if ( "label" in elem.parentNode ) { 1044 return elem.parentNode.disabled === disabled; 1045 } else { 1046 return elem.disabled === disabled; 1047 } 1048 } 1049 1050 // Support: IE 6 - 11+ 1051 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 1052 return elem.isDisabled === disabled || 1053 1054 // Where there is no isDisabled, check manually 1055 elem.isDisabled !== !disabled && 1056 inDisabledFieldset( elem ) === disabled; 1057 } 1058 1059 return elem.disabled === disabled; 1060 1061 // Try to winnow out elements that can't be disabled before trusting the disabled property. 1062 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 1063 // even exist on them, let alone have a boolean value. 1064 } else if ( "label" in elem ) { 1065 return elem.disabled === disabled; 1066 } 1067 1068 // Remaining elements are neither :enabled nor :disabled 1069 return false; 1070 }; 1071} 1072 1073/** 1074 * Returns a function to use in pseudos for positionals 1075 * @param {Function} fn 1076 */ 1077function createPositionalPseudo( fn ) { 1078 return markFunction( function( argument ) { 1079 argument = +argument; 1080 return markFunction( function( seed, matches ) { 1081 var j, 1082 matchIndexes = fn( [], seed.length, argument ), 1083 i = matchIndexes.length; 1084 1085 // Match elements found at the specified indexes 1086 while ( i-- ) { 1087 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 1088 seed[ j ] = !( matches[ j ] = seed[ j ] ); 1089 } 1090 } 1091 } ); 1092 } ); 1093} 1094 1095/** 1096 * Checks a node for validity as a jQuery selector context 1097 * @param {Element|Object=} context 1098 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1099 */ 1100function testContext( context ) { 1101 return context && typeof context.getElementsByTagName !== "undefined" && context; 1102} 1103 1104/** 1105 * Sets document-related variables once based on the current document 1106 * @param {Element|Object} [node] An element or document object to use to set the document 1107 * @returns {Object} Returns the current document 1108 */ 1109function setDocument( node ) { 1110 var subWindow, 1111 doc = node ? node.ownerDocument || node : preferredDoc; 1112 1113 // Return early if doc is invalid or already selected 1114 // Support: IE 11+, Edge 17 - 18+ 1115 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1116 // two documents; shallow comparisons work. 1117 // eslint-disable-next-line eqeqeq 1118 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 1119 return document; 1120 } 1121 1122 // Update global variables 1123 document = doc; 1124 documentElement = document.documentElement; 1125 documentIsHTML = !jQuery.isXMLDoc( document ); 1126 1127 // Support: iOS 7 only, IE 9 - 11+ 1128 // Older browsers didn't support unprefixed `matches`. 1129 matches = documentElement.matches || 1130 documentElement.webkitMatchesSelector ||
vendor: 4,667 bytes, lines 1131-1282
1131 documentElement.msMatchesSelector; 1132 1133 // Support: IE 9 - 11+, Edge 12 - 18+ 1134 // Accessing iframe documents after unload throws "permission denied" errors 1135 // (see trac-13936). 1136 // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`, 1137 // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well. 1138 if ( documentElement.msMatchesSelector && 1139 1140 // Support: IE 11+, Edge 17 - 18+ 1141 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1142 // two documents; shallow comparisons work. 1143 // eslint-disable-next-line eqeqeq 1144 preferredDoc != document && 1145 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 1146 1147 // Support: IE 9 - 11+, Edge 12 - 18+ 1148 subWindow.addEventListener( "unload", unloadHandler ); 1149 } 1150 1151 // Support: IE <10 1152 // Check if getElementById returns elements by name 1153 // The broken getElementById methods don't pick up programmatically-set names, 1154 // so use a roundabout getElementsByName test 1155 support.getById = assert( function( el ) { 1156 documentElement.appendChild( el ).id = jQuery.expando; 1157 return !document.getElementsByName || 1158 !document.getElementsByName( jQuery.expando ).length; 1159 } ); 1160 1161 // Support: IE 9 only 1162 // Check to see if it's possible to do matchesSelector 1163 // on a disconnected node. 1164 support.disconnectedMatch = assert( function( el ) { 1165 return matches.call( el, "*" ); 1166 } ); 1167 1168 // Support: IE 9 - 11+, Edge 12 - 18+ 1169 // IE/Edge don't support the :scope pseudo-class. 1170 support.scope = assert( function() { 1171 return document.querySelectorAll( ":scope" ); 1172 } ); 1173 1174 // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only 1175 // Make sure the `:has()` argument is parsed unforgivingly. 1176 // We include `*` in the test to detect buggy implementations that are 1177 // _selectively_ forgiving (specifically when the list includes at least 1178 // one valid selector). 1179 // Note that we treat complete lack of support for `:has()` as if it were 1180 // spec-compliant support, which is fine because use of `:has()` in such 1181 // environments will fail in the qSA path and fall back to jQuery traversal 1182 // anyway. 1183 support.cssHas = assert( function() { 1184 try { 1185 document.querySelector( ":has(*,:jqfake)" ); 1186 return false; 1187 } catch ( e ) { 1188 return true; 1189 } 1190 } ); 1191 1192 // ID filter and find 1193 if ( support.getById ) { 1194 Expr.filter.ID = function( id ) { 1195 var attrId = id.replace( runescape, funescape ); 1196 return function( elem ) { 1197 return elem.getAttribute( "id" ) === attrId; 1198 }; 1199 }; 1200 Expr.find.ID = function( id, context ) { 1201 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1202 var elem = context.getElementById( id ); 1203 return elem ? [ elem ] : []; 1204 } 1205 }; 1206 } else { 1207 Expr.filter.ID = function( id ) { 1208 var attrId = id.replace( runescape, funescape ); 1209 return function( elem ) { 1210 var node = typeof elem.getAttributeNode !== "undefined" && 1211 elem.getAttributeNode( "id" ); 1212 return node && node.value === attrId; 1213 }; 1214 }; 1215 1216 // Support: IE 6 - 7 only 1217 // getElementById is not reliable as a find shortcut 1218 Expr.find.ID = function( id, context ) { 1219 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1220 var node, i, elems, 1221 elem = context.getElementById( id ); 1222 1223 if ( elem ) { 1224 1225 // Verify the id attribute 1226 node = elem.getAttributeNode( "id" ); 1227 if ( node && node.value === id ) { 1228 return [ elem ]; 1229 } 1230 1231 // Fall back on getElementsByName 1232 elems = context.getElementsByName( id ); 1233 i = 0; 1234 while ( ( elem = elems[ i++ ] ) ) { 1235 node = elem.getAttributeNode( "id" ); 1236 if ( node && node.value === id ) { 1237 return [ elem ]; 1238 } 1239 } 1240 } 1241 1242 return []; 1243 } 1244 }; 1245 } 1246 1247 // Tag 1248 Expr.find.TAG = function( tag, context ) { 1249 if ( typeof context.getElementsByTagName !== "undefined" ) { 1250 return context.getElementsByTagName( tag ); 1251 1252 // DocumentFragment nodes don't have gEBTN 1253 } else { 1254 return context.querySelectorAll( tag ); 1255 } 1256 }; 1257 1258 // Class 1259 Expr.find.CLASS = function( className, context ) { 1260 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 1261 return context.getElementsByClassName( className ); 1262 } 1263 }; 1264 1265 /* QSA/matchesSelector 1266 ---------------------------------------------------------------------- */ 1267 1268 // QSA and matchesSelector support 1269 1270 rbuggyQSA = []; 1271 1272 // Build QSA regex 1273 // Regex strategy adopted from Diego Perini 1274 assert( function( el ) { 1275 1276 var input; 1277 1278 documentElement.appendChild( el ).innerHTML = 1279 "<a id='" + expando + "' href='' disabled='disabled'></a>" + 1280 "<select id='" + expando + "-\r\\' disabled='disabled'>" + 1281 "<option selected=''></option></select>"; 1282
vendor: 38,614 bytes, lines 1283-2654
1283 // Support: iOS <=7 - 8 only 1284 // Boolean attributes and "value" are not treated correctly in some XML documents 1285 if ( !el.querySelectorAll( "[selected]" ).length ) { 1286 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 1287 } 1288 1289 // Support: iOS <=7 - 8 only 1290 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 1291 rbuggyQSA.push( "~=" ); 1292 } 1293 1294 // Support: iOS 8 only 1295 // https://bugs.webkit.org/show_bug.cgi?id=136851 1296 // In-page `selector#id sibling-combinator selector` fails 1297 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 1298 rbuggyQSA.push( ".#.+[+~]" ); 1299 } 1300 1301 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 1302 // In some of the document kinds, these selectors wouldn't work natively. 1303 // This is probably OK but for backwards compatibility we want to maintain 1304 // handling them through jQuery traversal in jQuery 3.x. 1305 if ( !el.querySelectorAll( ":checked" ).length ) { 1306 rbuggyQSA.push( ":checked" ); 1307 } 1308 1309 // Support: Windows 8 Native Apps 1310 // The type and name attributes are restricted during .innerHTML assignment 1311 input = document.createElement( "input" ); 1312 input.setAttribute( "type", "hidden" ); 1313 el.appendChild( input ).setAttribute( "name", "D" ); 1314 1315 // Support: IE 9 - 11+ 1316 // IE's :disabled selector does not pick up the children of disabled fieldsets 1317 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 1318 // In some of the document kinds, these selectors wouldn't work natively. 1319 // This is probably OK but for backwards compatibility we want to maintain 1320 // handling them through jQuery traversal in jQuery 3.x. 1321 documentElement.appendChild( el ).disabled = true; 1322 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 1323 rbuggyQSA.push( ":enabled", ":disabled" ); 1324 } 1325 1326 // Support: IE 11+, Edge 15 - 18+ 1327 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 1328 // Adding a temporary attribute to the document before the selection works 1329 // around the issue. 1330 // Interestingly, IE 10 & older don't seem to have the issue. 1331 input = document.createElement( "input" ); 1332 input.setAttribute( "name", "" ); 1333 el.appendChild( input ); 1334 if ( !el.querySelectorAll( "[name='']" ).length ) { 1335 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 1336 whitespace + "*(?:''|\"\")" ); 1337 } 1338 } ); 1339 1340 if ( !support.cssHas ) { 1341 1342 // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ 1343 // Our regular `try-catch` mechanism fails to detect natively-unsupported 1344 // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) 1345 // in browsers that parse the `:has()` argument as a forgiving selector list. 1346 // https://drafts.csswg.org/selectors/#relational now requires the argument 1347 // to be parsed unforgivingly, but browsers have not yet fully adjusted. 1348 rbuggyQSA.push( ":has" ); 1349 } 1350 1351 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 1352 1353 /* Sorting 1354 ---------------------------------------------------------------------- */ 1355 1356 // Document order sorting 1357 sortOrder = function( a, b ) { 1358 1359 // Flag for duplicate removal 1360 if ( a === b ) { 1361 hasDuplicate = true; 1362 return 0; 1363 } 1364 1365 // Sort on method existence if only one input has compareDocumentPosition 1366 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1367 if ( compare ) { 1368 return compare; 1369 } 1370 1371 // Calculate position if both inputs belong to the same document 1372 // Support: IE 11+, Edge 17 - 18+ 1373 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1374 // two documents; shallow comparisons work. 1375 // eslint-disable-next-line eqeqeq 1376 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 1377 a.compareDocumentPosition( b ) : 1378 1379 // Otherwise we know they are disconnected 1380 1; 1381 1382 // Disconnected nodes 1383 if ( compare & 1 || 1384 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 1385 1386 // Choose the first element that is related to our preferred document 1387 // Support: IE 11+, Edge 17 - 18+ 1388 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1389 // two documents; shallow comparisons work. 1390 // eslint-disable-next-line eqeqeq 1391 if ( a === document || a.ownerDocument == preferredDoc && 1392 find.contains( preferredDoc, a ) ) { 1393 return -1; 1394 } 1395 1396 // Support: IE 11+, Edge 17 - 18+ 1397 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1398 // two documents; shallow comparisons work. 1399 // eslint-disable-next-line eqeqeq 1400 if ( b === document || b.ownerDocument == preferredDoc && 1401 find.contains( preferredDoc, b ) ) { 1402 return 1; 1403 } 1404 1405 // Maintain original order 1406 return sortInput ? 1407 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 1408 0; 1409 } 1410 1411 return compare & 4 ? -1 : 1; 1412 }; 1413 1414 return document; 1415} 1416 1417find.matches = function( expr, elements ) { 1418 return find( expr, null, null, elements ); 1419}; 1420 1421find.matchesSelector = function( elem, expr ) { 1422 setDocument( elem ); 1423 1424 if ( documentIsHTML && 1425 !nonnativeSelectorCache[ expr + " " ] && 1426 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 1427 1428 try { 1429 var ret = matches.call( elem, expr ); 1430 1431 // IE 9's matchesSelector returns false on disconnected nodes 1432 if ( ret || support.disconnectedMatch || 1433 1434 // As well, disconnected nodes are said to be in a document 1435 // fragment in IE 9 1436 elem.document && elem.document.nodeType !== 11 ) { 1437 return ret; 1438 } 1439 } catch ( e ) { 1440 nonnativeSelectorCache( expr, true ); 1441 } 1442 } 1443 1444 return find( expr, document, null, [ elem ] ).length > 0; 1445}; 1446 1447find.contains = function( context, elem ) { 1448 1449 // Set document vars if needed 1450 // Support: IE 11+, Edge 17 - 18+ 1451 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1452 // two documents; shallow comparisons work. 1453 // eslint-disable-next-line eqeqeq 1454 if ( ( context.ownerDocument || context ) != document ) { 1455 setDocument( context ); 1456 } 1457 return jQuery.contains( context, elem ); 1458}; 1459 1460 1461find.attr = function( elem, name ) { 1462 1463 // Set document vars if needed 1464 // Support: IE 11+, Edge 17 - 18+ 1465 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1466 // two documents; shallow comparisons work. 1467 // eslint-disable-next-line eqeqeq 1468 if ( ( elem.ownerDocument || elem ) != document ) { 1469 setDocument( elem ); 1470 } 1471 1472 var fn = Expr.attrHandle[ name.toLowerCase() ], 1473 1474 // Don't get fooled by Object.prototype properties (see trac-13807) 1475 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 1476 fn( elem, name, !documentIsHTML ) : 1477 undefined; 1478 1479 if ( val !== undefined ) { 1480 return val; 1481 } 1482 1483 return elem.getAttribute( name ); 1484}; 1485 1486find.error = function( msg ) { 1487 throw new Error( "Syntax error, unrecognized expression: " + msg ); 1488}; 1489 1490/** 1491 * Document sorting and removing duplicates 1492 * @param {ArrayLike} results 1493 */ 1494jQuery.uniqueSort = function( results ) { 1495 var elem, 1496 duplicates = [], 1497 j = 0, 1498 i = 0; 1499 1500 // Unless we *know* we can detect duplicates, assume their presence 1501 // 1502 // Support: Android <=4.0+ 1503 // Testing for detecting duplicates is unpredictable so instead assume we can't 1504 // depend on duplicate detection in all browsers without a stable sort. 1505 hasDuplicate = !support.sortStable; 1506 sortInput = !support.sortStable && slice.call( results, 0 ); 1507 sort.call( results, sortOrder ); 1508 1509 if ( hasDuplicate ) { 1510 while ( ( elem = results[ i++ ] ) ) { 1511 if ( elem === results[ i ] ) { 1512 j = duplicates.push( i ); 1513 } 1514 } 1515 while ( j-- ) { 1516 splice.call( results, duplicates[ j ], 1 ); 1517 } 1518 } 1519 1520 // Clear input after sorting to release objects 1521 // See https://github.com/jquery/sizzle/pull/225 1522 sortInput = null; 1523 1524 return results; 1525}; 1526 1527jQuery.fn.uniqueSort = function() { 1528 return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) ); 1529}; 1530 1531Expr = jQuery.expr = { 1532 1533 // Can be adjusted by the user 1534 cacheLength: 50, 1535 1536 createPseudo: markFunction, 1537 1538 match: matchExpr, 1539 1540 attrHandle: {}, 1541 1542 find: {}, 1543 1544 relative: { 1545 ">": { dir: "parentNode", first: true }, 1546 " ": { dir: "parentNode" }, 1547 "+": { dir: "previousSibling", first: true }, 1548 "~": { dir: "previousSibling" } 1549 }, 1550 1551 preFilter: { 1552 ATTR: function( match ) { 1553 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 1554 1555 // Move the given value to match[3] whether quoted or unquoted 1556 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ) 1557 .replace( runescape, funescape ); 1558 1559 if ( match[ 2 ] === "~=" ) { 1560 match[ 3 ] = " " + match[ 3 ] + " "; 1561 } 1562 1563 return match.slice( 0, 4 ); 1564 }, 1565 1566 CHILD: function( match ) { 1567 1568 /* matches from matchExpr["CHILD"] 1569 1 type (only|nth|...) 1570 2 what (child|of-type) 1571 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1572 4 xn-component of xn+y argument ([+-]?\d*n|) 1573 5 sign of xn-component 1574 6 x of xn-component 1575 7 sign of y-component 1576 8 y of y-component 1577 */ 1578 match[ 1 ] = match[ 1 ].toLowerCase(); 1579 1580 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 1581 1582 // nth-* requires argument 1583 if ( !match[ 3 ] ) { 1584 find.error( match[ 0 ] ); 1585 } 1586 1587 // numeric x and y parameters for Expr.filter.CHILD 1588 // remember that false/true cast respectively to 0/1 1589 match[ 4 ] = +( match[ 4 ] ? 1590 match[ 5 ] + ( match[ 6 ] || 1 ) : 1591 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) 1592 ); 1593 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 1594 1595 // other types prohibit arguments 1596 } else if ( match[ 3 ] ) { 1597 find.error( match[ 0 ] ); 1598 } 1599 1600 return match; 1601 }, 1602 1603 PSEUDO: function( match ) { 1604 var excess, 1605 unquoted = !match[ 6 ] && match[ 2 ]; 1606 1607 if ( matchExpr.CHILD.test( match[ 0 ] ) ) { 1608 return null; 1609 } 1610 1611 // Accept quoted arguments as-is 1612 if ( match[ 3 ] ) { 1613 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 1614 1615 // Strip excess characters from unquoted arguments 1616 } else if ( unquoted && rpseudo.test( unquoted ) && 1617 1618 // Get excess from tokenize (recursively) 1619 ( excess = tokenize( unquoted, true ) ) && 1620 1621 // advance to the next closing parenthesis 1622 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 1623 1624 // excess is a negative index 1625 match[ 0 ] = match[ 0 ].slice( 0, excess ); 1626 match[ 2 ] = unquoted.slice( 0, excess ); 1627 } 1628 1629 // Return only captures needed by the pseudo filter method (type and argument) 1630 return match.slice( 0, 3 ); 1631 } 1632 }, 1633 1634 filter: { 1635 1636 TAG: function( nodeNameSelector ) { 1637 var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 1638 return nodeNameSelector === "*" ? 1639 function() { 1640 return true; 1641 } : 1642 function( elem ) { 1643 return nodeName( elem, expectedNodeName ); 1644 }; 1645 }, 1646 1647 CLASS: function( className ) { 1648 var pattern = classCache[ className + " " ]; 1649 1650 return pattern || 1651 ( pattern = new RegExp( "(^|" + whitespace + ")" + className + 1652 "(" + whitespace + "|$)" ) ) && 1653 classCache( className, function( elem ) { 1654 return pattern.test( 1655 typeof elem.className === "string" && elem.className || 1656 typeof elem.getAttribute !== "undefined" && 1657 elem.getAttribute( "class" ) || 1658 "" 1659 ); 1660 } ); 1661 }, 1662 1663 ATTR: function( name, operator, check ) { 1664 return function( elem ) { 1665 var result = find.attr( elem, name ); 1666 1667 if ( result == null ) { 1668 return operator === "!="; 1669 } 1670 if ( !operator ) { 1671 return true; 1672 } 1673 1674 result += ""; 1675 1676 if ( operator === "=" ) { 1677 return result === check; 1678 } 1679 if ( operator === "!=" ) { 1680 return result !== check; 1681 } 1682 if ( operator === "^=" ) { 1683 return check && result.indexOf( check ) === 0; 1684 } 1685 if ( operator === "*=" ) { 1686 return check && result.indexOf( check ) > -1; 1687 } 1688 if ( operator === "$=" ) { 1689 return check && result.slice( -check.length ) === check; 1690 } 1691 if ( operator === "~=" ) { 1692 return ( " " + result.replace( rwhitespace, " " ) + " " ) 1693 .indexOf( check ) > -1; 1694 } 1695 if ( operator === "|=" ) { 1696 return result === check || result.slice( 0, check.length + 1 ) === check + "-"; 1697 } 1698 1699 return false; 1700 }; 1701 }, 1702 1703 CHILD: function( type, what, _argument, first, last ) { 1704 var simple = type.slice( 0, 3 ) !== "nth", 1705 forward = type.slice( -4 ) !== "last", 1706 ofType = what === "of-type"; 1707 1708 return first === 1 && last === 0 ? 1709 1710 // Shortcut for :nth-*(n) 1711 function( elem ) { 1712 return !!elem.parentNode; 1713 } : 1714 1715 function( elem, _context, xml ) { 1716 var cache, outerCache, node, nodeIndex, start, 1717 dir = simple !== forward ? "nextSibling" : "previousSibling", 1718 parent = elem.parentNode, 1719 name = ofType && elem.nodeName.toLowerCase(), 1720 useCache = !xml && !ofType, 1721 diff = false; 1722 1723 if ( parent ) { 1724 1725 // :(first|last|only)-(child|of-type) 1726 if ( simple ) { 1727 while ( dir ) { 1728 node = elem; 1729 while ( ( node = node[ dir ] ) ) { 1730 if ( ofType ? 1731 nodeName( node, name ) : 1732 node.nodeType === 1 ) { 1733 1734 return false; 1735 } 1736 } 1737 1738 // Reverse direction for :only-* (if we haven't yet done so) 1739 start = dir = type === "only" && !start && "nextSibling"; 1740 } 1741 return true; 1742 } 1743 1744 start = [ forward ? parent.firstChild : parent.lastChild ]; 1745 1746 // non-xml :nth-child(...) stores cache data on `parent` 1747 if ( forward && useCache ) { 1748 1749 // Seek `elem` from a previously-cached index 1750 outerCache = parent[ expando ] || ( parent[ expando ] = {} ); 1751 cache = outerCache[ type ] || []; 1752 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1753 diff = nodeIndex && cache[ 2 ]; 1754 node = nodeIndex && parent.childNodes[ nodeIndex ]; 1755 1756 while ( ( node = ++nodeIndex && node && node[ dir ] || 1757 1758 // Fallback to seeking `elem` from the start 1759 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 1760 1761 // When found, cache indexes on `parent` and break 1762 if ( node.nodeType === 1 && ++diff && node === elem ) { 1763 outerCache[ type ] = [ dirruns, nodeIndex, diff ]; 1764 break; 1765 } 1766 } 1767 1768 } else { 1769 1770 // Use previously-cached element index if available 1771 if ( useCache ) { 1772 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 1773 cache = outerCache[ type ] || []; 1774 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1775 diff = nodeIndex; 1776 } 1777 1778 // xml :nth-child(...) 1779 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 1780 if ( diff === false ) { 1781 1782 // Use the same loop as above to seek `elem` from the start 1783 while ( ( node = ++nodeIndex && node && node[ dir ] || 1784 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 1785 1786 if ( ( ofType ? 1787 nodeName( node, name ) : 1788 node.nodeType === 1 ) && 1789 ++diff ) { 1790 1791 // Cache the index of each encountered element 1792 if ( useCache ) { 1793 outerCache = node[ expando ] || 1794 ( node[ expando ] = {} ); 1795 outerCache[ type ] = [ dirruns, diff ]; 1796 } 1797 1798 if ( node === elem ) { 1799 break; 1800 } 1801 } 1802 } 1803 } 1804 } 1805 1806 // Incorporate the offset, then check against cycle size 1807 diff -= last; 1808 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 1809 } 1810 }; 1811 }, 1812 1813 PSEUDO: function( pseudo, argument ) { 1814 1815 // pseudo-class names are case-insensitive 1816 // https://www.w3.org/TR/selectors/#pseudo-classes 1817 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1818 // Remember that setFilters inherits from pseudos 1819 var args, 1820 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 1821 find.error( "unsupported pseudo: " + pseudo ); 1822 1823 // The user may use createPseudo to indicate that 1824 // arguments are needed to create the filter function 1825 // just as jQuery does 1826 if ( fn[ expando ] ) { 1827 return fn( argument ); 1828 } 1829 1830 // But maintain support for old signatures 1831 if ( fn.length > 1 ) { 1832 args = [ pseudo, pseudo, "", argument ]; 1833 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 1834 markFunction( function( seed, matches ) { 1835 var idx, 1836 matched = fn( seed, argument ), 1837 i = matched.length; 1838 while ( i-- ) { 1839 idx = indexOf.call( seed, matched[ i ] ); 1840 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 1841 } 1842 } ) : 1843 function( elem ) { 1844 return fn( elem, 0, args ); 1845 }; 1846 } 1847 1848 return fn; 1849 } 1850 }, 1851 1852 pseudos: { 1853 1854 // Potentially complex pseudos 1855 not: markFunction( function( selector ) { 1856 1857 // Trim the selector passed to compile 1858 // to avoid treating leading and trailing 1859 // spaces as combinators 1860 var input = [], 1861 results = [], 1862 matcher = compile( selector.replace( rtrimCSS, "$1" ) ); 1863 1864 return matcher[ expando ] ? 1865 markFunction( function( seed, matches, _context, xml ) { 1866 var elem, 1867 unmatched = matcher( seed, null, xml, [] ), 1868 i = seed.length; 1869 1870 // Match elements unmatched by `matcher` 1871 while ( i-- ) { 1872 if ( ( elem = unmatched[ i ] ) ) { 1873 seed[ i ] = !( matches[ i ] = elem ); 1874 } 1875 } 1876 } ) : 1877 function( elem, _context, xml ) { 1878 input[ 0 ] = elem; 1879 matcher( input, null, xml, results ); 1880 1881 // Don't keep the element 1882 // (see https://github.com/jquery/sizzle/issues/299) 1883 input[ 0 ] = null; 1884 return !results.pop(); 1885 }; 1886 } ), 1887 1888 has: markFunction( function( selector ) { 1889 return function( elem ) { 1890 return find( selector, elem ).length > 0; 1891 }; 1892 } ), 1893 1894 contains: markFunction( function( text ) { 1895 text = text.replace( runescape, funescape ); 1896 return function( elem ) { 1897 return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1; 1898 }; 1899 } ), 1900 1901 // "Whether an element is represented by a :lang() selector 1902 // is based solely on the element's language value 1903 // being equal to the identifier C, 1904 // or beginning with the identifier C immediately followed by "-". 1905 // The matching of C against the element's language value is performed case-insensitively. 1906 // The identifier C does not have to be a valid language name." 1907 // https://www.w3.org/TR/selectors/#lang-pseudo 1908 lang: markFunction( function( lang ) { 1909 1910 // lang value must be a valid identifier 1911 if ( !ridentifier.test( lang || "" ) ) { 1912 find.error( "unsupported lang: " + lang ); 1913 } 1914 lang = lang.replace( runescape, funescape ).toLowerCase(); 1915 return function( elem ) { 1916 var elemLang; 1917 do { 1918 if ( ( elemLang = documentIsHTML ? 1919 elem.lang : 1920 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 1921 1922 elemLang = elemLang.toLowerCase(); 1923 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 1924 } 1925 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 1926 return false; 1927 }; 1928 } ), 1929 1930 // Miscellaneous 1931 target: function( elem ) { 1932 var hash = window.location && window.location.hash; 1933 return hash && hash.slice( 1 ) === elem.id; 1934 }, 1935 1936 root: function( elem ) { 1937 return elem === documentElement; 1938 }, 1939 1940 focus: function( elem ) { 1941 return elem === safeActiveElement() && 1942 document.hasFocus() && 1943 !!( elem.type || elem.href || ~elem.tabIndex ); 1944 }, 1945 1946 // Boolean properties 1947 enabled: createDisabledPseudo( false ), 1948 disabled: createDisabledPseudo( true ), 1949 1950 checked: function( elem ) { 1951 1952 // In CSS3, :checked should return both checked and selected elements 1953 // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1954 return ( nodeName( elem, "input" ) && !!elem.checked ) || 1955 ( nodeName( elem, "option" ) && !!elem.selected ); 1956 }, 1957 1958 selected: function( elem ) { 1959 1960 // Support: IE <=11+ 1961 // Accessing the selectedIndex property 1962 // forces the browser to treat the default option as 1963 // selected when in an optgroup. 1964 if ( elem.parentNode ) { 1965 // eslint-disable-next-line no-unused-expressions 1966 elem.parentNode.selectedIndex; 1967 } 1968 1969 return elem.selected === true; 1970 }, 1971 1972 // Contents 1973 empty: function( elem ) { 1974 1975 // https://www.w3.org/TR/selectors/#empty-pseudo 1976 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 1977 // but not by others (comment: 8; processing instruction: 7; etc.) 1978 // nodeType < 6 works because attributes (2) do not appear as children 1979 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1980 if ( elem.nodeType < 6 ) { 1981 return false; 1982 } 1983 } 1984 return true; 1985 }, 1986 1987 parent: function( elem ) { 1988 return !Expr.pseudos.empty( elem ); 1989 }, 1990 1991 // Element/input types 1992 header: function( elem ) { 1993 return rheader.test( elem.nodeName ); 1994 }, 1995 1996 input: function( elem ) { 1997 return rinputs.test( elem.nodeName ); 1998 }, 1999 2000 button: function( elem ) { 2001 return nodeName( elem, "input" ) && elem.type === "button" || 2002 nodeName( elem, "button" ); 2003 }, 2004 2005 text: function( elem ) { 2006 var attr; 2007 return nodeName( elem, "input" ) && elem.type === "text" && 2008 2009 // Support: IE <10 only 2010 // New HTML5 attribute values (e.g., "search") appear 2011 // with elem.type === "text" 2012 ( ( attr = elem.getAttribute( "type" ) ) == null || 2013 attr.toLowerCase() === "text" ); 2014 }, 2015 2016 // Position-in-collection 2017 first: createPositionalPseudo( function() { 2018 return [ 0 ]; 2019 } ), 2020 2021 last: createPositionalPseudo( function( _matchIndexes, length ) { 2022 return [ length - 1 ]; 2023 } ), 2024 2025 eq: createPositionalPseudo( function( _matchIndexes, length, argument ) { 2026 return [ argument < 0 ? argument + length : argument ]; 2027 } ), 2028 2029 even: createPositionalPseudo( function( matchIndexes, length ) { 2030 var i = 0; 2031 for ( ; i < length; i += 2 ) { 2032 matchIndexes.push( i ); 2033 } 2034 return matchIndexes; 2035 } ), 2036 2037 odd: createPositionalPseudo( function( matchIndexes, length ) { 2038 var i = 1; 2039 for ( ; i < length; i += 2 ) { 2040 matchIndexes.push( i ); 2041 } 2042 return matchIndexes; 2043 } ), 2044 2045 lt: createPositionalPseudo( function( matchIndexes, length, argument ) { 2046 var i; 2047 2048 if ( argument < 0 ) { 2049 i = argument + length; 2050 } else if ( argument > length ) { 2051 i = length; 2052 } else { 2053 i = argument; 2054 } 2055 2056 for ( ; --i >= 0; ) { 2057 matchIndexes.push( i ); 2058 } 2059 return matchIndexes; 2060 } ), 2061 2062 gt: createPositionalPseudo( function( matchIndexes, length, argument ) { 2063 var i = argument < 0 ? argument + length : argument; 2064 for ( ; ++i < length; ) { 2065 matchIndexes.push( i ); 2066 } 2067 return matchIndexes; 2068 } ) 2069 } 2070}; 2071 2072Expr.pseudos.nth = Expr.pseudos.eq; 2073 2074// Add button/input type pseudos 2075for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 2076 Expr.pseudos[ i ] = createInputPseudo( i ); 2077} 2078for ( i in { submit: true, reset: true } ) { 2079 Expr.pseudos[ i ] = createButtonPseudo( i ); 2080} 2081 2082// Easy API for creating new setFilters 2083function setFilters() {} 2084setFilters.prototype = Expr.filters = Expr.pseudos; 2085Expr.setFilters = new setFilters(); 2086 2087function tokenize( selector, parseOnly ) { 2088 var matched, match, tokens, type, 2089 soFar, groups, preFilters, 2090 cached = tokenCache[ selector + " " ]; 2091 2092 if ( cached ) { 2093 return parseOnly ? 0 : cached.slice( 0 ); 2094 } 2095 2096 soFar = selector; 2097 groups = []; 2098 preFilters = Expr.preFilter; 2099 2100 while ( soFar ) { 2101 2102 // Comma and first run 2103 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 2104 if ( match ) { 2105 2106 // Don't consume trailing commas as valid 2107 soFar = soFar.slice( match[ 0 ].length ) || soFar; 2108 } 2109 groups.push( ( tokens = [] ) ); 2110 } 2111 2112 matched = false; 2113 2114 // Combinators 2115 if ( ( match = rleadingCombinator.exec( soFar ) ) ) { 2116 matched = match.shift(); 2117 tokens.push( { 2118 value: matched, 2119 2120 // Cast descendant combinators to space 2121 type: match[ 0 ].replace( rtrimCSS, " " ) 2122 } ); 2123 soFar = soFar.slice( matched.length ); 2124 } 2125 2126 // Filters 2127 for ( type in Expr.filter ) { 2128 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 2129 ( match = preFilters[ type ]( match ) ) ) ) { 2130 matched = match.shift(); 2131 tokens.push( { 2132 value: matched, 2133 type: type, 2134 matches: match 2135 } ); 2136 soFar = soFar.slice( matched.length ); 2137 } 2138 } 2139 2140 if ( !matched ) { 2141 break; 2142 } 2143 } 2144 2145 // Return the length of the invalid excess 2146 // if we're just parsing 2147 // Otherwise, throw an error or return tokens 2148 if ( parseOnly ) { 2149 return soFar.length; 2150 } 2151 2152 return soFar ? 2153 find.error( selector ) : 2154 2155 // Cache the tokens 2156 tokenCache( selector, groups ).slice( 0 ); 2157} 2158 2159function toSelector( tokens ) { 2160 var i = 0, 2161 len = tokens.length, 2162 selector = ""; 2163 for ( ; i < len; i++ ) { 2164 selector += tokens[ i ].value; 2165 } 2166 return selector; 2167} 2168 2169function addCombinator( matcher, combinator, base ) { 2170 var dir = combinator.dir, 2171 skip = combinator.next, 2172 key = skip || dir, 2173 checkNonElements = base && key === "parentNode", 2174 doneName = done++; 2175 2176 return combinator.first ? 2177 2178 // Check against closest ancestor/preceding element 2179 function( elem, context, xml ) { 2180 while ( ( elem = elem[ dir ] ) ) { 2181 if ( elem.nodeType === 1 || checkNonElements ) { 2182 return matcher( elem, context, xml ); 2183 } 2184 } 2185 return false; 2186 } : 2187 2188 // Check against all ancestor/preceding elements 2189 function( elem, context, xml ) { 2190 var oldCache, outerCache, 2191 newCache = [ dirruns, doneName ]; 2192 2193 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 2194 if ( xml ) { 2195 while ( ( elem = elem[ dir ] ) ) { 2196 if ( elem.nodeType === 1 || checkNonElements ) { 2197 if ( matcher( elem, context, xml ) ) { 2198 return true; 2199 } 2200 } 2201 } 2202 } else { 2203 while ( ( elem = elem[ dir ] ) ) { 2204 if ( elem.nodeType === 1 || checkNonElements ) { 2205 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 2206 2207 if ( skip && nodeName( elem, skip ) ) { 2208 elem = elem[ dir ] || elem; 2209 } else if ( ( oldCache = outerCache[ key ] ) && 2210 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 2211 2212 // Assign to newCache so results back-propagate to previous elements 2213 return ( newCache[ 2 ] = oldCache[ 2 ] ); 2214 } else { 2215 2216 // Reuse newcache so results back-propagate to previous elements 2217 outerCache[ key ] = newCache; 2218 2219 // A match means we're done; a fail means we have to keep checking 2220 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 2221 return true; 2222 } 2223 } 2224 } 2225 } 2226 } 2227 return false; 2228 }; 2229} 2230 2231function elementMatcher( matchers ) { 2232 return matchers.length > 1 ? 2233 function( elem, context, xml ) { 2234 var i = matchers.length; 2235 while ( i-- ) { 2236 if ( !matchers[ i ]( elem, context, xml ) ) { 2237 return false; 2238 } 2239 } 2240 return true; 2241 } : 2242 matchers[ 0 ]; 2243} 2244 2245function multipleContexts( selector, contexts, results ) { 2246 var i = 0, 2247 len = contexts.length; 2248 for ( ; i < len; i++ ) { 2249 find( selector, contexts[ i ], results ); 2250 } 2251 return results; 2252} 2253 2254function condense( unmatched, map, filter, context, xml ) { 2255 var elem, 2256 newUnmatched = [], 2257 i = 0, 2258 len = unmatched.length, 2259 mapped = map != null; 2260 2261 for ( ; i < len; i++ ) { 2262 if ( ( elem = unmatched[ i ] ) ) { 2263 if ( !filter || filter( elem, context, xml ) ) { 2264 newUnmatched.push( elem ); 2265 if ( mapped ) { 2266 map.push( i ); 2267 } 2268 } 2269 } 2270 } 2271 2272 return newUnmatched; 2273} 2274 2275function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 2276 if ( postFilter && !postFilter[ expando ] ) { 2277 postFilter = setMatcher( postFilter ); 2278 } 2279 if ( postFinder && !postFinder[ expando ] ) { 2280 postFinder = setMatcher( postFinder, postSelector ); 2281 } 2282 return markFunction( function( seed, results, context, xml ) { 2283 var temp, i, elem, matcherOut, 2284 preMap = [], 2285 postMap = [], 2286 preexisting = results.length, 2287 2288 // Get initial elements from seed or context 2289 elems = seed || 2290 multipleContexts( selector || "*", 2291 context.nodeType ? [ context ] : context, [] ), 2292 2293 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2294 matcherIn = preFilter && ( seed || !selector ) ? 2295 condense( elems, preMap, preFilter, context, xml ) : 2296 elems; 2297 2298 if ( matcher ) { 2299 2300 // If we have a postFinder, or filtered seed, or non-seed postFilter 2301 // or preexisting results, 2302 matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 2303 2304 // ...intermediate processing is necessary 2305 [] : 2306 2307 // ...otherwise use results directly 2308 results; 2309 2310 // Find primary matches 2311 matcher( matcherIn, matcherOut, context, xml ); 2312 } else { 2313 matcherOut = matcherIn; 2314 } 2315 2316 // Apply postFilter 2317 if ( postFilter ) { 2318 temp = condense( matcherOut, postMap ); 2319 postFilter( temp, [], context, xml ); 2320 2321 // Un-match failing elements by moving them back to matcherIn 2322 i = temp.length; 2323 while ( i-- ) { 2324 if ( ( elem = temp[ i ] ) ) { 2325 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 2326 } 2327 } 2328 } 2329 2330 if ( seed ) { 2331 if ( postFinder || preFilter ) { 2332 if ( postFinder ) { 2333 2334 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2335 temp = []; 2336 i = matcherOut.length; 2337 while ( i-- ) { 2338 if ( ( elem = matcherOut[ i ] ) ) { 2339 2340 // Restore matcherIn since elem is not yet a final match 2341 temp.push( ( matcherIn[ i ] = elem ) ); 2342 } 2343 } 2344 postFinder( null, ( matcherOut = [] ), temp, xml ); 2345 } 2346 2347 // Move matched elements from seed to results to keep them synchronized 2348 i = matcherOut.length; 2349 while ( i-- ) { 2350 if ( ( elem = matcherOut[ i ] ) && 2351 ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) { 2352 2353 seed[ temp ] = !( results[ temp ] = elem ); 2354 } 2355 } 2356 } 2357 2358 // Add elements to results, through postFinder if defined 2359 } else { 2360 matcherOut = condense( 2361 matcherOut === results ? 2362 matcherOut.splice( preexisting, matcherOut.length ) : 2363 matcherOut 2364 ); 2365 if ( postFinder ) { 2366 postFinder( null, results, matcherOut, xml ); 2367 } else { 2368 push.apply( results, matcherOut ); 2369 } 2370 } 2371 } ); 2372} 2373 2374function matcherFromTokens( tokens ) { 2375 var checkContext, matcher, j, 2376 len = tokens.length, 2377 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 2378 implicitRelative = leadingRelative || Expr.relative[ " " ], 2379 i = leadingRelative ? 1 : 0, 2380 2381 // The foundational matcher ensures that elements are reachable from top-level context(s) 2382 matchContext = addCombinator( function( elem ) { 2383 return elem === checkContext; 2384 }, implicitRelative, true ), 2385 matchAnyContext = addCombinator( function( elem ) { 2386 return indexOf.call( checkContext, elem ) > -1; 2387 }, implicitRelative, true ), 2388 matchers = [ function( elem, context, xml ) { 2389 2390 // Support: IE 11+, Edge 17 - 18+ 2391 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2392 // two documents; shallow comparisons work. 2393 // eslint-disable-next-line eqeqeq 2394 var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || ( 2395 ( checkContext = context ).nodeType ? 2396 matchContext( elem, context, xml ) : 2397 matchAnyContext( elem, context, xml ) ); 2398 2399 // Avoid hanging onto element 2400 // (see https://github.com/jquery/sizzle/issues/299) 2401 checkContext = null; 2402 return ret; 2403 } ]; 2404 2405 for ( ; i < len; i++ ) { 2406 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 2407 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 2408 } else { 2409 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 2410 2411 // Return special upon seeing a positional matcher 2412 if ( matcher[ expando ] ) { 2413 2414 // Find the next relative operator (if any) for proper handling 2415 j = ++i; 2416 for ( ; j < len; j++ ) { 2417 if ( Expr.relative[ tokens[ j ].type ] ) { 2418 break; 2419 } 2420 } 2421 return setMatcher( 2422 i > 1 && elementMatcher( matchers ), 2423 i > 1 && toSelector( 2424 2425 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2426 tokens.slice( 0, i - 1 ) 2427 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 2428 ).replace( rtrimCSS, "$1" ), 2429 matcher, 2430 i < j && matcherFromTokens( tokens.slice( i, j ) ), 2431 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 2432 j < len && toSelector( tokens ) 2433 ); 2434 } 2435 matchers.push( matcher ); 2436 } 2437 } 2438 2439 return elementMatcher( matchers ); 2440} 2441 2442function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 2443 var bySet = setMatchers.length > 0, 2444 byElement = elementMatchers.length > 0, 2445 superMatcher = function( seed, context, xml, results, outermost ) { 2446 var elem, j, matcher, 2447 matchedCount = 0, 2448 i = "0", 2449 unmatched = seed && [], 2450 setMatched = [], 2451 contextBackup = outermostContext, 2452 2453 // We must always have either seed elements or outermost context 2454 elems = seed || byElement && Expr.find.TAG( "*", outermost ), 2455 2456 // Use integer dirruns iff this is the outermost matcher 2457 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 2458 len = elems.length; 2459 2460 if ( outermost ) { 2461 2462 // Support: IE 11+, Edge 17 - 18+ 2463 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2464 // two documents; shallow comparisons work. 2465 // eslint-disable-next-line eqeqeq 2466 outermostContext = context == document || context || outermost; 2467 } 2468 2469 // Add elements passing elementMatchers directly to results 2470 // Support: iOS <=7 - 9 only 2471 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching 2472 // elements by id. (see trac-14142) 2473 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 2474 if ( byElement && elem ) { 2475 j = 0; 2476 2477 // Support: IE 11+, Edge 17 - 18+ 2478 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2479 // two documents; shallow comparisons work. 2480 // eslint-disable-next-line eqeqeq 2481 if ( !context && elem.ownerDocument != document ) { 2482 setDocument( elem ); 2483 xml = !documentIsHTML; 2484 } 2485 while ( ( matcher = elementMatchers[ j++ ] ) ) { 2486 if ( matcher( elem, context || document, xml ) ) { 2487 push.call( results, elem ); 2488 break; 2489 } 2490 } 2491 if ( outermost ) { 2492 dirruns = dirrunsUnique; 2493 } 2494 } 2495 2496 // Track unmatched elements for set filters 2497 if ( bySet ) { 2498 2499 // They will have gone through all possible matchers 2500 if ( ( elem = !matcher && elem ) ) { 2501 matchedCount--; 2502 } 2503 2504 // Lengthen the array for every element, matched or not 2505 if ( seed ) { 2506 unmatched.push( elem ); 2507 } 2508 } 2509 } 2510 2511 // `i` is now the count of elements visited above, and adding it to `matchedCount` 2512 // makes the latter nonnegative. 2513 matchedCount += i; 2514 2515 // Apply set filters to unmatched elements 2516 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 2517 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 2518 // no element matchers and no seed. 2519 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 2520 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 2521 // numerically zero. 2522 if ( bySet && i !== matchedCount ) { 2523 j = 0; 2524 while ( ( matcher = setMatchers[ j++ ] ) ) { 2525 matcher( unmatched, setMatched, context, xml ); 2526 } 2527 2528 if ( seed ) { 2529 2530 // Reintegrate element matches to eliminate the need for sorting 2531 if ( matchedCount > 0 ) { 2532 while ( i-- ) { 2533 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 2534 setMatched[ i ] = pop.call( results ); 2535 } 2536 } 2537 } 2538 2539 // Discard index placeholder values to get only actual matches 2540 setMatched = condense( setMatched ); 2541 } 2542 2543 // Add matches to results 2544 push.apply( results, setMatched ); 2545 2546 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2547 if ( outermost && !seed && setMatched.length > 0 && 2548 ( matchedCount + setMatchers.length ) > 1 ) { 2549 2550 jQuery.uniqueSort( results ); 2551 } 2552 } 2553 2554 // Override manipulation of globals by nested matchers 2555 if ( outermost ) { 2556 dirruns = dirrunsUnique; 2557 outermostContext = contextBackup; 2558 } 2559 2560 return unmatched; 2561 }; 2562 2563 return bySet ? 2564 markFunction( superMatcher ) : 2565 superMatcher; 2566} 2567 2568function compile( selector, match /* Internal Use Only */ ) { 2569 var i, 2570 setMatchers = [], 2571 elementMatchers = [], 2572 cached = compilerCache[ selector + " " ]; 2573 2574 if ( !cached ) { 2575 2576 // Generate a function of recursive functions that can be used to check each element 2577 if ( !match ) { 2578 match = tokenize( selector ); 2579 } 2580 i = match.length; 2581 while ( i-- ) { 2582 cached = matcherFromTokens( match[ i ] ); 2583 if ( cached[ expando ] ) { 2584 setMatchers.push( cached ); 2585 } else { 2586 elementMatchers.push( cached ); 2587 } 2588 } 2589 2590 // Cache the compiled function 2591 cached = compilerCache( selector, 2592 matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 2593 2594 // Save selector and tokenization 2595 cached.selector = selector; 2596 } 2597 return cached; 2598} 2599 2600/** 2601 * A low-level selection function that works with jQuery's compiled 2602 * selector functions 2603 * @param {String|Function} selector A selector or a pre-compiled 2604 * selector function built with jQuery selector compile 2605 * @param {Element} context 2606 * @param {Array} [results] 2607 * @param {Array} [seed] A set of elements to match against 2608 */ 2609function select( selector, context, results, seed ) { 2610 var i, tokens, token, type, find, 2611 compiled = typeof selector === "function" && selector, 2612 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 2613 2614 results = results || []; 2615 2616 // Try to minimize operations if there is only one selector in the list and no seed 2617 // (the latter of which guarantees us context) 2618 if ( match.length === 1 ) { 2619 2620 // Reduce context if the leading compound selector is an ID 2621 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 2622 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 2623 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 2624 2625 context = ( Expr.find.ID( 2626 token.matches[ 0 ].replace( runescape, funescape ), 2627 context 2628 ) || [] )[ 0 ]; 2629 if ( !context ) { 2630 return results; 2631 2632 // Precompiled matchers will still verify ancestry, so step up a level 2633 } else if ( compiled ) { 2634 context = context.parentNode; 2635 } 2636 2637 selector = selector.slice( tokens.shift().value.length ); 2638 } 2639 2640 // Fetch a seed set for right-to-left matching 2641 i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length; 2642 while ( i-- ) { 2643 token = tokens[ i ]; 2644 2645 // Abort if we hit a combinator 2646 if ( Expr.relative[ ( type = token.type ) ] ) { 2647 break; 2648 } 2649 if ( ( find = Expr.find[ type ] ) ) { 2650 2651 // Search, expanding context for leading sibling combinators 2652 if ( ( seed = find( 2653 token.matches[ 0 ].replace( runescape, funescape ), 2654 rsibling.test( tokens[ 0 ].type ) &&
vendor: 4,497 bytes, lines 2655-2839
2655 testContext( context.parentNode ) || context 2656 ) ) ) { 2657 2658 // If seed is empty or no tokens remain, we can return early 2659 tokens.splice( i, 1 ); 2660 selector = seed.length && toSelector( tokens ); 2661 if ( !selector ) { 2662 push.apply( results, seed ); 2663 return results; 2664 } 2665 2666 break; 2667 } 2668 } 2669 } 2670 } 2671 2672 // Compile and execute a filtering function if one is not provided 2673 // Provide `match` to avoid retokenization if we modified the selector above 2674 ( compiled || compile( selector, match ) )( 2675 seed, 2676 context, 2677 !documentIsHTML, 2678 results, 2679 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 2680 ); 2681 return results; 2682} 2683 2684// One-time assignments 2685 2686// Support: Android <=4.0 - 4.1+ 2687// Sort stability 2688support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 2689 2690// Initialize against the default document 2691setDocument(); 2692 2693// Support: Android <=4.0 - 4.1+ 2694// Detached nodes confoundingly follow *each other* 2695support.sortDetached = assert( function( el ) { 2696 2697 // Should return 1, but returns 4 (following) 2698 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 2699} ); 2700 2701jQuery.find = find; 2702 2703// Deprecated 2704jQuery.expr[ ":" ] = jQuery.expr.pseudos; 2705jQuery.unique = jQuery.uniqueSort; 2706 2707// These have always been private, but they used to be documented as part of 2708// Sizzle so let's maintain them for now for backwards compatibility purposes. 2709find.compile = compile; 2710find.select = select; 2711find.setDocument = setDocument; 2712find.tokenize = tokenize; 2713 2714find.escape = jQuery.escapeSelector; 2715find.getText = jQuery.text; 2716find.isXML = jQuery.isXMLDoc; 2717find.selectors = jQuery.expr; 2718find.support = jQuery.support; 2719find.uniqueSort = jQuery.uniqueSort; 2720 2721 /* eslint-enable */ 2722 2723} )(); 2724 2725 2726var dir = function( elem, dir, until ) { 2727 var matched = [], 2728 truncate = until !== undefined; 2729 2730 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 2731 if ( elem.nodeType === 1 ) { 2732 if ( truncate && jQuery( elem ).is( until ) ) { 2733 break; 2734 } 2735 matched.push( elem ); 2736 } 2737 } 2738 return matched; 2739}; 2740 2741 2742var siblings = function( n, elem ) { 2743 var matched = []; 2744 2745 for ( ; n; n = n.nextSibling ) { 2746 if ( n.nodeType === 1 && n !== elem ) { 2747 matched.push( n ); 2748 } 2749 } 2750 2751 return matched; 2752}; 2753 2754 2755var rneedsContext = jQuery.expr.match.needsContext; 2756 2757var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 2758 2759 2760 2761// Implement the identical functionality for filter and not 2762function winnow( elements, qualifier, not ) { 2763 if ( isFunction( qualifier ) ) { 2764 return jQuery.grep( elements, function( elem, i ) { 2765 return !!qualifier.call( elem, i, elem ) !== not; 2766 } ); 2767 } 2768 2769 // Single element 2770 if ( qualifier.nodeType ) { 2771 return jQuery.grep( elements, function( elem ) { 2772 return ( elem === qualifier ) !== not; 2773 } ); 2774 } 2775 2776 // Arraylike of elements (jQuery, arguments, Array) 2777 if ( typeof qualifier !== "string" ) { 2778 return jQuery.grep( elements, function( elem ) { 2779 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 2780 } ); 2781 } 2782 2783 // Filtered directly for both simple and complex selectors 2784 return jQuery.filter( qualifier, elements, not ); 2785} 2786 2787jQuery.filter = function( expr, elems, not ) { 2788 var elem = elems[ 0 ]; 2789 2790 if ( not ) { 2791 expr = ":not(" + expr + ")"; 2792 } 2793 2794 if ( elems.length === 1 && elem.nodeType === 1 ) { 2795 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 2796 } 2797 2798 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 2799 return elem.nodeType === 1; 2800 } ) ); 2801}; 2802 2803jQuery.fn.extend( { 2804 find: function( selector ) { 2805 var i, ret, 2806 len = this.length, 2807 self = this; 2808 2809 if ( typeof selector !== "string" ) { 2810 return this.pushStack( jQuery( selector ).filter( function() { 2811 for ( i = 0; i < len; i++ ) { 2812 if ( jQuery.contains( self[ i ], this ) ) { 2813 return true; 2814 } 2815 } 2816 } ) ); 2817 } 2818 2819 ret = this.pushStack( [] ); 2820 2821 for ( i = 0; i < len; i++ ) { 2822 jQuery.find( selector, self[ i ], ret ); 2823 } 2824 2825 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 2826 }, 2827 filter: function( selector ) { 2828 return this.pushStack( winnow( this, selector || [], false ) ); 2829 }, 2830 not: function( selector ) { 2831 return this.pushStack( winnow( this, selector || [], true ) ); 2832 }, 2833 is: function( selector ) { 2834 return !!winnow( 2835 this, 2836 2837 // If this is a positional/relative selector, check membership in the returned set 2838 // so $("p:first").is("p:last") won't return true for a doc with two "p". 2839 typeof selector === "string" && rneedsContext.test( selector ) ?
vendor: 9,941 bytes, lines 2840-3228
2840 jQuery( selector ) : 2841 selector || [], 2842 false 2843 ).length; 2844 } 2845} ); 2846 2847 2848// Initialize a jQuery object 2849 2850 2851// A central reference to the root jQuery(document) 2852var rootjQuery, 2853 2854 // A simple way to check for HTML strings 2855 // Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521) 2856 // Strict HTML recognition (trac-11290: must start with <) 2857 // Shortcut simple #id case for speed 2858 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 2859 2860 init = jQuery.fn.init = function( selector, context, root ) { 2861 var match, elem; 2862 2863 // HANDLE: $(""), $(null), $(undefined), $(false) 2864 if ( !selector ) { 2865 return this; 2866 } 2867 2868 // Method init() accepts an alternate rootjQuery 2869 // so migrate can support jQuery.sub (gh-2101) 2870 root = root || rootjQuery; 2871 2872 // Handle HTML strings 2873 if ( typeof selector === "string" ) { 2874 if ( selector[ 0 ] === "<" && 2875 selector[ selector.length - 1 ] === ">" && 2876 selector.length >= 3 ) { 2877 2878 // Assume that strings that start and end with <> are HTML and skip the regex check 2879 match = [ null, selector, null ]; 2880 2881 } else { 2882 match = rquickExpr.exec( selector ); 2883 } 2884 2885 // Match html or make sure no context is specified for #id 2886 if ( match && ( match[ 1 ] || !context ) ) { 2887 2888 // HANDLE: $(html) -> $(array) 2889 if ( match[ 1 ] ) { 2890 context = context instanceof jQuery ? context[ 0 ] : context; 2891 2892 // Option to run scripts is true for back-compat 2893 // Intentionally let the error be thrown if parseHTML is not present 2894 jQuery.merge( this, jQuery.parseHTML( 2895 match[ 1 ], 2896 context && context.nodeType ? context.ownerDocument || context : document, 2897 true 2898 ) ); 2899 2900 // HANDLE: $(html, props) 2901 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 2902 for ( match in context ) { 2903 2904 // Properties of context are called as methods if possible 2905 if ( isFunction( this[ match ] ) ) { 2906 this[ match ]( context[ match ] ); 2907 2908 // ...and otherwise set as attributes 2909 } else { 2910 this.attr( match, context[ match ] ); 2911 } 2912 } 2913 } 2914 2915 return this; 2916 2917 // HANDLE: $(#id) 2918 } else { 2919 elem = document.getElementById( match[ 2 ] ); 2920 2921 if ( elem ) { 2922 2923 // Inject the element directly into the jQuery object 2924 this[ 0 ] = elem; 2925 this.length = 1; 2926 } 2927 return this; 2928 } 2929 2930 // HANDLE: $(expr, $(...)) 2931 } else if ( !context || context.jquery ) { 2932 return ( context || root ).find( selector ); 2933 2934 // HANDLE: $(expr, context) 2935 // (which is just equivalent to: $(context).find(expr) 2936 } else { 2937 return this.constructor( context ).find( selector ); 2938 } 2939 2940 // HANDLE: $(DOMElement) 2941 } else if ( selector.nodeType ) { 2942 this[ 0 ] = selector; 2943 this.length = 1; 2944 return this; 2945 2946 // HANDLE: $(function) 2947 // Shortcut for document ready 2948 } else if ( isFunction( selector ) ) { 2949 return root.ready !== undefined ? 2950 root.ready( selector ) : 2951 2952 // Execute immediately if ready is not present 2953 selector( jQuery ); 2954 } 2955 2956 return jQuery.makeArray( selector, this ); 2957 }; 2958 2959// Give the init function the jQuery prototype for later instantiation 2960init.prototype = jQuery.fn; 2961 2962// Initialize central reference 2963rootjQuery = jQuery( document ); 2964 2965 2966var rparentsprev = /^(?:parents|prev(?:Until|All))/, 2967 2968 // Methods guaranteed to produce a unique set when starting from a unique set 2969 guaranteedUnique = { 2970 children: true, 2971 contents: true, 2972 next: true, 2973 prev: true 2974 }; 2975 2976jQuery.fn.extend( { 2977 has: function( target ) { 2978 var targets = jQuery( target, this ), 2979 l = targets.length; 2980 2981 return this.filter( function() { 2982 var i = 0; 2983 for ( ; i < l; i++ ) { 2984 if ( jQuery.contains( this, targets[ i ] ) ) { 2985 return true; 2986 } 2987 } 2988 } ); 2989 }, 2990 2991 closest: function( selectors, context ) { 2992 var cur, 2993 i = 0, 2994 l = this.length, 2995 matched = [], 2996 targets = typeof selectors !== "string" && jQuery( selectors ); 2997 2998 // Positional selectors never match, since there's no _selection_ context 2999 if ( !rneedsContext.test( selectors ) ) { 3000 for ( ; i < l; i++ ) { 3001 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 3002 3003 // Always skip document fragments 3004 if ( cur.nodeType < 11 && ( targets ? 3005 targets.index( cur ) > -1 : 3006 3007 // Don't pass non-elements to jQuery#find 3008 cur.nodeType === 1 && 3009 jQuery.find.matchesSelector( cur, selectors ) ) ) { 3010 3011 matched.push( cur ); 3012 break; 3013 } 3014 } 3015 } 3016 } 3017 3018 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 3019 }, 3020 3021 // Determine the position of an element within the set 3022 index: function( elem ) { 3023 3024 // No argument, return index in parent 3025 if ( !elem ) { 3026 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 3027 } 3028 3029 // Index in selector 3030 if ( typeof elem === "string" ) { 3031 return indexOf.call( jQuery( elem ), this[ 0 ] ); 3032 } 3033 3034 // Locate the position of the desired element 3035 return indexOf.call( this, 3036 3037 // If it receives a jQuery object, the first element is used 3038 elem.jquery ? elem[ 0 ] : elem 3039 ); 3040 }, 3041 3042 add: function( selector, context ) { 3043 return this.pushStack( 3044 jQuery.uniqueSort( 3045 jQuery.merge( this.get(), jQuery( selector, context ) ) 3046 ) 3047 ); 3048 }, 3049 3050 addBack: function( selector ) { 3051 return this.add( selector == null ? 3052 this.prevObject : this.prevObject.filter( selector ) 3053 ); 3054 } 3055} ); 3056 3057function sibling( cur, dir ) { 3058 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 3059 return cur; 3060} 3061 3062jQuery.each( { 3063 parent: function( elem ) { 3064 var parent = elem.parentNode; 3065 return parent && parent.nodeType !== 11 ? parent : null; 3066 }, 3067 parents: function( elem ) { 3068 return dir( elem, "parentNode" ); 3069 }, 3070 parentsUntil: function( elem, _i, until ) { 3071 return dir( elem, "parentNode", until ); 3072 }, 3073 next: function( elem ) { 3074 return sibling( elem, "nextSibling" ); 3075 }, 3076 prev: function( elem ) { 3077 return sibling( elem, "previousSibling" ); 3078 }, 3079 nextAll: function( elem ) { 3080 return dir( elem, "nextSibling" ); 3081 }, 3082 prevAll: function( elem ) { 3083 return dir( elem, "previousSibling" ); 3084 }, 3085 nextUntil: function( elem, _i, until ) { 3086 return dir( elem, "nextSibling", until ); 3087 }, 3088 prevUntil: function( elem, _i, until ) { 3089 return dir( elem, "previousSibling", until ); 3090 }, 3091 siblings: function( elem ) { 3092 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 3093 }, 3094 children: function( elem ) { 3095 return siblings( elem.firstChild ); 3096 }, 3097 contents: function( elem ) { 3098 if ( elem.contentDocument != null && 3099 3100 // Support: IE 11+ 3101 // <object> elements with no `data` attribute has an object 3102 // `contentDocument` with a `null` prototype. 3103 getProto( elem.contentDocument ) ) { 3104 3105 return elem.contentDocument; 3106 } 3107 3108 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 3109 // Treat the template element as a regular one in browsers that 3110 // don't support it. 3111 if ( nodeName( elem, "template" ) ) { 3112 elem = elem.content || elem; 3113 } 3114 3115 return jQuery.merge( [], elem.childNodes ); 3116 } 3117}, function( name, fn ) { 3118 jQuery.fn[ name ] = function( until, selector ) { 3119 var matched = jQuery.map( this, fn, until ); 3120 3121 if ( name.slice( -5 ) !== "Until" ) { 3122 selector = until; 3123 } 3124 3125 if ( selector && typeof selector === "string" ) { 3126 matched = jQuery.filter( selector, matched ); 3127 } 3128 3129 if ( this.length > 1 ) { 3130 3131 // Remove duplicates 3132 if ( !guaranteedUnique[ name ] ) { 3133 jQuery.uniqueSort( matched ); 3134 } 3135 3136 // Reverse order for parents* and prev-derivatives 3137 if ( rparentsprev.test( name ) ) { 3138 matched.reverse(); 3139 } 3140 } 3141 3142 return this.pushStack( matched ); 3143 }; 3144} ); 3145var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 3146 3147 3148 3149// Convert String-formatted options into Object-formatted ones 3150function createOptions( options ) { 3151 var object = {}; 3152 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 3153 object[ flag ] = true; 3154 } ); 3155 return object; 3156} 3157 3158/* 3159 * Create a callback list using the following parameters: 3160 * 3161 * options: an optional list of space-separated options that will change how 3162 * the callback list behaves or a more traditional option object 3163 * 3164 * By default a callback list will act like an event callback list and can be 3165 * "fired" multiple times. 3166 * 3167 * Possible options: 3168 * 3169 * once: will ensure the callback list can only be fired once (like a Deferred) 3170 * 3171 * memory: will keep track of previous values and will call any callback added 3172 * after the list has been fired right away with the latest "memorized" 3173 * values (like a Deferred) 3174 * 3175 * unique: will ensure a callback can only be added once (no duplicate in the list) 3176 * 3177 * stopOnFalse: interrupt callings when a callback returns false 3178 * 3179 */ 3180jQuery.Callbacks = function( options ) { 3181 3182 // Convert options from String-formatted to Object-formatted if needed 3183 // (we check in cache first) 3184 options = typeof options === "string" ? 3185 createOptions( options ) : 3186 jQuery.extend( {}, options ); 3187 3188 var // Flag to know if list is currently firing 3189 firing, 3190 3191 // Last fire value for non-forgettable lists 3192 memory, 3193 3194 // Flag to know if list was already fired 3195 fired, 3196 3197 // Flag to prevent firing 3198 locked, 3199 3200 // Actual callback list 3201 list = [], 3202 3203 // Queue of execution data for repeatable lists 3204 queue = [], 3205 3206 // Index of currently firing callback (modified by add/remove as needed) 3207 firingIndex = -1, 3208 3209 // Fire callbacks 3210 fire = function() { 3211 3212 // Enforce single-firing 3213 locked = locked || options.once; 3214 3215 // Execute callbacks for all pending executions, 3216 // respecting firingIndex overrides and runtime changes 3217 fired = firing = true; 3218 for ( ; queue.length; firingIndex = -1 ) { 3219 memory = queue.shift(); 3220 while ( ++firingIndex < list.length ) { 3221 3222 // Run callback and check for early termination 3223 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 3224 options.stopOnFalse ) { 3225 3226 // Jump to end and forget the data so .add doesn't re-fire 3227 firingIndex = list.length; 3228 memory = false;
vendor: 4,918 bytes, lines 3229-3438
3229 } 3230 } 3231 } 3232 3233 // Forget the data if we're done with it 3234 if ( !options.memory ) { 3235 memory = false; 3236 } 3237 3238 firing = false; 3239 3240 // Clean up if we're done firing for good 3241 if ( locked ) { 3242 3243 // Keep an empty list if we have data for future add calls 3244 if ( memory ) { 3245 list = []; 3246 3247 // Otherwise, this object is spent 3248 } else { 3249 list = ""; 3250 } 3251 } 3252 }, 3253 3254 // Actual Callbacks object 3255 self = { 3256 3257 // Add a callback or a collection of callbacks to the list 3258 add: function() { 3259 if ( list ) { 3260 3261 // If we have memory from a past run, we should fire after adding 3262 if ( memory && !firing ) { 3263 firingIndex = list.length - 1; 3264 queue.push( memory ); 3265 } 3266 3267 ( function add( args ) { 3268 jQuery.each( args, function( _, arg ) { 3269 if ( isFunction( arg ) ) { 3270 if ( !options.unique || !self.has( arg ) ) { 3271 list.push( arg ); 3272 } 3273 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 3274 3275 // Inspect recursively 3276 add( arg ); 3277 } 3278 } ); 3279 } )( arguments ); 3280 3281 if ( memory && !firing ) { 3282 fire(); 3283 } 3284 } 3285 return this; 3286 }, 3287 3288 // Remove a callback from the list 3289 remove: function() { 3290 jQuery.each( arguments, function( _, arg ) { 3291 var index; 3292 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 3293 list.splice( index, 1 ); 3294 3295 // Handle firing indexes 3296 if ( index <= firingIndex ) { 3297 firingIndex--; 3298 } 3299 } 3300 } ); 3301 return this; 3302 }, 3303 3304 // Check if a given callback is in the list. 3305 // If no argument is given, return whether or not list has callbacks attached. 3306 has: function( fn ) { 3307 return fn ? 3308 jQuery.inArray( fn, list ) > -1 : 3309 list.length > 0; 3310 }, 3311 3312 // Remove all callbacks from the list 3313 empty: function() { 3314 if ( list ) { 3315 list = []; 3316 } 3317 return this; 3318 }, 3319 3320 // Disable .fire and .add 3321 // Abort any current/pending executions 3322 // Clear all callbacks and values 3323 disable: function() { 3324 locked = queue = []; 3325 list = memory = ""; 3326 return this; 3327 }, 3328 disabled: function() { 3329 return !list; 3330 }, 3331 3332 // Disable .fire 3333 // Also disable .add unless we have memory (since it would have no effect) 3334 // Abort any pending executions 3335 lock: function() { 3336 locked = queue = []; 3337 if ( !memory && !firing ) { 3338 list = memory = ""; 3339 } 3340 return this; 3341 }, 3342 locked: function() { 3343 return !!locked; 3344 }, 3345 3346 // Call all callbacks with the given context and arguments 3347 fireWith: function( context, args ) { 3348 if ( !locked ) { 3349 args = args || []; 3350 args = [ context, args.slice ? args.slice() : args ]; 3351 queue.push( args ); 3352 if ( !firing ) { 3353 fire(); 3354 } 3355 } 3356 return this; 3357 }, 3358 3359 // Call all the callbacks with the given arguments 3360 fire: function() { 3361 self.fireWith( this, arguments ); 3362 return this; 3363 }, 3364 3365 // To know if the callbacks have already been called at least once 3366 fired: function() { 3367 return !!fired; 3368 } 3369 }; 3370 3371 return self; 3372}; 3373 3374 3375function Identity( v ) { 3376 return v; 3377} 3378function Thrower( ex ) { 3379 throw ex; 3380} 3381 3382function adoptValue( value, resolve, reject, noValue ) { 3383 var method; 3384 3385 try { 3386 3387 // Check for promise aspect first to privilege synchronous behavior 3388 if ( value && isFunction( ( method = value.promise ) ) ) { 3389 method.call( value ).done( resolve ).fail( reject ); 3390 3391 // Other thenables 3392 } else if ( value && isFunction( ( method = value.then ) ) ) { 3393 method.call( value, resolve, reject ); 3394 3395 // Other non-thenables 3396 } else { 3397 3398 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 3399 // * false: [ value ].slice( 0 ) => resolve( value ) 3400 // * true: [ value ].slice( 1 ) => resolve() 3401 resolve.apply( undefined, [ value ].slice( noValue ) ); 3402 } 3403 3404 // For Promises/A+, convert exceptions into rejections 3405 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 3406 // Deferred#then to conditionally suppress rejection. 3407 } catch ( value ) { 3408 3409 // Support: Android 4.0 only 3410 // Strict mode functions invoked without .call/.apply get global-object context 3411 reject.apply( undefined, [ value ] ); 3412 } 3413} 3414 3415jQuery.extend( { 3416 3417 Deferred: function( func ) { 3418 var tuples = [ 3419 3420 // action, add listener, callbacks, 3421 // ... .then handlers, argument index, [final state] 3422 [ "notify", "progress", jQuery.Callbacks( "memory" ), 3423 jQuery.Callbacks( "memory" ), 2 ], 3424 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 3425 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 3426 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 3427 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 3428 ], 3429 state = "pending", 3430 promise = { 3431 state: function() { 3432 return state; 3433 }, 3434 always: function() { 3435 deferred.done( arguments ).fail( arguments ); 3436 return this; 3437 }, 3438 "catch": function( fn ) {
vendor: 28,472 bytes, lines 3439-4550
3439 return promise.then( null, fn ); 3440 }, 3441 3442 // Keep pipe for back-compat 3443 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 3444 var fns = arguments; 3445 3446 return jQuery.Deferred( function( newDefer ) { 3447 jQuery.each( tuples, function( _i, tuple ) { 3448 3449 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 3450 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 3451 3452 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 3453 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 3454 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 3455 deferred[ tuple[ 1 ] ]( function() { 3456 var returned = fn && fn.apply( this, arguments ); 3457 if ( returned && isFunction( returned.promise ) ) { 3458 returned.promise() 3459 .progress( newDefer.notify ) 3460 .done( newDefer.resolve ) 3461 .fail( newDefer.reject ); 3462 } else { 3463 newDefer[ tuple[ 0 ] + "With" ]( 3464 this, 3465 fn ? [ returned ] : arguments 3466 ); 3467 } 3468 } ); 3469 } ); 3470 fns = null; 3471 } ).promise(); 3472 }, 3473 then: function( onFulfilled, onRejected, onProgress ) { 3474 var maxDepth = 0; 3475 function resolve( depth, deferred, handler, special ) { 3476 return function() { 3477 var that = this, 3478 args = arguments, 3479 mightThrow = function() { 3480 var returned, then; 3481 3482 // Support: Promises/A+ section 2.3.3.3.3 3483 // https://promisesaplus.com/#point-59 3484 // Ignore double-resolution attempts 3485 if ( depth < maxDepth ) { 3486 return; 3487 } 3488 3489 returned = handler.apply( that, args ); 3490 3491 // Support: Promises/A+ section 2.3.1 3492 // https://promisesaplus.com/#point-48 3493 if ( returned === deferred.promise() ) { 3494 throw new TypeError( "Thenable self-resolution" ); 3495 } 3496 3497 // Support: Promises/A+ sections 2.3.3.1, 3.5 3498 // https://promisesaplus.com/#point-54 3499 // https://promisesaplus.com/#point-75 3500 // Retrieve `then` only once 3501 then = returned && 3502 3503 // Support: Promises/A+ section 2.3.4 3504 // https://promisesaplus.com/#point-64 3505 // Only check objects and functions for thenability 3506 ( typeof returned === "object" || 3507 typeof returned === "function" ) && 3508 returned.then; 3509 3510 // Handle a returned thenable 3511 if ( isFunction( then ) ) { 3512 3513 // Special processors (notify) just wait for resolution 3514 if ( special ) { 3515 then.call( 3516 returned, 3517 resolve( maxDepth, deferred, Identity, special ), 3518 resolve( maxDepth, deferred, Thrower, special ) 3519 ); 3520 3521 // Normal processors (resolve) also hook into progress 3522 } else { 3523 3524 // ...and disregard older resolution values 3525 maxDepth++; 3526 3527 then.call( 3528 returned, 3529 resolve( maxDepth, deferred, Identity, special ), 3530 resolve( maxDepth, deferred, Thrower, special ), 3531 resolve( maxDepth, deferred, Identity, 3532 deferred.notifyWith ) 3533 ); 3534 } 3535 3536 // Handle all other returned values 3537 } else { 3538 3539 // Only substitute handlers pass on context 3540 // and multiple values (non-spec behavior) 3541 if ( handler !== Identity ) { 3542 that = undefined; 3543 args = [ returned ]; 3544 } 3545 3546 // Process the value(s) 3547 // Default process is resolve 3548 ( special || deferred.resolveWith )( that, args ); 3549 } 3550 }, 3551 3552 // Only normal processors (resolve) catch and reject exceptions 3553 process = special ? 3554 mightThrow : 3555 function() { 3556 try { 3557 mightThrow(); 3558 } catch ( e ) { 3559 3560 if ( jQuery.Deferred.exceptionHook ) { 3561 jQuery.Deferred.exceptionHook( e, 3562 process.error ); 3563 } 3564 3565 // Support: Promises/A+ section 2.3.3.3.4.1 3566 // https://promisesaplus.com/#point-61 3567 // Ignore post-resolution exceptions 3568 if ( depth + 1 >= maxDepth ) { 3569 3570 // Only substitute handlers pass on context 3571 // and multiple values (non-spec behavior) 3572 if ( handler !== Thrower ) { 3573 that = undefined; 3574 args = [ e ]; 3575 } 3576 3577 deferred.rejectWith( that, args ); 3578 } 3579 } 3580 }; 3581 3582 // Support: Promises/A+ section 2.3.3.3.1 3583 // https://promisesaplus.com/#point-57 3584 // Re-resolve promises immediately to dodge false rejection from 3585 // subsequent errors 3586 if ( depth ) { 3587 process(); 3588 } else { 3589 3590 // Call an optional hook to record the error, in case of exception 3591 // since it's otherwise lost when execution goes async 3592 if ( jQuery.Deferred.getErrorHook ) { 3593 process.error = jQuery.Deferred.getErrorHook(); 3594 3595 // The deprecated alias of the above. While the name suggests 3596 // returning the stack, not an error instance, jQuery just passes 3597 // it directly to `console.warn` so both will work; an instance 3598 // just better cooperates with source maps. 3599 } else if ( jQuery.Deferred.getStackHook ) { 3600 process.error = jQuery.Deferred.getStackHook(); 3601 } 3602 window.setTimeout( process ); 3603 } 3604 }; 3605 } 3606 3607 return jQuery.Deferred( function( newDefer ) { 3608 3609 // progress_handlers.add( ... ) 3610 tuples[ 0 ][ 3 ].add( 3611 resolve( 3612 0, 3613 newDefer, 3614 isFunction( onProgress ) ? 3615 onProgress : 3616 Identity, 3617 newDefer.notifyWith 3618 ) 3619 ); 3620 3621 // fulfilled_handlers.add( ... ) 3622 tuples[ 1 ][ 3 ].add( 3623 resolve( 3624 0, 3625 newDefer, 3626 isFunction( onFulfilled ) ? 3627 onFulfilled : 3628 Identity 3629 ) 3630 ); 3631 3632 // rejected_handlers.add( ... ) 3633 tuples[ 2 ][ 3 ].add( 3634 resolve( 3635 0, 3636 newDefer, 3637 isFunction( onRejected ) ? 3638 onRejected : 3639 Thrower 3640 ) 3641 ); 3642 } ).promise(); 3643 }, 3644 3645 // Get a promise for this deferred 3646 // If obj is provided, the promise aspect is added to the object 3647 promise: function( obj ) { 3648 return obj != null ? jQuery.extend( obj, promise ) : promise; 3649 } 3650 }, 3651 deferred = {}; 3652 3653 // Add list-specific methods 3654 jQuery.each( tuples, function( i, tuple ) { 3655 var list = tuple[ 2 ], 3656 stateString = tuple[ 5 ]; 3657 3658 // promise.progress = list.add 3659 // promise.done = list.add 3660 // promise.fail = list.add 3661 promise[ tuple[ 1 ] ] = list.add; 3662 3663 // Handle state 3664 if ( stateString ) { 3665 list.add( 3666 function() { 3667 3668 // state = "resolved" (i.e., fulfilled) 3669 // state = "rejected" 3670 state = stateString; 3671 }, 3672 3673 // rejected_callbacks.disable 3674 // fulfilled_callbacks.disable 3675 tuples[ 3 - i ][ 2 ].disable, 3676 3677 // rejected_handlers.disable 3678 // fulfilled_handlers.disable 3679 tuples[ 3 - i ][ 3 ].disable, 3680 3681 // progress_callbacks.lock 3682 tuples[ 0 ][ 2 ].lock, 3683 3684 // progress_handlers.lock 3685 tuples[ 0 ][ 3 ].lock 3686 ); 3687 } 3688 3689 // progress_handlers.fire 3690 // fulfilled_handlers.fire 3691 // rejected_handlers.fire 3692 list.add( tuple[ 3 ].fire ); 3693 3694 // deferred.notify = function() { deferred.notifyWith(...) } 3695 // deferred.resolve = function() { deferred.resolveWith(...) } 3696 // deferred.reject = function() { deferred.rejectWith(...) } 3697 deferred[ tuple[ 0 ] ] = function() { 3698 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 3699 return this; 3700 }; 3701 3702 // deferred.notifyWith = list.fireWith 3703 // deferred.resolveWith = list.fireWith 3704 // deferred.rejectWith = list.fireWith 3705 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 3706 } ); 3707 3708 // Make the deferred a promise 3709 promise.promise( deferred ); 3710 3711 // Call given func if any 3712 if ( func ) { 3713 func.call( deferred, deferred ); 3714 } 3715 3716 // All done! 3717 return deferred; 3718 }, 3719 3720 // Deferred helper 3721 when: function( singleValue ) { 3722 var 3723 3724 // count of uncompleted subordinates 3725 remaining = arguments.length, 3726 3727 // count of unprocessed arguments 3728 i = remaining, 3729 3730 // subordinate fulfillment data 3731 resolveContexts = Array( i ), 3732 resolveValues = slice.call( arguments ), 3733 3734 // the primary Deferred 3735 primary = jQuery.Deferred(), 3736 3737 // subordinate callback factory 3738 updateFunc = function( i ) { 3739 return function( value ) { 3740 resolveContexts[ i ] = this; 3741 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 3742 if ( !( --remaining ) ) { 3743 primary.resolveWith( resolveContexts, resolveValues ); 3744 } 3745 }; 3746 }; 3747 3748 // Single- and empty arguments are adopted like Promise.resolve 3749 if ( remaining <= 1 ) { 3750 adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, 3751 !remaining ); 3752 3753 // Use .then() to unwrap secondary thenables (cf. gh-3000) 3754 if ( primary.state() === "pending" || 3755 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 3756 3757 return primary.then(); 3758 } 3759 } 3760 3761 // Multiple arguments are aggregated like Promise.all array elements 3762 while ( i-- ) { 3763 adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); 3764 } 3765 3766 return primary.promise(); 3767 } 3768} ); 3769 3770 3771// These usually indicate a programmer mistake during development, 3772// warn about them ASAP rather than swallowing them by default. 3773var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 3774 3775// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error 3776// captured before the async barrier to get the original error cause 3777// which may otherwise be hidden. 3778jQuery.Deferred.exceptionHook = function( error, asyncError ) { 3779 3780 // Support: IE 8 - 9 only 3781 // Console exists when dev tools are open, which can happen at any time 3782 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 3783 window.console.warn( "jQuery.Deferred exception: " + error.message, 3784 error.stack, asyncError ); 3785 } 3786}; 3787 3788 3789 3790 3791jQuery.readyException = function( error ) { 3792 window.setTimeout( function() { 3793 throw error; 3794 } ); 3795}; 3796 3797 3798 3799 3800// The deferred used on DOM ready 3801var readyList = jQuery.Deferred(); 3802 3803jQuery.fn.ready = function( fn ) { 3804 3805 readyList 3806 .then( fn ) 3807 3808 // Wrap jQuery.readyException in a function so that the lookup 3809 // happens at the time of error handling instead of callback 3810 // registration. 3811 .catch( function( error ) { 3812 jQuery.readyException( error ); 3813 } ); 3814 3815 return this; 3816}; 3817 3818jQuery.extend( { 3819 3820 // Is the DOM ready to be used? Set to true once it occurs. 3821 isReady: false, 3822 3823 // A counter to track how many items to wait for before 3824 // the ready event fires. See trac-6781 3825 readyWait: 1, 3826 3827 // Handle when the DOM is ready 3828 ready: function( wait ) { 3829 3830 // Abort if there are pending holds or we're already ready 3831 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 3832 return; 3833 } 3834 3835 // Remember that the DOM is ready 3836 jQuery.isReady = true; 3837 3838 // If a normal DOM Ready event fired, decrement, and wait if need be 3839 if ( wait !== true && --jQuery.readyWait > 0 ) { 3840 return; 3841 } 3842 3843 // If there are functions bound, to execute 3844 readyList.resolveWith( document, [ jQuery ] ); 3845 } 3846} ); 3847 3848jQuery.ready.then = readyList.then; 3849 3850// The ready event handler and self cleanup method 3851function completed() { 3852 document.removeEventListener( "DOMContentLoaded", completed ); 3853 window.removeEventListener( "load", completed ); 3854 jQuery.ready(); 3855} 3856 3857// Catch cases where $(document).ready() is called 3858// after the browser event has already occurred. 3859// Support: IE <=9 - 10 only 3860// Older IE sometimes signals "interactive" too soon 3861if ( document.readyState === "complete" || 3862 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 3863 3864 // Handle it asynchronously to allow scripts the opportunity to delay ready 3865 window.setTimeout( jQuery.ready ); 3866 3867} else { 3868 3869 // Use the handy event callback 3870 document.addEventListener( "DOMContentLoaded", completed ); 3871 3872 // A fallback to window.onload, that will always work 3873 window.addEventListener( "load", completed ); 3874} 3875 3876 3877 3878 3879// Multifunctional method to get and set values of a collection 3880// The value/s can optionally be executed if it's a function 3881var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 3882 var i = 0, 3883 len = elems.length, 3884 bulk = key == null; 3885 3886 // Sets many values 3887 if ( toType( key ) === "object" ) { 3888 chainable = true; 3889 for ( i in key ) { 3890 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 3891 } 3892 3893 // Sets one value 3894 } else if ( value !== undefined ) { 3895 chainable = true; 3896 3897 if ( !isFunction( value ) ) { 3898 raw = true; 3899 } 3900 3901 if ( bulk ) { 3902 3903 // Bulk operations run against the entire set 3904 if ( raw ) { 3905 fn.call( elems, value ); 3906 fn = null; 3907 3908 // ...except when executing function values 3909 } else { 3910 bulk = fn; 3911 fn = function( elem, _key, value ) { 3912 return bulk.call( jQuery( elem ), value ); 3913 }; 3914 } 3915 } 3916 3917 if ( fn ) { 3918 for ( ; i < len; i++ ) { 3919 fn( 3920 elems[ i ], key, raw ? 3921 value : 3922 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 3923 ); 3924 } 3925 } 3926 } 3927 3928 if ( chainable ) { 3929 return elems; 3930 } 3931 3932 // Gets 3933 if ( bulk ) { 3934 return fn.call( elems ); 3935 } 3936 3937 return len ? fn( elems[ 0 ], key ) : emptyGet; 3938}; 3939 3940 3941// Matches dashed string for camelizing 3942var rmsPrefix = /^-ms-/, 3943 rdashAlpha = /-([a-z])/g; 3944 3945// Used by camelCase as callback to replace() 3946function fcamelCase( _all, letter ) { 3947 return letter.toUpperCase(); 3948} 3949 3950// Convert dashed to camelCase; used by the css and data modules 3951// Support: IE <=9 - 11, Edge 12 - 15 3952// Microsoft forgot to hump their vendor prefix (trac-9572) 3953function camelCase( string ) { 3954 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 3955} 3956var acceptData = function( owner ) { 3957 3958 // Accepts only: 3959 // - Node 3960 // - Node.ELEMENT_NODE 3961 // - Node.DOCUMENT_NODE 3962 // - Object 3963 // - Any 3964 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 3965}; 3966 3967 3968 3969 3970function Data() { 3971 this.expando = jQuery.expando + Data.uid++; 3972} 3973 3974Data.uid = 1; 3975 3976Data.prototype = { 3977 3978 cache: function( owner ) { 3979 3980 // Check if the owner object already has a cache 3981 var value = owner[ this.expando ]; 3982 3983 // If not, create one 3984 if ( !value ) { 3985 value = {}; 3986 3987 // We can accept data for non-element nodes in modern browsers, 3988 // but we should not, see trac-8335. 3989 // Always return an empty object. 3990 if ( acceptData( owner ) ) { 3991 3992 // If it is a node unlikely to be stringify-ed or looped over 3993 // use plain assignment 3994 if ( owner.nodeType ) { 3995 owner[ this.expando ] = value; 3996 3997 // Otherwise secure it in a non-enumerable property 3998 // configurable must be true to allow the property to be 3999 // deleted when data is removed 4000 } else { 4001 Object.defineProperty( owner, this.expando, { 4002 value: value, 4003 configurable: true 4004 } ); 4005 } 4006 } 4007 } 4008 4009 return value; 4010 }, 4011 set: function( owner, data, value ) { 4012 var prop, 4013 cache = this.cache( owner ); 4014 4015 // Handle: [ owner, key, value ] args 4016 // Always use camelCase key (gh-2257) 4017 if ( typeof data === "string" ) { 4018 cache[ camelCase( data ) ] = value; 4019 4020 // Handle: [ owner, { properties } ] args 4021 } else { 4022 4023 // Copy the properties one-by-one to the cache object 4024 for ( prop in data ) { 4025 cache[ camelCase( prop ) ] = data[ prop ]; 4026 } 4027 } 4028 return cache; 4029 }, 4030 get: function( owner, key ) { 4031 return key === undefined ? 4032 this.cache( owner ) : 4033 4034 // Always use camelCase key (gh-2257) 4035 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 4036 }, 4037 access: function( owner, key, value ) { 4038 4039 // In cases where either: 4040 // 4041 // 1. No key was specified 4042 // 2. A string key was specified, but no value provided 4043 // 4044 // Take the "read" path and allow the get method to determine 4045 // which value to return, respectively either: 4046 // 4047 // 1. The entire cache object 4048 // 2. The data stored at the key 4049 // 4050 if ( key === undefined || 4051 ( ( key && typeof key === "string" ) && value === undefined ) ) { 4052 4053 return this.get( owner, key ); 4054 } 4055 4056 // When the key is not a string, or both a key and value 4057 // are specified, set or extend (existing objects) with either: 4058 // 4059 // 1. An object of properties 4060 // 2. A key and value 4061 // 4062 this.set( owner, key, value ); 4063 4064 // Since the "set" path can have two possible entry points 4065 // return the expected data based on which path was taken[*] 4066 return value !== undefined ? value : key; 4067 }, 4068 remove: function( owner, key ) { 4069 var i, 4070 cache = owner[ this.expando ]; 4071 4072 if ( cache === undefined ) { 4073 return; 4074 } 4075 4076 if ( key !== undefined ) { 4077 4078 // Support array or space separated string of keys 4079 if ( Array.isArray( key ) ) { 4080 4081 // If key is an array of keys... 4082 // We always set camelCase keys, so remove that. 4083 key = key.map( camelCase ); 4084 } else { 4085 key = camelCase( key ); 4086 4087 // If a key with the spaces exists, use it. 4088 // Otherwise, create an array by matching non-whitespace 4089 key = key in cache ? 4090 [ key ] : 4091 ( key.match( rnothtmlwhite ) || [] ); 4092 } 4093 4094 i = key.length; 4095 4096 while ( i-- ) { 4097 delete cache[ key[ i ] ]; 4098 } 4099 } 4100 4101 // Remove the expando if there's no more data 4102 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 4103 4104 // Support: Chrome <=35 - 45 4105 // Webkit & Blink performance suffers when deleting properties 4106 // from DOM nodes, so set to undefined instead 4107 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 4108 if ( owner.nodeType ) { 4109 owner[ this.expando ] = undefined; 4110 } else { 4111 delete owner[ this.expando ]; 4112 } 4113 } 4114 }, 4115 hasData: function( owner ) { 4116 var cache = owner[ this.expando ]; 4117 return cache !== undefined && !jQuery.isEmptyObject( cache ); 4118 } 4119}; 4120var dataPriv = new Data(); 4121 4122var dataUser = new Data(); 4123 4124 4125 4126// Implementation Summary 4127// 4128// 1. Enforce API surface and semantic compatibility with 1.9.x branch 4129// 2. Improve the module's maintainability by reducing the storage 4130// paths to a single mechanism. 4131// 3. Use the same single mechanism to support "private" and "user" data. 4132// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 4133// 5. Avoid exposing implementation details on user objects (eg. expando properties) 4134// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 4135 4136var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 4137 rmultiDash = /[A-Z]/g; 4138 4139function getData( data ) { 4140 if ( data === "true" ) { 4141 return true; 4142 } 4143 4144 if ( data === "false" ) { 4145 return false; 4146 } 4147 4148 if ( data === "null" ) { 4149 return null; 4150 } 4151 4152 // Only convert to a number if it doesn't change the string 4153 if ( data === +data + "" ) { 4154 return +data; 4155 } 4156 4157 if ( rbrace.test( data ) ) { 4158 return JSON.parse( data ); 4159 } 4160 4161 return data; 4162} 4163 4164function dataAttr( elem, key, data ) { 4165 var name; 4166 4167 // If nothing was found internally, try to fetch any 4168 // data from the HTML5 data-* attribute 4169 if ( data === undefined && elem.nodeType === 1 ) { 4170 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 4171 data = elem.getAttribute( name ); 4172 4173 if ( typeof data === "string" ) { 4174 try { 4175 data = getData( data ); 4176 } catch ( e ) {} 4177 4178 // Make sure we set the data so it isn't changed later 4179 dataUser.set( elem, key, data ); 4180 } else { 4181 data = undefined; 4182 } 4183 } 4184 return data; 4185} 4186 4187jQuery.extend( { 4188 hasData: function( elem ) { 4189 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 4190 }, 4191 4192 data: function( elem, name, data ) { 4193 return dataUser.access( elem, name, data ); 4194 }, 4195 4196 removeData: function( elem, name ) { 4197 dataUser.remove( elem, name ); 4198 }, 4199 4200 // TODO: Now that all calls to _data and _removeData have been replaced 4201 // with direct calls to dataPriv methods, these can be deprecated. 4202 _data: function( elem, name, data ) { 4203 return dataPriv.access( elem, name, data ); 4204 }, 4205 4206 _removeData: function( elem, name ) { 4207 dataPriv.remove( elem, name ); 4208 } 4209} ); 4210 4211jQuery.fn.extend( { 4212 data: function( key, value ) { 4213 var i, name, data, 4214 elem = this[ 0 ], 4215 attrs = elem && elem.attributes; 4216 4217 // Gets all values 4218 if ( key === undefined ) { 4219 if ( this.length ) { 4220 data = dataUser.get( elem ); 4221 4222 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 4223 i = attrs.length; 4224 while ( i-- ) { 4225 4226 // Support: IE 11 only 4227 // The attrs elements can be null (trac-14894) 4228 if ( attrs[ i ] ) { 4229 name = attrs[ i ].name; 4230 if ( name.indexOf( "data-" ) === 0 ) { 4231 name = camelCase( name.slice( 5 ) ); 4232 dataAttr( elem, name, data[ name ] ); 4233 } 4234 } 4235 } 4236 dataPriv.set( elem, "hasDataAttrs", true ); 4237 } 4238 } 4239 4240 return data; 4241 } 4242 4243 // Sets multiple values 4244 if ( typeof key === "object" ) { 4245 return this.each( function() { 4246 dataUser.set( this, key ); 4247 } ); 4248 } 4249 4250 return access( this, function( value ) { 4251 var data; 4252 4253 // The calling jQuery object (element matches) is not empty 4254 // (and therefore has an element appears at this[ 0 ]) and the 4255 // `value` parameter was not undefined. An empty jQuery object 4256 // will result in `undefined` for elem = this[ 0 ] which will 4257 // throw an exception if an attempt to read a data cache is made. 4258 if ( elem && value === undefined ) { 4259 4260 // Attempt to get data from the cache 4261 // The key will always be camelCased in Data 4262 data = dataUser.get( elem, key ); 4263 if ( data !== undefined ) { 4264 return data; 4265 } 4266 4267 // Attempt to "discover" the data in 4268 // HTML5 custom data-* attrs 4269 data = dataAttr( elem, key ); 4270 if ( data !== undefined ) { 4271 return data; 4272 } 4273 4274 // We tried really hard, but the data doesn't exist. 4275 return; 4276 } 4277 4278 // Set the data... 4279 this.each( function() { 4280 4281 // We always store the camelCased key 4282 dataUser.set( this, key, value ); 4283 } ); 4284 }, null, value, arguments.length > 1, null, true ); 4285 }, 4286 4287 removeData: function( key ) { 4288 return this.each( function() { 4289 dataUser.remove( this, key ); 4290 } ); 4291 } 4292} ); 4293 4294 4295jQuery.extend( { 4296 queue: function( elem, type, data ) { 4297 var queue; 4298 4299 if ( elem ) { 4300 type = ( type || "fx" ) + "queue"; 4301 queue = dataPriv.get( elem, type ); 4302 4303 // Speed up dequeue by getting out quickly if this is just a lookup 4304 if ( data ) { 4305 if ( !queue || Array.isArray( data ) ) { 4306 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 4307 } else { 4308 queue.push( data ); 4309 } 4310 } 4311 return queue || []; 4312 } 4313 }, 4314 4315 dequeue: function( elem, type ) { 4316 type = type || "fx"; 4317 4318 var queue = jQuery.queue( elem, type ), 4319 startLength = queue.length, 4320 fn = queue.shift(), 4321 hooks = jQuery._queueHooks( elem, type ), 4322 next = function() { 4323 jQuery.dequeue( elem, type ); 4324 }; 4325 4326 // If the fx queue is dequeued, always remove the progress sentinel 4327 if ( fn === "inprogress" ) { 4328 fn = queue.shift(); 4329 startLength--; 4330 } 4331 4332 if ( fn ) { 4333 4334 // Add a progress sentinel to prevent the fx queue from being 4335 // automatically dequeued 4336 if ( type === "fx" ) { 4337 queue.unshift( "inprogress" ); 4338 } 4339 4340 // Clear up the last queue stop function 4341 delete hooks.stop; 4342 fn.call( elem, next, hooks ); 4343 } 4344 4345 if ( !startLength && hooks ) { 4346 hooks.empty.fire(); 4347 } 4348 }, 4349 4350 // Not public - generate a queueHooks object, or return the current one 4351 _queueHooks: function( elem, type ) { 4352 var key = type + "queueHooks"; 4353 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 4354 empty: jQuery.Callbacks( "once memory" ).add( function() { 4355 dataPriv.remove( elem, [ type + "queue", key ] ); 4356 } ) 4357 } ); 4358 } 4359} ); 4360 4361jQuery.fn.extend( { 4362 queue: function( type, data ) { 4363 var setter = 2; 4364 4365 if ( typeof type !== "string" ) { 4366 data = type; 4367 type = "fx"; 4368 setter--; 4369 } 4370 4371 if ( arguments.length < setter ) { 4372 return jQuery.queue( this[ 0 ], type ); 4373 } 4374 4375 return data === undefined ? 4376 this : 4377 this.each( function() { 4378 var queue = jQuery.queue( this, type, data ); 4379 4380 // Ensure a hooks for this queue 4381 jQuery._queueHooks( this, type ); 4382 4383 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 4384 jQuery.dequeue( this, type ); 4385 } 4386 } ); 4387 }, 4388 dequeue: function( type ) { 4389 return this.each( function() { 4390 jQuery.dequeue( this, type ); 4391 } ); 4392 }, 4393 clearQueue: function( type ) { 4394 return this.queue( type || "fx", [] ); 4395 }, 4396 4397 // Get a promise resolved when queues of a certain type 4398 // are emptied (fx is the type by default) 4399 promise: function( type, obj ) { 4400 var tmp, 4401 count = 1, 4402 defer = jQuery.Deferred(), 4403 elements = this, 4404 i = this.length, 4405 resolve = function() { 4406 if ( !( --count ) ) { 4407 defer.resolveWith( elements, [ elements ] ); 4408 } 4409 }; 4410 4411 if ( typeof type !== "string" ) { 4412 obj = type; 4413 type = undefined; 4414 } 4415 type = type || "fx"; 4416 4417 while ( i-- ) { 4418 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 4419 if ( tmp && tmp.empty ) { 4420 count++; 4421 tmp.empty.add( resolve ); 4422 } 4423 } 4424 resolve(); 4425 return defer.promise( obj ); 4426 } 4427} ); 4428var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 4429 4430var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 4431 4432 4433var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 4434 4435var documentElement = document.documentElement; 4436 4437 4438 4439 var isAttached = function( elem ) { 4440 return jQuery.contains( elem.ownerDocument, elem ); 4441 }, 4442 composed = { composed: true }; 4443 4444 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 4445 // Check attachment across shadow DOM boundaries when possible (gh-3504) 4446 // Support: iOS 10.0-10.2 only 4447 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 4448 // leading to errors. We need to check for `getRootNode`. 4449 if ( documentElement.getRootNode ) { 4450 isAttached = function( elem ) { 4451 return jQuery.contains( elem.ownerDocument, elem ) || 4452 elem.getRootNode( composed ) === elem.ownerDocument; 4453 }; 4454 } 4455var isHiddenWithinTree = function( elem, el ) { 4456 4457 // isHiddenWithinTree might be called from jQuery#filter function; 4458 // in that case, element will be second argument 4459 elem = el || elem; 4460 4461 // Inline style trumps all 4462 return elem.style.display === "none" || 4463 elem.style.display === "" && 4464 4465 // Otherwise, check computed style 4466 // Support: Firefox <=43 - 45 4467 // Disconnected elements can have computed display: none, so first confirm that elem is 4468 // in the document. 4469 isAttached( elem ) && 4470 4471 jQuery.css( elem, "display" ) === "none"; 4472 }; 4473 4474 4475 4476function adjustCSS( elem, prop, valueParts, tween ) { 4477 var adjusted, scale, 4478 maxIterations = 20, 4479 currentValue = tween ? 4480 function() { 4481 return tween.cur(); 4482 } : 4483 function() { 4484 return jQuery.css( elem, prop, "" ); 4485 }, 4486 initial = currentValue(), 4487 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 4488 4489 // Starting value computation is required for potential unit mismatches 4490 initialInUnit = elem.nodeType && 4491 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 4492 rcssNum.exec( jQuery.css( elem, prop ) ); 4493 4494 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 4495 4496 // Support: Firefox <=54 4497 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 4498 initial = initial / 2; 4499 4500 // Trust units reported by jQuery.css 4501 unit = unit || initialInUnit[ 3 ]; 4502 4503 // Iteratively approximate from a nonzero starting point 4504 initialInUnit = +initial || 1; 4505 4506 while ( maxIterations-- ) { 4507 4508 // Evaluate and update our best guess (doubling guesses that zero out). 4509 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 4510 jQuery.style( elem, prop, initialInUnit + unit ); 4511 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 4512 maxIterations = 0; 4513 } 4514 initialInUnit = initialInUnit / scale; 4515 4516 } 4517 4518 initialInUnit = initialInUnit * 2; 4519 jQuery.style( elem, prop, initialInUnit + unit ); 4520 4521 // Make sure we update the tween properties later on 4522 valueParts = valueParts || []; 4523 } 4524 4525 if ( valueParts ) { 4526 initialInUnit = +initialInUnit || +initial || 0; 4527 4528 // Apply relative offset (+=/-=) if specified 4529 adjusted = valueParts[ 1 ] ? 4530 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 4531 +valueParts[ 2 ]; 4532 if ( tween ) { 4533 tween.unit = unit; 4534 tween.start = initialInUnit; 4535 tween.end = adjusted; 4536 } 4537 } 4538 return adjusted; 4539} 4540 4541 4542var defaultDisplayMap = {}; 4543 4544function getDefaultDisplay( elem ) { 4545 var temp, 4546 doc = elem.ownerDocument, 4547 nodeName = elem.nodeName, 4548 display = defaultDisplayMap[ nodeName ]; 4549 4550 if ( display ) {
vendor: 2,317 bytes, lines 4551-4649
4551 return display; 4552 } 4553 4554 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 4555 display = jQuery.css( temp, "display" ); 4556 4557 temp.parentNode.removeChild( temp ); 4558 4559 if ( display === "none" ) { 4560 display = "block"; 4561 } 4562 defaultDisplayMap[ nodeName ] = display; 4563 4564 return display; 4565} 4566 4567function showHide( elements, show ) { 4568 var display, elem, 4569 values = [], 4570 index = 0, 4571 length = elements.length; 4572 4573 // Determine new display value for elements that need to change 4574 for ( ; index < length; index++ ) { 4575 elem = elements[ index ]; 4576 if ( !elem.style ) { 4577 continue; 4578 } 4579 4580 display = elem.style.display; 4581 if ( show ) { 4582 4583 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 4584 // check is required in this first loop unless we have a nonempty display value (either 4585 // inline or about-to-be-restored) 4586 if ( display === "none" ) { 4587 values[ index ] = dataPriv.get( elem, "display" ) || null; 4588 if ( !values[ index ] ) { 4589 elem.style.display = ""; 4590 } 4591 } 4592 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 4593 values[ index ] = getDefaultDisplay( elem ); 4594 } 4595 } else { 4596 if ( display !== "none" ) { 4597 values[ index ] = "none"; 4598 4599 // Remember what we're overwriting 4600 dataPriv.set( elem, "display", display ); 4601 } 4602 } 4603 } 4604 4605 // Set the display of the elements in a second loop to avoid constant reflow 4606 for ( index = 0; index < length; index++ ) { 4607 if ( values[ index ] != null ) { 4608 elements[ index ].style.display = values[ index ]; 4609 } 4610 } 4611 4612 return elements; 4613} 4614 4615jQuery.fn.extend( { 4616 show: function() { 4617 return showHide( this, true ); 4618 }, 4619 hide: function() { 4620 return showHide( this ); 4621 }, 4622 toggle: function( state ) { 4623 if ( typeof state === "boolean" ) { 4624 return state ? this.show() : this.hide(); 4625 } 4626 4627 return this.each( function() { 4628 if ( isHiddenWithinTree( this ) ) { 4629 jQuery( this ).show(); 4630 } else { 4631 jQuery( this ).hide(); 4632 } 4633 } ); 4634 } 4635} ); 4636var rcheckableType = ( /^(?:checkbox|radio)$/i ); 4637 4638var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 4639 4640var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 4641 4642 4643 4644( function() { 4645 var fragment = document.createDocumentFragment(), 4646 div = fragment.appendChild( document.createElement( "div" ) ), 4647 input = document.createElement( "input" ); 4648 4649 // Support: Android 4.0 - 4.3 only
vendor: 10,092 bytes, lines 4650-5034
4650 // Check state lost if the name is set (trac-11217) 4651 // Support: Windows Web Apps (WWA) 4652 // `name` and `type` must use .setAttribute for WWA (trac-14901) 4653 input.setAttribute( "type", "radio" ); 4654 input.setAttribute( "checked", "checked" ); 4655 input.setAttribute( "name", "t" ); 4656 4657 div.appendChild( input ); 4658 4659 // Support: Android <=4.1 only 4660 // Older WebKit doesn't clone checked state correctly in fragments 4661 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 4662 4663 // Support: IE <=11 only 4664 // Make sure textarea (and checkbox) defaultValue is properly cloned 4665 div.innerHTML = "<textarea>x</textarea>"; 4666 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 4667 4668 // Support: IE <=9 only 4669 // IE <=9 replaces <option> tags with their contents when inserted outside of 4670 // the select element. 4671 div.innerHTML = "<option></option>"; 4672 support.option = !!div.lastChild; 4673} )(); 4674 4675 4676// We have to close these tags to support XHTML (trac-13200) 4677var wrapMap = { 4678 4679 // XHTML parsers do not magically insert elements in the 4680 // same way that tag soup parsers do. So we cannot shorten 4681 // this by omitting <tbody> or other required elements. 4682 thead: [ 1, "<table>", "</table>" ], 4683 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 4684 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 4685 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 4686 4687 _default: [ 0, "", "" ] 4688}; 4689 4690wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4691wrapMap.th = wrapMap.td; 4692 4693// Support: IE <=9 only 4694if ( !support.option ) { 4695 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; 4696} 4697 4698 4699function getAll( context, tag ) { 4700 4701 // Support: IE <=9 - 11 only 4702 // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) 4703 var ret; 4704 4705 if ( typeof context.getElementsByTagName !== "undefined" ) { 4706 ret = context.getElementsByTagName( tag || "*" ); 4707 4708 } else if ( typeof context.querySelectorAll !== "undefined" ) { 4709 ret = context.querySelectorAll( tag || "*" ); 4710 4711 } else { 4712 ret = []; 4713 } 4714 4715 if ( tag === undefined || tag && nodeName( context, tag ) ) { 4716 return jQuery.merge( [ context ], ret ); 4717 } 4718 4719 return ret; 4720} 4721 4722 4723// Mark scripts as having already been evaluated 4724function setGlobalEval( elems, refElements ) { 4725 var i = 0, 4726 l = elems.length; 4727 4728 for ( ; i < l; i++ ) { 4729 dataPriv.set( 4730 elems[ i ], 4731 "globalEval", 4732 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 4733 ); 4734 } 4735} 4736 4737 4738var rhtml = /<|&#?\w+;/; 4739 4740function buildFragment( elems, context, scripts, selection, ignored ) { 4741 var elem, tmp, tag, wrap, attached, j, 4742 fragment = context.createDocumentFragment(), 4743 nodes = [], 4744 i = 0, 4745 l = elems.length; 4746 4747 for ( ; i < l; i++ ) { 4748 elem = elems[ i ]; 4749 4750 if ( elem || elem === 0 ) { 4751 4752 // Add nodes directly 4753 if ( toType( elem ) === "object" ) { 4754 4755 // Support: Android <=4.0 only, PhantomJS 1 only 4756 // push.apply(_, arraylike) throws on ancient WebKit 4757 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 4758 4759 // Convert non-html into a text node 4760 } else if ( !rhtml.test( elem ) ) { 4761 nodes.push( context.createTextNode( elem ) ); 4762 4763 // Convert html into DOM nodes 4764 } else { 4765 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 4766 4767 // Deserialize a standard representation 4768 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 4769 wrap = wrapMap[ tag ] || wrapMap._default; 4770 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 4771 4772 // Descend through wrappers to the right content 4773 j = wrap[ 0 ]; 4774 while ( j-- ) { 4775 tmp = tmp.lastChild; 4776 } 4777 4778 // Support: Android <=4.0 only, PhantomJS 1 only 4779 // push.apply(_, arraylike) throws on ancient WebKit 4780 jQuery.merge( nodes, tmp.childNodes ); 4781 4782 // Remember the top-level container 4783 tmp = fragment.firstChild; 4784 4785 // Ensure the created nodes are orphaned (trac-12392) 4786 tmp.textContent = ""; 4787 } 4788 } 4789 } 4790 4791 // Remove wrapper from fragment 4792 fragment.textContent = ""; 4793 4794 i = 0; 4795 while ( ( elem = nodes[ i++ ] ) ) { 4796 4797 // Skip elements already in the context collection (trac-4087) 4798 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 4799 if ( ignored ) { 4800 ignored.push( elem ); 4801 } 4802 continue; 4803 } 4804 4805 attached = isAttached( elem ); 4806 4807 // Append to fragment 4808 tmp = getAll( fragment.appendChild( elem ), "script" ); 4809 4810 // Preserve script evaluation history 4811 if ( attached ) { 4812 setGlobalEval( tmp ); 4813 } 4814 4815 // Capture executables 4816 if ( scripts ) { 4817 j = 0; 4818 while ( ( elem = tmp[ j++ ] ) ) { 4819 if ( rscriptType.test( elem.type || "" ) ) { 4820 scripts.push( elem ); 4821 } 4822 } 4823 } 4824 } 4825 4826 return fragment; 4827} 4828 4829 4830var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 4831 4832function returnTrue() { 4833 return true; 4834} 4835 4836function returnFalse() { 4837 return false; 4838} 4839 4840function on( elem, types, selector, data, fn, one ) { 4841 var origFn, type; 4842 4843 // Types can be a map of types/handlers 4844 if ( typeof types === "object" ) { 4845 4846 // ( types-Object, selector, data ) 4847 if ( typeof selector !== "string" ) { 4848 4849 // ( types-Object, data ) 4850 data = data || selector; 4851 selector = undefined; 4852 } 4853 for ( type in types ) { 4854 on( elem, type, selector, data, types[ type ], one ); 4855 } 4856 return elem; 4857 } 4858 4859 if ( data == null && fn == null ) { 4860 4861 // ( types, fn ) 4862 fn = selector; 4863 data = selector = undefined; 4864 } else if ( fn == null ) { 4865 if ( typeof selector === "string" ) { 4866 4867 // ( types, selector, fn ) 4868 fn = data; 4869 data = undefined; 4870 } else { 4871 4872 // ( types, data, fn ) 4873 fn = data; 4874 data = selector; 4875 selector = undefined; 4876 } 4877 } 4878 if ( fn === false ) { 4879 fn = returnFalse; 4880 } else if ( !fn ) { 4881 return elem; 4882 } 4883 4884 if ( one === 1 ) { 4885 origFn = fn; 4886 fn = function( event ) { 4887 4888 // Can use an empty set, since event contains the info 4889 jQuery().off( event ); 4890 return origFn.apply( this, arguments ); 4891 }; 4892 4893 // Use same guid so caller can remove using origFn 4894 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 4895 } 4896 return elem.each( function() { 4897 jQuery.event.add( this, types, fn, data, selector ); 4898 } ); 4899} 4900 4901/* 4902 * Helper functions for managing events -- not part of the public interface. 4903 * Props to Dean Edwards' addEvent library for many of the ideas. 4904 */ 4905jQuery.event = { 4906 4907 global: {}, 4908 4909 add: function( elem, types, handler, data, selector ) { 4910 4911 var handleObjIn, eventHandle, tmp, 4912 events, t, handleObj, 4913 special, handlers, type, namespaces, origType, 4914 elemData = dataPriv.get( elem ); 4915 4916 // Only attach events to objects that accept data 4917 if ( !acceptData( elem ) ) { 4918 return; 4919 } 4920 4921 // Caller can pass in an object of custom data in lieu of the handler 4922 if ( handler.handler ) { 4923 handleObjIn = handler; 4924 handler = handleObjIn.handler; 4925 selector = handleObjIn.selector; 4926 } 4927 4928 // Ensure that invalid selectors throw exceptions at attach time 4929 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 4930 if ( selector ) { 4931 jQuery.find.matchesSelector( documentElement, selector ); 4932 } 4933 4934 // Make sure that the handler has a unique ID, used to find/remove it later 4935 if ( !handler.guid ) { 4936 handler.guid = jQuery.guid++; 4937 } 4938 4939 // Init the element's event structure and main handler, if this is the first 4940 if ( !( events = elemData.events ) ) { 4941 events = elemData.events = Object.create( null ); 4942 } 4943 if ( !( eventHandle = elemData.handle ) ) { 4944 eventHandle = elemData.handle = function( e ) { 4945 4946 // Discard the second event of a jQuery.event.trigger() and 4947 // when an event is called after a page has unloaded 4948 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 4949 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 4950 }; 4951 } 4952 4953 // Handle multiple events separated by a space 4954 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 4955 t = types.length; 4956 while ( t-- ) { 4957 tmp = rtypenamespace.exec( types[ t ] ) || []; 4958 type = origType = tmp[ 1 ]; 4959 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 4960 4961 // There *must* be a type, no attaching namespace-only handlers 4962 if ( !type ) { 4963 continue; 4964 } 4965 4966 // If event changes its type, use the special event handlers for the changed type 4967 special = jQuery.event.special[ type ] || {}; 4968 4969 // If selector defined, determine special event api type, otherwise given type 4970 type = ( selector ? special.delegateType : special.bindType ) || type; 4971 4972 // Update special based on newly reset type 4973 special = jQuery.event.special[ type ] || {}; 4974 4975 // handleObj is passed to all event handlers 4976 handleObj = jQuery.extend( { 4977 type: type, 4978 origType: origType, 4979 data: data, 4980 handler: handler, 4981 guid: handler.guid, 4982 selector: selector, 4983 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 4984 namespace: namespaces.join( "." ) 4985 }, handleObjIn ); 4986 4987 // Init the event handler queue if we're the first 4988 if ( !( handlers = events[ type ] ) ) { 4989 handlers = events[ type ] = []; 4990 handlers.delegateCount = 0; 4991 4992 // Only use addEventListener if the special events handler returns false 4993 if ( !special.setup || 4994 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 4995 4996 if ( elem.addEventListener ) { 4997 elem.addEventListener( type, eventHandle ); 4998 } 4999 } 5000 } 5001 5002 if ( special.add ) { 5003 special.add.call( elem, handleObj ); 5004 5005 if ( !handleObj.handler.guid ) { 5006 handleObj.handler.guid = handler.guid; 5007 } 5008 } 5009 5010 // Add to the element's handler list, delegates in front 5011 if ( selector ) { 5012 handlers.splice( handlers.delegateCount++, 0, handleObj ); 5013 } else { 5014 handlers.push( handleObj ); 5015 } 5016 5017 // Keep track of which events have ever been used, for event optimization 5018 jQuery.event.global[ type ] = true; 5019 } 5020 5021 }, 5022 5023 // Detach an event or set of events from an element 5024 remove: function( elem, types, handler, selector, mappedTypes ) { 5025 5026 var j, origCount, tmp, 5027 events, t, handleObj, 5028 special, handlers, type, namespaces, origType, 5029 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 5030 5031 if ( !elemData || !( events = elemData.events ) ) { 5032 return; 5033 } 5034
vendor: 4,197 bytes, lines 5035-5173
5035 // Once for each type.namespace in types; type may be omitted 5036 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 5037 t = types.length; 5038 while ( t-- ) { 5039 tmp = rtypenamespace.exec( types[ t ] ) || []; 5040 type = origType = tmp[ 1 ]; 5041 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 5042 5043 // Unbind all events (on this namespace, if provided) for the element 5044 if ( !type ) { 5045 for ( type in events ) { 5046 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 5047 } 5048 continue; 5049 } 5050 5051 special = jQuery.event.special[ type ] || {}; 5052 type = ( selector ? special.delegateType : special.bindType ) || type; 5053 handlers = events[ type ] || []; 5054 tmp = tmp[ 2 ] && 5055 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 5056 5057 // Remove matching events 5058 origCount = j = handlers.length; 5059 while ( j-- ) { 5060 handleObj = handlers[ j ]; 5061 5062 if ( ( mappedTypes || origType === handleObj.origType ) && 5063 ( !handler || handler.guid === handleObj.guid ) && 5064 ( !tmp || tmp.test( handleObj.namespace ) ) && 5065 ( !selector || selector === handleObj.selector || 5066 selector === "**" && handleObj.selector ) ) { 5067 handlers.splice( j, 1 ); 5068 5069 if ( handleObj.selector ) { 5070 handlers.delegateCount--; 5071 } 5072 if ( special.remove ) { 5073 special.remove.call( elem, handleObj ); 5074 } 5075 } 5076 } 5077 5078 // Remove generic event handler if we removed something and no more handlers exist 5079 // (avoids potential for endless recursion during removal of special event handlers) 5080 if ( origCount && !handlers.length ) { 5081 if ( !special.teardown || 5082 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 5083 5084 jQuery.removeEvent( elem, type, elemData.handle ); 5085 } 5086 5087 delete events[ type ]; 5088 } 5089 } 5090 5091 // Remove data and the expando if it's no longer used 5092 if ( jQuery.isEmptyObject( events ) ) { 5093 dataPriv.remove( elem, "handle events" ); 5094 } 5095 }, 5096 5097 dispatch: function( nativeEvent ) { 5098 5099 var i, j, ret, matched, handleObj, handlerQueue, 5100 args = new Array( arguments.length ), 5101 5102 // Make a writable jQuery.Event from the native event object 5103 event = jQuery.event.fix( nativeEvent ), 5104 5105 handlers = ( 5106 dataPriv.get( this, "events" ) || Object.create( null ) 5107 )[ event.type ] || [], 5108 special = jQuery.event.special[ event.type ] || {}; 5109 5110 // Use the fix-ed jQuery.Event rather than the (read-only) native event 5111 args[ 0 ] = event; 5112 5113 for ( i = 1; i < arguments.length; i++ ) { 5114 args[ i ] = arguments[ i ]; 5115 } 5116 5117 event.delegateTarget = this; 5118 5119 // Call the preDispatch hook for the mapped type, and let it bail if desired 5120 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 5121 return; 5122 } 5123 5124 // Determine handlers 5125 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 5126 5127 // Run delegates first; they may want to stop propagation beneath us 5128 i = 0; 5129 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 5130 event.currentTarget = matched.elem; 5131 5132 j = 0; 5133 while ( ( handleObj = matched.handlers[ j++ ] ) && 5134 !event.isImmediatePropagationStopped() ) { 5135 5136 // If the event is namespaced, then each handler is only invoked if it is 5137 // specially universal or its namespaces are a superset of the event's. 5138 if ( !event.rnamespace || handleObj.namespace === false || 5139 event.rnamespace.test( handleObj.namespace ) ) { 5140 5141 event.handleObj = handleObj; 5142 event.data = handleObj.data; 5143 5144 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 5145 handleObj.handler ).apply( matched.elem, args ); 5146 5147 if ( ret !== undefined ) { 5148 if ( ( event.result = ret ) === false ) { 5149 event.preventDefault(); 5150 event.stopPropagation(); 5151 } 5152 } 5153 } 5154 } 5155 } 5156 5157 // Call the postDispatch hook for the mapped type 5158 if ( special.postDispatch ) { 5159 special.postDispatch.call( this, event ); 5160 } 5161 5162 return event.result; 5163 }, 5164 5165 handlers: function( event, handlers ) { 5166 var i, handleObj, sel, matchedHandlers, matchedSelectors, 5167 handlerQueue = [], 5168 delegateCount = handlers.delegateCount, 5169 cur = event.target; 5170 5171 // Find delegate handlers 5172 if ( delegateCount && 5173
vendor: 19,034 bytes, lines 5174-5820
5174 // Support: IE <=9 5175 // Black-hole SVG <use> instance trees (trac-13180) 5176 cur.nodeType && 5177 5178 // Support: Firefox <=42 5179 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 5180 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 5181 // Support: IE 11 only 5182 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 5183 !( event.type === "click" && event.button >= 1 ) ) { 5184 5185 for ( ; cur !== this; cur = cur.parentNode || this ) { 5186 5187 // Don't check non-elements (trac-13208) 5188 // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) 5189 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 5190 matchedHandlers = []; 5191 matchedSelectors = {}; 5192 for ( i = 0; i < delegateCount; i++ ) { 5193 handleObj = handlers[ i ]; 5194 5195 // Don't conflict with Object.prototype properties (trac-13203) 5196 sel = handleObj.selector + " "; 5197 5198 if ( matchedSelectors[ sel ] === undefined ) { 5199 matchedSelectors[ sel ] = handleObj.needsContext ? 5200 jQuery( sel, this ).index( cur ) > -1 : 5201 jQuery.find( sel, this, null, [ cur ] ).length; 5202 } 5203 if ( matchedSelectors[ sel ] ) { 5204 matchedHandlers.push( handleObj ); 5205 } 5206 } 5207 if ( matchedHandlers.length ) { 5208 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 5209 } 5210 } 5211 } 5212 } 5213 5214 // Add the remaining (directly-bound) handlers 5215 cur = this; 5216 if ( delegateCount < handlers.length ) { 5217 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 5218 } 5219 5220 return handlerQueue; 5221 }, 5222 5223 addProp: function( name, hook ) { 5224 Object.defineProperty( jQuery.Event.prototype, name, { 5225 enumerable: true, 5226 configurable: true, 5227 5228 get: isFunction( hook ) ? 5229 function() { 5230 if ( this.originalEvent ) { 5231 return hook( this.originalEvent ); 5232 } 5233 } : 5234 function() { 5235 if ( this.originalEvent ) { 5236 return this.originalEvent[ name ]; 5237 } 5238 }, 5239 5240 set: function( value ) { 5241 Object.defineProperty( this, name, { 5242 enumerable: true, 5243 configurable: true, 5244 writable: true, 5245 value: value 5246 } ); 5247 } 5248 } ); 5249 }, 5250 5251 fix: function( originalEvent ) { 5252 return originalEvent[ jQuery.expando ] ? 5253 originalEvent : 5254 new jQuery.Event( originalEvent ); 5255 }, 5256 5257 special: { 5258 load: { 5259 5260 // Prevent triggered image.load events from bubbling to window.load 5261 noBubble: true 5262 }, 5263 click: { 5264 5265 // Utilize native event to ensure correct state for checkable inputs 5266 setup: function( data ) { 5267 5268 // For mutual compressibility with _default, replace `this` access with a local var. 5269 // `|| data` is dead code meant only to preserve the variable through minification. 5270 var el = this || data; 5271 5272 // Claim the first handler 5273 if ( rcheckableType.test( el.type ) && 5274 el.click && nodeName( el, "input" ) ) { 5275 5276 // dataPriv.set( el, "click", ... ) 5277 leverageNative( el, "click", true ); 5278 } 5279 5280 // Return false to allow normal processing in the caller 5281 return false; 5282 }, 5283 trigger: function( data ) { 5284 5285 // For mutual compressibility with _default, replace `this` access with a local var. 5286 // `|| data` is dead code meant only to preserve the variable through minification. 5287 var el = this || data; 5288 5289 // Force setup before triggering a click 5290 if ( rcheckableType.test( el.type ) && 5291 el.click && nodeName( el, "input" ) ) { 5292 5293 leverageNative( el, "click" ); 5294 } 5295 5296 // Return non-false to allow normal event-path propagation 5297 return true; 5298 }, 5299 5300 // For cross-browser consistency, suppress native .click() on links 5301 // Also prevent it if we're currently inside a leveraged native-event stack 5302 _default: function( event ) { 5303 var target = event.target; 5304 return rcheckableType.test( target.type ) && 5305 target.click && nodeName( target, "input" ) && 5306 dataPriv.get( target, "click" ) || 5307 nodeName( target, "a" ); 5308 } 5309 }, 5310 5311 beforeunload: { 5312 postDispatch: function( event ) { 5313 5314 // Support: Firefox 20+ 5315 // Firefox doesn't alert if the returnValue field is not set. 5316 if ( event.result !== undefined && event.originalEvent ) { 5317 event.originalEvent.returnValue = event.result; 5318 } 5319 } 5320 } 5321 } 5322}; 5323 5324// Ensure the presence of an event listener that handles manually-triggered 5325// synthetic events by interrupting progress until reinvoked in response to 5326// *native* events that it fires directly, ensuring that state changes have 5327// already occurred before other listeners are invoked. 5328function leverageNative( el, type, isSetup ) { 5329 5330 // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add 5331 if ( !isSetup ) { 5332 if ( dataPriv.get( el, type ) === undefined ) { 5333 jQuery.event.add( el, type, returnTrue ); 5334 } 5335 return; 5336 } 5337 5338 // Register the controller as a special universal handler for all event namespaces 5339 dataPriv.set( el, type, false ); 5340 jQuery.event.add( el, type, { 5341 namespace: false, 5342 handler: function( event ) { 5343 var result, 5344 saved = dataPriv.get( this, type ); 5345 5346 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 5347 5348 // Interrupt processing of the outer synthetic .trigger()ed event 5349 if ( !saved ) { 5350 5351 // Store arguments for use when handling the inner native event 5352 // There will always be at least one argument (an event object), so this array 5353 // will not be confused with a leftover capture object. 5354 saved = slice.call( arguments ); 5355 dataPriv.set( this, type, saved ); 5356 5357 // Trigger the native event and capture its result 5358 this[ type ](); 5359 result = dataPriv.get( this, type ); 5360 dataPriv.set( this, type, false ); 5361 5362 if ( saved !== result ) { 5363 5364 // Cancel the outer synthetic event 5365 event.stopImmediatePropagation(); 5366 event.preventDefault(); 5367 5368 return result; 5369 } 5370 5371 // If this is an inner synthetic event for an event with a bubbling surrogate 5372 // (focus or blur), assume that the surrogate already propagated from triggering 5373 // the native event and prevent that from happening again here. 5374 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 5375 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 5376 // less bad than duplication. 5377 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 5378 event.stopPropagation(); 5379 } 5380 5381 // If this is a native event triggered above, everything is now in order 5382 // Fire an inner synthetic event with the original arguments 5383 } else if ( saved ) { 5384 5385 // ...and capture the result 5386 dataPriv.set( this, type, jQuery.event.trigger( 5387 saved[ 0 ], 5388 saved.slice( 1 ), 5389 this 5390 ) ); 5391 5392 // Abort handling of the native event by all jQuery handlers while allowing 5393 // native handlers on the same element to run. On target, this is achieved 5394 // by stopping immediate propagation just on the jQuery event. However, 5395 // the native event is re-wrapped by a jQuery one on each level of the 5396 // propagation so the only way to stop it for jQuery is to stop it for 5397 // everyone via native `stopPropagation()`. This is not a problem for 5398 // focus/blur which don't bubble, but it does also stop click on checkboxes 5399 // and radios. We accept this limitation. 5400 event.stopPropagation(); 5401 event.isImmediatePropagationStopped = returnTrue; 5402 } 5403 } 5404 } ); 5405} 5406 5407jQuery.removeEvent = function( elem, type, handle ) { 5408 5409 // This "if" is needed for plain objects 5410 if ( elem.removeEventListener ) { 5411 elem.removeEventListener( type, handle ); 5412 } 5413}; 5414 5415jQuery.Event = function( src, props ) { 5416 5417 // Allow instantiation without the 'new' keyword 5418 if ( !( this instanceof jQuery.Event ) ) { 5419 return new jQuery.Event( src, props ); 5420 } 5421 5422 // Event object 5423 if ( src && src.type ) { 5424 this.originalEvent = src; 5425 this.type = src.type; 5426 5427 // Events bubbling up the document may have been marked as prevented 5428 // by a handler lower down the tree; reflect the correct value. 5429 this.isDefaultPrevented = src.defaultPrevented || 5430 src.defaultPrevented === undefined && 5431 5432 // Support: Android <=2.3 only 5433 src.returnValue === false ? 5434 returnTrue : 5435 returnFalse; 5436 5437 // Create target properties 5438 // Support: Safari <=6 - 7 only 5439 // Target should not be a text node (trac-504, trac-13143) 5440 this.target = ( src.target && src.target.nodeType === 3 ) ? 5441 src.target.parentNode : 5442 src.target; 5443 5444 this.currentTarget = src.currentTarget; 5445 this.relatedTarget = src.relatedTarget; 5446 5447 // Event type 5448 } else { 5449 this.type = src; 5450 } 5451 5452 // Put explicitly provided properties onto the event object 5453 if ( props ) { 5454 jQuery.extend( this, props ); 5455 } 5456 5457 // Create a timestamp if incoming event doesn't have one 5458 this.timeStamp = src && src.timeStamp || Date.now(); 5459 5460 // Mark it as fixed 5461 this[ jQuery.expando ] = true; 5462}; 5463 5464// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 5465// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 5466jQuery.Event.prototype = { 5467 constructor: jQuery.Event, 5468 isDefaultPrevented: returnFalse, 5469 isPropagationStopped: returnFalse, 5470 isImmediatePropagationStopped: returnFalse, 5471 isSimulated: false, 5472 5473 preventDefault: function() { 5474 var e = this.originalEvent; 5475 5476 this.isDefaultPrevented = returnTrue; 5477 5478 if ( e && !this.isSimulated ) { 5479 e.preventDefault(); 5480 } 5481 }, 5482 stopPropagation: function() { 5483 var e = this.originalEvent; 5484 5485 this.isPropagationStopped = returnTrue; 5486 5487 if ( e && !this.isSimulated ) { 5488 e.stopPropagation(); 5489 } 5490 }, 5491 stopImmediatePropagation: function() { 5492 var e = this.originalEvent; 5493 5494 this.isImmediatePropagationStopped = returnTrue; 5495 5496 if ( e && !this.isSimulated ) { 5497 e.stopImmediatePropagation(); 5498 } 5499 5500 this.stopPropagation(); 5501 } 5502}; 5503 5504// Includes all common event props including KeyEvent and MouseEvent specific props 5505jQuery.each( { 5506 altKey: true, 5507 bubbles: true, 5508 cancelable: true, 5509 changedTouches: true, 5510 ctrlKey: true, 5511 detail: true, 5512 eventPhase: true, 5513 metaKey: true, 5514 pageX: true, 5515 pageY: true, 5516 shiftKey: true, 5517 view: true, 5518 "char": true, 5519 code: true, 5520 charCode: true, 5521 key: true, 5522 keyCode: true, 5523 button: true, 5524 buttons: true, 5525 clientX: true, 5526 clientY: true, 5527 offsetX: true, 5528 offsetY: true, 5529 pointerId: true, 5530 pointerType: true, 5531 screenX: true, 5532 screenY: true, 5533 targetTouches: true, 5534 toElement: true, 5535 touches: true, 5536 which: true 5537}, jQuery.event.addProp ); 5538 5539jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 5540 5541 function focusMappedHandler( nativeEvent ) { 5542 if ( document.documentMode ) { 5543 5544 // Support: IE 11+ 5545 // Attach a single focusin/focusout handler on the document while someone wants 5546 // focus/blur. This is because the former are synchronous in IE while the latter 5547 // are async. In other browsers, all those handlers are invoked synchronously. 5548 5549 // `handle` from private data would already wrap the event, but we need 5550 // to change the `type` here. 5551 var handle = dataPriv.get( this, "handle" ), 5552 event = jQuery.event.fix( nativeEvent ); 5553 event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; 5554 event.isSimulated = true; 5555 5556 // First, handle focusin/focusout 5557 handle( nativeEvent ); 5558 5559 // ...then, handle focus/blur 5560 // 5561 // focus/blur don't bubble while focusin/focusout do; simulate the former by only 5562 // invoking the handler at the lower level. 5563 if ( event.target === event.currentTarget ) { 5564 5565 // The setup part calls `leverageNative`, which, in turn, calls 5566 // `jQuery.event.add`, so event handle will already have been set 5567 // by this point. 5568 handle( event ); 5569 } 5570 } else { 5571 5572 // For non-IE browsers, attach a single capturing handler on the document 5573 // while someone wants focusin/focusout. 5574 jQuery.event.simulate( delegateType, nativeEvent.target, 5575 jQuery.event.fix( nativeEvent ) ); 5576 } 5577 } 5578 5579 jQuery.event.special[ type ] = { 5580 5581 // Utilize native event if possible so blur/focus sequence is correct 5582 setup: function() { 5583 5584 var attaches; 5585 5586 // Claim the first handler 5587 // dataPriv.set( this, "focus", ... ) 5588 // dataPriv.set( this, "blur", ... ) 5589 leverageNative( this, type, true ); 5590 5591 if ( document.documentMode ) { 5592 5593 // Support: IE 9 - 11+ 5594 // We use the same native handler for focusin & focus (and focusout & blur) 5595 // so we need to coordinate setup & teardown parts between those events. 5596 // Use `delegateType` as the key as `type` is already used by `leverageNative`. 5597 attaches = dataPriv.get( this, delegateType ); 5598 if ( !attaches ) { 5599 this.addEventListener( delegateType, focusMappedHandler ); 5600 } 5601 dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 ); 5602 } else { 5603 5604 // Return false to allow normal processing in the caller 5605 return false; 5606 } 5607 }, 5608 trigger: function() { 5609 5610 // Force setup before trigger 5611 leverageNative( this, type ); 5612 5613 // Return non-false to allow normal event-path propagation 5614 return true; 5615 }, 5616 5617 teardown: function() { 5618 var attaches; 5619 5620 if ( document.documentMode ) { 5621 attaches = dataPriv.get( this, delegateType ) - 1; 5622 if ( !attaches ) { 5623 this.removeEventListener( delegateType, focusMappedHandler ); 5624 dataPriv.remove( this, delegateType ); 5625 } else { 5626 dataPriv.set( this, delegateType, attaches ); 5627 } 5628 } else { 5629 5630 // Return false to indicate standard teardown should be applied 5631 return false; 5632 } 5633 }, 5634 5635 // Suppress native focus or blur if we're currently inside 5636 // a leveraged native-event stack 5637 _default: function( event ) { 5638 return dataPriv.get( event.target, type ); 5639 }, 5640 5641 delegateType: delegateType 5642 }; 5643 5644 // Support: Firefox <=44 5645 // Firefox doesn't have focus(in | out) events 5646 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 5647 // 5648 // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 5649 // focus(in | out) events fire after focus & blur events, 5650 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 5651 // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 5652 // 5653 // Support: IE 9 - 11+ 5654 // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch, 5655 // attach a single handler for both events in IE. 5656 jQuery.event.special[ delegateType ] = { 5657 setup: function() { 5658 5659 // Handle: regular nodes (via `this.ownerDocument`), window 5660 // (via `this.document`) & document (via `this`). 5661 var doc = this.ownerDocument || this.document || this, 5662 dataHolder = document.documentMode ? this : doc, 5663 attaches = dataPriv.get( dataHolder, delegateType ); 5664 5665 // Support: IE 9 - 11+ 5666 // We use the same native handler for focusin & focus (and focusout & blur) 5667 // so we need to coordinate setup & teardown parts between those events. 5668 // Use `delegateType` as the key as `type` is already used by `leverageNative`. 5669 if ( !attaches ) { 5670 if ( document.documentMode ) { 5671 this.addEventListener( delegateType, focusMappedHandler ); 5672 } else { 5673 doc.addEventListener( type, focusMappedHandler, true ); 5674 } 5675 } 5676 dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 ); 5677 }, 5678 teardown: function() { 5679 var doc = this.ownerDocument || this.document || this, 5680 dataHolder = document.documentMode ? this : doc, 5681 attaches = dataPriv.get( dataHolder, delegateType ) - 1; 5682 5683 if ( !attaches ) { 5684 if ( document.documentMode ) { 5685 this.removeEventListener( delegateType, focusMappedHandler ); 5686 } else { 5687 doc.removeEventListener( type, focusMappedHandler, true ); 5688 } 5689 dataPriv.remove( dataHolder, delegateType ); 5690 } else { 5691 dataPriv.set( dataHolder, delegateType, attaches ); 5692 } 5693 } 5694 }; 5695} ); 5696 5697// Create mouseenter/leave events using mouseover/out and event-time checks 5698// so that event delegation works in jQuery. 5699// Do the same for pointerenter/pointerleave and pointerover/pointerout 5700// 5701// Support: Safari 7 only 5702// Safari sends mouseenter too often; see: 5703// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 5704// for the description of the bug (it existed in older Chrome versions as well). 5705jQuery.each( { 5706 mouseenter: "mouseover", 5707 mouseleave: "mouseout", 5708 pointerenter: "pointerover", 5709 pointerleave: "pointerout" 5710}, function( orig, fix ) { 5711 jQuery.event.special[ orig ] = { 5712 delegateType: fix, 5713 bindType: fix, 5714 5715 handle: function( event ) { 5716 var ret, 5717 target = this, 5718 related = event.relatedTarget, 5719 handleObj = event.handleObj; 5720 5721 // For mouseenter/leave call the handler if related is outside the target. 5722 // NB: No relatedTarget if the mouse left/entered the browser window 5723 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 5724 event.type = handleObj.origType; 5725 ret = handleObj.handler.apply( this, arguments ); 5726 event.type = fix; 5727 } 5728 return ret; 5729 } 5730 }; 5731} ); 5732 5733jQuery.fn.extend( { 5734 5735 on: function( types, selector, data, fn ) { 5736 return on( this, types, selector, data, fn ); 5737 }, 5738 one: function( types, selector, data, fn ) { 5739 return on( this, types, selector, data, fn, 1 ); 5740 }, 5741 off: function( types, selector, fn ) { 5742 var handleObj, type; 5743 if ( types && types.preventDefault && types.handleObj ) { 5744 5745 // ( event ) dispatched jQuery.Event 5746 handleObj = types.handleObj; 5747 jQuery( types.delegateTarget ).off( 5748 handleObj.namespace ? 5749 handleObj.origType + "." + handleObj.namespace : 5750 handleObj.origType, 5751 handleObj.selector, 5752 handleObj.handler 5753 ); 5754 return this; 5755 } 5756 if ( typeof types === "object" ) { 5757 5758 // ( types-object [, selector] ) 5759 for ( type in types ) { 5760 this.off( type, selector, types[ type ] ); 5761 } 5762 return this; 5763 } 5764 if ( selector === false || typeof selector === "function" ) { 5765 5766 // ( types [, fn] ) 5767 fn = selector; 5768 selector = undefined; 5769 } 5770 if ( fn === false ) { 5771 fn = returnFalse; 5772 } 5773 return this.each( function() { 5774 jQuery.event.remove( this, types, fn, selector ); 5775 } ); 5776 } 5777} ); 5778 5779 5780var 5781 5782 // Support: IE <=10 - 11, Edge 12 - 13 only 5783 // In IE/Edge using regex groups here causes severe slowdowns. 5784 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 5785 rnoInnerhtml = /<script|<style|<link/i, 5786 5787 // checked="checked" or checked 5788 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5789 5790 rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g; 5791 5792// Prefer a tbody over its parent table for containing new rows 5793function manipulationTarget( elem, content ) { 5794 if ( nodeName( elem, "table" ) && 5795 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 5796 5797 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 5798 } 5799 5800 return elem; 5801} 5802 5803// Replace/restore the type attribute of script elements for safe DOM manipulation 5804function disableScript( elem ) { 5805 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 5806 return elem; 5807} 5808function restoreScript( elem ) { 5809 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 5810 elem.type = elem.type.slice( 5 ); 5811 } else { 5812 elem.removeAttribute( "type" ); 5813 } 5814 5815 return elem; 5816} 5817 5818function cloneCopyEvent( src, dest ) { 5819 var i, l, type, pdataOld, udataOld, udataCur, events; 5820
vendor: 6,382 bytes, lines 5821-6050
5821 if ( dest.nodeType !== 1 ) { 5822 return; 5823 } 5824 5825 // 1. Copy private data: events, handlers, etc. 5826 if ( dataPriv.hasData( src ) ) { 5827 pdataOld = dataPriv.get( src ); 5828 events = pdataOld.events; 5829 5830 if ( events ) { 5831 dataPriv.remove( dest, "handle events" ); 5832 5833 for ( type in events ) { 5834 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 5835 jQuery.event.add( dest, type, events[ type ][ i ] ); 5836 } 5837 } 5838 } 5839 } 5840 5841 // 2. Copy user data 5842 if ( dataUser.hasData( src ) ) { 5843 udataOld = dataUser.access( src ); 5844 udataCur = jQuery.extend( {}, udataOld ); 5845 5846 dataUser.set( dest, udataCur ); 5847 } 5848} 5849 5850// Fix IE bugs, see support tests 5851function fixInput( src, dest ) { 5852 var nodeName = dest.nodeName.toLowerCase(); 5853 5854 // Fails to persist the checked state of a cloned checkbox or radio button. 5855 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 5856 dest.checked = src.checked; 5857 5858 // Fails to return the selected option to the default selected state when cloning options 5859 } else if ( nodeName === "input" || nodeName === "textarea" ) { 5860 dest.defaultValue = src.defaultValue; 5861 } 5862} 5863 5864function domManip( collection, args, callback, ignored ) { 5865 5866 // Flatten any nested arrays 5867 args = flat( args ); 5868 5869 var fragment, first, scripts, hasScripts, node, doc, 5870 i = 0, 5871 l = collection.length, 5872 iNoClone = l - 1, 5873 value = args[ 0 ], 5874 valueIsFunction = isFunction( value ); 5875 5876 // We can't cloneNode fragments that contain checked, in WebKit 5877 if ( valueIsFunction || 5878 ( l > 1 && typeof value === "string" && 5879 !support.checkClone && rchecked.test( value ) ) ) { 5880 return collection.each( function( index ) { 5881 var self = collection.eq( index ); 5882 if ( valueIsFunction ) { 5883 args[ 0 ] = value.call( this, index, self.html() ); 5884 } 5885 domManip( self, args, callback, ignored ); 5886 } ); 5887 } 5888 5889 if ( l ) { 5890 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 5891 first = fragment.firstChild; 5892 5893 if ( fragment.childNodes.length === 1 ) { 5894 fragment = first; 5895 } 5896 5897 // Require either new content or an interest in ignored elements to invoke the callback 5898 if ( first || ignored ) { 5899 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 5900 hasScripts = scripts.length; 5901 5902 // Use the original fragment for the last item 5903 // instead of the first because it can end up 5904 // being emptied incorrectly in certain situations (trac-8070). 5905 for ( ; i < l; i++ ) { 5906 node = fragment; 5907 5908 if ( i !== iNoClone ) { 5909 node = jQuery.clone( node, true, true ); 5910 5911 // Keep references to cloned scripts for later restoration 5912 if ( hasScripts ) { 5913 5914 // Support: Android <=4.0 only, PhantomJS 1 only 5915 // push.apply(_, arraylike) throws on ancient WebKit 5916 jQuery.merge( scripts, getAll( node, "script" ) ); 5917 } 5918 } 5919 5920 callback.call( collection[ i ], node, i ); 5921 } 5922 5923 if ( hasScripts ) { 5924 doc = scripts[ scripts.length - 1 ].ownerDocument; 5925 5926 // Re-enable scripts 5927 jQuery.map( scripts, restoreScript ); 5928 5929 // Evaluate executable scripts on first document insertion 5930 for ( i = 0; i < hasScripts; i++ ) { 5931 node = scripts[ i ]; 5932 if ( rscriptType.test( node.type || "" ) && 5933 !dataPriv.access( node, "globalEval" ) && 5934 jQuery.contains( doc, node ) ) { 5935 5936 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 5937 5938 // Optional AJAX dependency, but won't run scripts if not present 5939 if ( jQuery._evalUrl && !node.noModule ) { 5940 jQuery._evalUrl( node.src, { 5941 nonce: node.nonce || node.getAttribute( "nonce" ) 5942 }, doc ); 5943 } 5944 } else { 5945 5946 // Unwrap a CDATA section containing script contents. This shouldn't be 5947 // needed as in XML documents they're already not visible when 5948 // inspecting element contents and in HTML documents they have no 5949 // meaning but we're preserving that logic for backwards compatibility. 5950 // This will be removed completely in 4.0. See gh-4904. 5951 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 5952 } 5953 } 5954 } 5955 } 5956 } 5957 } 5958 5959 return collection; 5960} 5961 5962function remove( elem, selector, keepData ) { 5963 var node, 5964 nodes = selector ? jQuery.filter( selector, elem ) : elem, 5965 i = 0; 5966 5967 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 5968 if ( !keepData && node.nodeType === 1 ) { 5969 jQuery.cleanData( getAll( node ) ); 5970 } 5971 5972 if ( node.parentNode ) { 5973 if ( keepData && isAttached( node ) ) { 5974 setGlobalEval( getAll( node, "script" ) ); 5975 } 5976 node.parentNode.removeChild( node ); 5977 } 5978 } 5979 5980 return elem; 5981} 5982 5983jQuery.extend( { 5984 htmlPrefilter: function( html ) { 5985 return html; 5986 }, 5987 5988 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 5989 var i, l, srcElements, destElements, 5990 clone = elem.cloneNode( true ), 5991 inPage = isAttached( elem ); 5992 5993 // Fix IE cloning issues 5994 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 5995 !jQuery.isXMLDoc( elem ) ) { 5996 5997 // We eschew jQuery#find here for performance reasons: 5998 // https://jsperf.com/getall-vs-sizzle/2 5999 destElements = getAll( clone ); 6000 srcElements = getAll( elem ); 6001 6002 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6003 fixInput( srcElements[ i ], destElements[ i ] ); 6004 } 6005 } 6006 6007 // Copy the events from the original to the clone 6008 if ( dataAndEvents ) { 6009 if ( deepDataAndEvents ) { 6010 srcElements = srcElements || getAll( elem ); 6011 destElements = destElements || getAll( clone ); 6012 6013 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6014 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 6015 } 6016 } else { 6017 cloneCopyEvent( elem, clone ); 6018 } 6019 } 6020 6021 // Preserve script evaluation history 6022 destElements = getAll( clone, "script" ); 6023 if ( destElements.length > 0 ) { 6024 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 6025 } 6026 6027 // Return the cloned set 6028 return clone; 6029 }, 6030 6031 cleanData: function( elems ) { 6032 var data, elem, type, 6033 special = jQuery.event.special, 6034 i = 0; 6035 6036 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 6037 if ( acceptData( elem ) ) { 6038 if ( ( data = elem[ dataPriv.expando ] ) ) { 6039 if ( data.events ) { 6040 for ( type in data.events ) { 6041 if ( special[ type ] ) { 6042 jQuery.event.remove( elem, type ); 6043 6044 // This is a shortcut to avoid jQuery.event.remove's overhead 6045 } else { 6046 jQuery.removeEvent( elem, type, data.handle ); 6047 } 6048 } 6049 } 6050
vendor: 1,119 bytes, lines 6051-6095
6051 // Support: Chrome <=35 - 45+ 6052 // Assign undefined instead of using delete, see Data#remove 6053 elem[ dataPriv.expando ] = undefined; 6054 } 6055 if ( elem[ dataUser.expando ] ) { 6056 6057 // Support: Chrome <=35 - 45+ 6058 // Assign undefined instead of using delete, see Data#remove 6059 elem[ dataUser.expando ] = undefined; 6060 } 6061 } 6062 } 6063 } 6064} ); 6065 6066jQuery.fn.extend( { 6067 detach: function( selector ) { 6068 return remove( this, selector, true ); 6069 }, 6070 6071 remove: function( selector ) { 6072 return remove( this, selector ); 6073 }, 6074 6075 text: function( value ) { 6076 return access( this, function( value ) { 6077 return value === undefined ? 6078 jQuery.text( this ) : 6079 this.empty().each( function() { 6080 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6081 this.textContent = value; 6082 } 6083 } ); 6084 }, null, value, arguments.length ); 6085 }, 6086 6087 append: function() { 6088 return domManip( this, arguments, function( elem ) { 6089 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6090 var target = manipulationTarget( this, elem ); 6091 target.appendChild( elem ); 6092 } 6093 } ); 6094 }, 6095
vendor: 4,514 bytes, lines 6096-6287
6096 prepend: function() { 6097 return domManip( this, arguments, function( elem ) { 6098 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6099 var target = manipulationTarget( this, elem ); 6100 target.insertBefore( elem, target.firstChild ); 6101 } 6102 } ); 6103 }, 6104 6105 before: function() { 6106 return domManip( this, arguments, function( elem ) { 6107 if ( this.parentNode ) { 6108 this.parentNode.insertBefore( elem, this ); 6109 } 6110 } ); 6111 }, 6112 6113 after: function() { 6114 return domManip( this, arguments, function( elem ) { 6115 if ( this.parentNode ) { 6116 this.parentNode.insertBefore( elem, this.nextSibling ); 6117 } 6118 } ); 6119 }, 6120 6121 empty: function() { 6122 var elem, 6123 i = 0; 6124 6125 for ( ; ( elem = this[ i ] ) != null; i++ ) { 6126 if ( elem.nodeType === 1 ) { 6127 6128 // Prevent memory leaks 6129 jQuery.cleanData( getAll( elem, false ) ); 6130 6131 // Remove any remaining nodes 6132 elem.textContent = ""; 6133 } 6134 } 6135 6136 return this; 6137 }, 6138 6139 clone: function( dataAndEvents, deepDataAndEvents ) { 6140 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 6141 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 6142 6143 return this.map( function() { 6144 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 6145 } ); 6146 }, 6147 6148 html: function( value ) { 6149 return access( this, function( value ) { 6150 var elem = this[ 0 ] || {}, 6151 i = 0, 6152 l = this.length; 6153 6154 if ( value === undefined && elem.nodeType === 1 ) { 6155 return elem.innerHTML; 6156 } 6157 6158 // See if we can take a shortcut and just use innerHTML 6159 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 6160 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 6161 6162 value = jQuery.htmlPrefilter( value ); 6163 6164 try { 6165 for ( ; i < l; i++ ) { 6166 elem = this[ i ] || {}; 6167 6168 // Remove element nodes and prevent memory leaks 6169 if ( elem.nodeType === 1 ) { 6170 jQuery.cleanData( getAll( elem, false ) ); 6171 elem.innerHTML = value; 6172 } 6173 } 6174 6175 elem = 0; 6176 6177 // If using innerHTML throws an exception, use the fallback method 6178 } catch ( e ) {} 6179 } 6180 6181 if ( elem ) { 6182 this.empty().append( value ); 6183 } 6184 }, null, value, arguments.length ); 6185 }, 6186 6187 replaceWith: function() { 6188 var ignored = []; 6189 6190 // Make the changes, replacing each non-ignored context element with the new content 6191 return domManip( this, arguments, function( elem ) { 6192 var parent = this.parentNode; 6193 6194 if ( jQuery.inArray( this, ignored ) < 0 ) { 6195 jQuery.cleanData( getAll( this ) ); 6196 if ( parent ) { 6197 parent.replaceChild( elem, this ); 6198 } 6199 } 6200 6201 // Force callback invocation 6202 }, ignored ); 6203 } 6204} ); 6205 6206jQuery.each( { 6207 appendTo: "append", 6208 prependTo: "prepend", 6209 insertBefore: "before", 6210 insertAfter: "after", 6211 replaceAll: "replaceWith" 6212}, function( name, original ) { 6213 jQuery.fn[ name ] = function( selector ) { 6214 var elems, 6215 ret = [], 6216 insert = jQuery( selector ), 6217 last = insert.length - 1, 6218 i = 0; 6219 6220 for ( ; i <= last; i++ ) { 6221 elems = i === last ? this : this.clone( true ); 6222 jQuery( insert[ i ] )[ original ]( elems ); 6223 6224 // Support: Android <=4.0 only, PhantomJS 1 only 6225 // .get() because push.apply(_, arraylike) throws on ancient WebKit 6226 push.apply( ret, elems.get() ); 6227 } 6228 6229 return this.pushStack( ret ); 6230 }; 6231} ); 6232var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 6233 6234var rcustomProp = /^--/; 6235 6236 6237var getStyles = function( elem ) { 6238 6239 // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) 6240 // IE throws on elements created in popups 6241 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 6242 var view = elem.ownerDocument.defaultView; 6243 6244 if ( !view || !view.opener ) { 6245 view = window; 6246 } 6247 6248 return view.getComputedStyle( elem ); 6249 }; 6250 6251var swap = function( elem, options, callback ) { 6252 var ret, name, 6253 old = {}; 6254 6255 // Remember the old values, and insert the new ones 6256 for ( name in options ) { 6257 old[ name ] = elem.style[ name ]; 6258 elem.style[ name ] = options[ name ]; 6259 } 6260 6261 ret = callback.call( elem ); 6262 6263 // Revert the old values 6264 for ( name in options ) { 6265 elem.style[ name ] = old[ name ]; 6266 } 6267 6268 return ret; 6269}; 6270 6271 6272var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 6273 6274 6275 6276( function() { 6277 6278 // Executing both pixelPosition & boxSizingReliable tests require only one layout 6279 // so they're executed at the same time to save the second computation. 6280 function computeStyleTests() { 6281 6282 // This is a singleton, we need to execute it only once 6283 if ( !div ) { 6284 return; 6285 } 6286 6287 container.style.cssText = "position:absolute;
vendor: 4,156 bytes, lines 6287-6406
6287left:-11111px;width:60px;" + 6288 "margin-top:1px;padding:0;border:0"; 6289 div.style.cssText = 6290 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 6291 "margin:auto;border:1px;padding:1px;" + 6292 "width:60%;top:1%"; 6293 documentElement.appendChild( container ).appendChild( div ); 6294 6295 var divStyle = window.getComputedStyle( div ); 6296 pixelPositionVal = divStyle.top !== "1%"; 6297 6298 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 6299 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 6300 6301 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 6302 // Some styles come back with percentage values, even though they shouldn't 6303 div.style.right = "60%"; 6304 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 6305 6306 // Support: IE 9 - 11 only 6307 // Detect misreporting of content dimensions for box-sizing:border-box elements 6308 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 6309 6310 // Support: IE 9 only 6311 // Detect overflow:scroll screwiness (gh-3699) 6312 // Support: Chrome <=64 6313 // Don't get tricked when zoom affects offsetWidth (gh-4029) 6314 div.style.position = "absolute"; 6315 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 6316 6317 documentElement.removeChild( container ); 6318 6319 // Nullify the div so it wouldn't be stored in the memory and 6320 // it will also be a sign that checks already performed 6321 div = null; 6322 } 6323 6324 function roundPixelMeasures( measure ) { 6325 return Math.round( parseFloat( measure ) ); 6326 } 6327 6328 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 6329 reliableTrDimensionsVal, reliableMarginLeftVal, 6330 container = document.createElement( "div" ), 6331 div = document.createElement( "div" ); 6332 6333 // Finish early in limited (non-browser) environments 6334 if ( !div.style ) { 6335 return; 6336 } 6337 6338 // Support: IE <=9 - 11 only 6339 // Style of cloned element affects source element cloned (trac-8908) 6340 div.style.backgroundClip = "content-box"; 6341 div.cloneNode( true ).style.backgroundClip = ""; 6342 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 6343 6344 jQuery.extend( support, { 6345 boxSizingReliable: function() { 6346 computeStyleTests(); 6347 return boxSizingReliableVal; 6348 }, 6349 pixelBoxStyles: function() { 6350 computeStyleTests(); 6351 return pixelBoxStylesVal; 6352 }, 6353 pixelPosition: function() { 6354 computeStyleTests(); 6355 return pixelPositionVal; 6356 }, 6357 reliableMarginLeft: function() { 6358 computeStyleTests(); 6359 return reliableMarginLeftVal; 6360 }, 6361 scrollboxSize: function() { 6362 computeStyleTests(); 6363 return scrollboxSizeVal; 6364 }, 6365 6366 // Support: IE 9 - 11+, Edge 15 - 18+ 6367 // IE/Edge misreport `getComputedStyle` of table rows with width/height 6368 // set in CSS while `offset*` properties report correct values. 6369 // Behavior in IE 9 is more subtle than in newer versions & it passes 6370 // some versions of this test; make sure not to make it pass there! 6371 // 6372 // Support: Firefox 70+ 6373 // Only Firefox includes border widths 6374 // in computed dimensions. (gh-4529) 6375 reliableTrDimensions: function() { 6376 var table, tr, trChild, trStyle; 6377 if ( reliableTrDimensionsVal == null ) { 6378 table = document.createElement( "table" ); 6379 tr = document.createElement( "tr" ); 6380 trChild = document.createElement( "div" ); 6381 6382 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; 6383 tr.style.cssText = "box-sizing:content-box;border:1px solid"; 6384 6385 // Support: Chrome 86+ 6386 // Height set through cssText does not get applied. 6387 // Computed height then comes back as 0. 6388 tr.style.height = "1px"; 6389 trChild.style.height = "9px"; 6390 6391 // Support: Android 8 Chrome 86+ 6392 // In our bodyBackground.html iframe, 6393 // display for all div elements is set to "inline", 6394 // which causes a problem only in Android 8 Chrome 86. 6395 // Ensuring the div is `display: block` 6396 // gets around this issue. 6397 trChild.style.display = "block"; 6398 6399 documentElement 6400 .appendChild( table ) 6401 .appendChild( tr ) 6402 .appendChild( trChild ); 6403 6404 trStyle = window.getComputedStyle( tr ); 6405 reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + 6406 parseInt( trStyle.borderTopWidth, 10 ) +
vendor: 12,879 bytes, lines 6407-6833
6407 parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; 6408 6409 documentElement.removeChild( table ); 6410 } 6411 return reliableTrDimensionsVal; 6412 } 6413 } ); 6414} )(); 6415 6416 6417function curCSS( elem, name, computed ) { 6418 var width, minWidth, maxWidth, ret, 6419 isCustomProp = rcustomProp.test( name ), 6420 6421 // Support: Firefox 51+ 6422 // Retrieving style before computed somehow 6423 // fixes an issue with getting wrong values 6424 // on detached elements 6425 style = elem.style; 6426 6427 computed = computed || getStyles( elem ); 6428 6429 // getPropertyValue is needed for: 6430 // .css('filter') (IE 9 only, trac-12537) 6431 // .css('--customProperty) (gh-3144) 6432 if ( computed ) { 6433 6434 // Support: IE <=9 - 11+ 6435 // IE only supports `"float"` in `getPropertyValue`; in computed styles 6436 // it's only available as `"cssFloat"`. We no longer modify properties 6437 // sent to `.css()` apart from camelCasing, so we need to check both. 6438 // Normally, this would create difference in behavior: if 6439 // `getPropertyValue` returns an empty string, the value returned 6440 // by `.css()` would be `undefined`. This is usually the case for 6441 // disconnected elements. However, in IE even disconnected elements 6442 // with no styles return `"none"` for `getPropertyValue( "float" )` 6443 ret = computed.getPropertyValue( name ) || computed[ name ]; 6444 6445 if ( isCustomProp && ret ) { 6446 6447 // Support: Firefox 105+, Chrome <=105+ 6448 // Spec requires trimming whitespace for custom properties (gh-4926). 6449 // Firefox only trims leading whitespace. Chrome just collapses 6450 // both leading & trailing whitespace to a single space. 6451 // 6452 // Fall back to `undefined` if empty string returned. 6453 // This collapses a missing definition with property defined 6454 // and set to an empty string but there's no standard API 6455 // allowing us to differentiate them without a performance penalty 6456 // and returning `undefined` aligns with older jQuery. 6457 // 6458 // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED 6459 // as whitespace while CSS does not, but this is not a problem 6460 // because CSS preprocessing replaces them with U+000A LINE FEED 6461 // (which *is* CSS whitespace) 6462 // https://www.w3.org/TR/css-syntax-3/#input-preprocessing 6463 ret = ret.replace( rtrimCSS, "$1" ) || undefined; 6464 } 6465 6466 if ( ret === "" && !isAttached( elem ) ) { 6467 ret = jQuery.style( elem, name ); 6468 } 6469 6470 // A tribute to the "awesome hack by Dean Edwards" 6471 // Android Browser returns percentage for some values, 6472 // but width seems to be reliably pixels. 6473 // This is against the CSSOM draft spec: 6474 // https://drafts.csswg.org/cssom/#resolved-values 6475 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 6476 6477 // Remember the original values 6478 width = style.width; 6479 minWidth = style.minWidth; 6480 maxWidth = style.maxWidth; 6481 6482 // Put in the new values to get a computed value out 6483 style.minWidth = style.maxWidth = style.width = ret; 6484 ret = computed.width; 6485 6486 // Revert the changed values 6487 style.width = width; 6488 style.minWidth = minWidth; 6489 style.maxWidth = maxWidth; 6490 } 6491 } 6492 6493 return ret !== undefined ? 6494 6495 // Support: IE <=9 - 11 only 6496 // IE returns zIndex value as an integer. 6497 ret + "" : 6498 ret; 6499} 6500 6501 6502function addGetHookIf( conditionFn, hookFn ) { 6503 6504 // Define the hook, we'll check on the first run if it's really needed. 6505 return { 6506 get: function() { 6507 if ( conditionFn() ) { 6508 6509 // Hook not needed (or it's not possible to use it due 6510 // to missing dependency), remove it. 6511 delete this.get; 6512 return; 6513 } 6514 6515 // Hook needed; redefine it so that the support test is not executed again. 6516 return ( this.get = hookFn ).apply( this, arguments ); 6517 } 6518 }; 6519} 6520 6521 6522var cssPrefixes = [ "Webkit", "Moz", "ms" ], 6523 emptyStyle = document.createElement( "div" ).style, 6524 vendorProps = {}; 6525 6526// Return a vendor-prefixed property or undefined 6527function vendorPropName( name ) { 6528 6529 // Check for vendor prefixed names 6530 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 6531 i = cssPrefixes.length; 6532 6533 while ( i-- ) { 6534 name = cssPrefixes[ i ] + capName; 6535 if ( name in emptyStyle ) { 6536 return name; 6537 } 6538 } 6539} 6540 6541// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 6542function finalPropName( name ) { 6543 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 6544 6545 if ( final ) { 6546 return final; 6547 } 6548 if ( name in emptyStyle ) { 6549 return name; 6550 } 6551 return vendorProps[ name ] = vendorPropName( name ) || name; 6552} 6553 6554 6555var 6556 6557 // Swappable if display is none or starts with table 6558 // except "table", "table-cell", or "table-caption" 6559 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 6560 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 6561 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6562 cssNormalTransform = { 6563 letterSpacing: "0", 6564 fontWeight: "400" 6565 }; 6566 6567function setPositiveNumber( _elem, value, subtract ) { 6568 6569 // Any relative (+/-) values have already been 6570 // normalized at this point 6571 var matches = rcssNum.exec( value ); 6572 return matches ? 6573 6574 // Guard against undefined "subtract", e.g., when used as in cssHooks 6575 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 6576 value; 6577} 6578 6579function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 6580 var i = dimension === "width" ? 1 : 0, 6581 extra = 0, 6582 delta = 0, 6583 marginDelta = 0; 6584 6585 // Adjustment may not be necessary 6586 if ( box === ( isBorderBox ? "border" : "content" ) ) { 6587 return 0; 6588 } 6589 6590 for ( ; i < 4; i += 2 ) { 6591 6592 // Both box models exclude margin 6593 // Count margin delta separately to only add it after scroll gutter adjustment. 6594 // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). 6595 if ( box === "margin" ) { 6596 marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 6597 } 6598 6599 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 6600 if ( !isBorderBox ) { 6601 6602 // Add padding 6603 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6604 6605 // For "border" or "margin", add border 6606 if ( box !== "padding" ) { 6607 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6608 6609 // But still keep track of it otherwise 6610 } else { 6611 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6612 } 6613 6614 // If we get here with a border-box (content + padding + border), we're seeking "content" or 6615 // "padding" or "margin" 6616 } else { 6617 6618 // For "content", subtract padding 6619 if ( box === "content" ) { 6620 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6621 } 6622 6623 // For "content" or "padding", subtract border 6624 if ( box !== "margin" ) { 6625 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6626 } 6627 } 6628 } 6629 6630 // Account for positive content-box scroll gutter when requested by providing computedVal 6631 if ( !isBorderBox && computedVal >= 0 ) { 6632 6633 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 6634 // Assuming integer scroll gutter, subtract the rest and round down 6635 delta += Math.max( 0, Math.ceil( 6636 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 6637 computedVal - 6638 delta - 6639 extra - 6640 0.5 6641 6642 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 6643 // Use an explicit zero to avoid NaN (gh-3964) 6644 ) ) || 0; 6645 } 6646 6647 return delta + marginDelta; 6648} 6649 6650function getWidthOrHeight( elem, dimension, extra ) { 6651 6652 // Start with computed style 6653 var styles = getStyles( elem ), 6654 6655 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 6656 // Fake content-box until we know it's needed to know the true value. 6657 boxSizingNeeded = !support.boxSizingReliable() || extra, 6658 isBorderBox = boxSizingNeeded && 6659 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6660 valueIsBorderBox = isBorderBox, 6661 6662 val = curCSS( elem, dimension, styles ), 6663 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 6664 6665 // Support: Firefox <=54 6666 // Return a confounding non-pixel value or feign ignorance, as appropriate. 6667 if ( rnumnonpx.test( val ) ) { 6668 if ( !extra ) { 6669 return val; 6670 } 6671 val = "auto"; 6672 } 6673 6674 6675 // Support: IE 9 - 11 only 6676 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 6677 // In those cases, the computed value can be trusted to be border-box. 6678 if ( ( !support.boxSizingReliable() && isBorderBox || 6679 6680 // Support: IE 10 - 11+, Edge 15 - 18+ 6681 // IE/Edge misreport `getComputedStyle` of table rows with width/height 6682 // set in CSS while `offset*` properties report correct values. 6683 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 6684 !support.reliableTrDimensions() && nodeName( elem, "tr" ) || 6685 6686 // Fall back to offsetWidth/offsetHeight when value is "auto" 6687 // This happens for inline elements with no explicit setting (gh-3571) 6688 val === "auto" || 6689 6690 // Support: Android <=4.1 - 4.3 only 6691 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 6692 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 6693 6694 // Make sure the element is visible & connected 6695 elem.getClientRects().length ) { 6696 6697 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 6698 6699 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 6700 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 6701 // retrieved value as a content box dimension. 6702 valueIsBorderBox = offsetProp in elem; 6703 if ( valueIsBorderBox ) { 6704 val = elem[ offsetProp ]; 6705 } 6706 } 6707 6708 // Normalize "" and auto 6709 val = parseFloat( val ) || 0; 6710 6711 // Adjust for the element's box model 6712 return ( val + 6713 boxModelAdjustment( 6714 elem, 6715 dimension, 6716 extra || ( isBorderBox ? "border" : "content" ), 6717 valueIsBorderBox, 6718 styles, 6719 6720 // Provide the current computed size to request scroll gutter calculation (gh-3589) 6721 val 6722 ) 6723 ) + "px"; 6724} 6725 6726jQuery.extend( { 6727 6728 // Add in style property hooks for overriding the default 6729 // behavior of getting and setting a style property 6730 cssHooks: { 6731 opacity: { 6732 get: function( elem, computed ) { 6733 if ( computed ) { 6734 6735 // We should always get a number back from opacity 6736 var ret = curCSS( elem, "opacity" ); 6737 return ret === "" ? "1" : ret; 6738 } 6739 } 6740 } 6741 }, 6742 6743 // Don't automatically add "px" to these possibly-unitless properties 6744 cssNumber: { 6745 animationIterationCount: true, 6746 aspectRatio: true, 6747 borderImageSlice: true, 6748 columnCount: true, 6749 flexGrow: true, 6750 flexShrink: true, 6751 fontWeight: true, 6752 gridArea: true, 6753 gridColumn: true, 6754 gridColumnEnd: true, 6755 gridColumnStart: true, 6756 gridRow: true, 6757 gridRowEnd: true, 6758 gridRowStart: true, 6759 lineHeight: true, 6760 opacity: true, 6761 order: true, 6762 orphans: true, 6763 scale: true, 6764 widows: true, 6765 zIndex: true, 6766 zoom: true, 6767 6768 // SVG-related 6769 fillOpacity: true, 6770 floodOpacity: true, 6771 stopOpacity: true, 6772 strokeMiterlimit: true, 6773 strokeOpacity: true 6774 }, 6775 6776 // Add in properties whose names you wish to fix before 6777 // setting or getting the value 6778 cssProps: {}, 6779 6780 // Get and set the style property on a DOM Node 6781 style: function( elem, name, value, extra ) { 6782 6783 // Don't set styles on text and comment nodes 6784 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6785 return; 6786 } 6787 6788 // Make sure that we're working with the right name 6789 var ret, type, hooks, 6790 origName = camelCase( name ), 6791 isCustomProp = rcustomProp.test( name ), 6792 style = elem.style; 6793 6794 // Make sure that we're working with the right name. We don't 6795 // want to query the value if it is a CSS custom property 6796 // since they are user-defined. 6797 if ( !isCustomProp ) { 6798 name = finalPropName( origName ); 6799 } 6800 6801 // Gets hook for the prefixed version, then unprefixed version 6802 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6803 6804 // Check if we're setting a value 6805 if ( value !== undefined ) { 6806 type = typeof value; 6807 6808 // Convert "+=" or "-=" to relative numbers (trac-7345) 6809 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 6810 value = adjustCSS( elem, name, ret ); 6811 6812 // Fixes bug trac-9237 6813 type = "number"; 6814 } 6815 6816 // Make sure that null and NaN values aren't set (trac-7116) 6817 if ( value == null || value !== value ) { 6818 return; 6819 } 6820 6821 // If a number was passed in, add the unit (except for certain CSS properties) 6822 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 6823 // "px" to a few hardcoded values. 6824 if ( type === "number" && !isCustomProp ) { 6825 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 6826 } 6827 6828 // background-* props affect original clone's values 6829 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 6830 style[ name ] = "inherit"; 6831 } 6832 6833 // If a hook was provided, use that value, otherwise just set the specified value
vendor: 16,052 bytes, lines 6834-7438
6834 if ( !hooks || !( "set" in hooks ) || 6835 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 6836 6837 if ( isCustomProp ) { 6838 style.setProperty( name, value ); 6839 } else { 6840 style[ name ] = value; 6841 } 6842 } 6843 6844 } else { 6845 6846 // If a hook was provided get the non-computed value from there 6847 if ( hooks && "get" in hooks && 6848 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 6849 6850 return ret; 6851 } 6852 6853 // Otherwise just get the value from the style object 6854 return style[ name ]; 6855 } 6856 }, 6857 6858 css: function( elem, name, extra, styles ) { 6859 var val, num, hooks, 6860 origName = camelCase( name ), 6861 isCustomProp = rcustomProp.test( name ); 6862 6863 // Make sure that we're working with the right name. We don't 6864 // want to modify the value if it is a CSS custom property 6865 // since they are user-defined. 6866 if ( !isCustomProp ) { 6867 name = finalPropName( origName ); 6868 } 6869 6870 // Try prefixed name followed by the unprefixed name 6871 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6872 6873 // If a hook was provided get the computed value from there 6874 if ( hooks && "get" in hooks ) { 6875 val = hooks.get( elem, true, extra ); 6876 } 6877 6878 // Otherwise, if a way to get the computed value exists, use that 6879 if ( val === undefined ) { 6880 val = curCSS( elem, name, styles ); 6881 } 6882 6883 // Convert "normal" to computed value 6884 if ( val === "normal" && name in cssNormalTransform ) { 6885 val = cssNormalTransform[ name ]; 6886 } 6887 6888 // Make numeric if forced or a qualifier was provided and val looks numeric 6889 if ( extra === "" || extra ) { 6890 num = parseFloat( val ); 6891 return extra === true || isFinite( num ) ? num || 0 : val; 6892 } 6893 6894 return val; 6895 } 6896} ); 6897 6898jQuery.each( [ "height", "width" ], function( _i, dimension ) { 6899 jQuery.cssHooks[ dimension ] = { 6900 get: function( elem, computed, extra ) { 6901 if ( computed ) { 6902 6903 // Certain elements can have dimension info if we invisibly show them 6904 // but it must have a current display style that would benefit 6905 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 6906 6907 // Support: Safari 8+ 6908 // Table columns in Safari have non-zero offsetWidth & zero 6909 // getBoundingClientRect().width unless display is changed. 6910 // Support: IE <=11 only 6911 // Running getBoundingClientRect on a disconnected node 6912 // in IE throws an error. 6913 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 6914 swap( elem, cssShow, function() { 6915 return getWidthOrHeight( elem, dimension, extra ); 6916 } ) : 6917 getWidthOrHeight( elem, dimension, extra ); 6918 } 6919 }, 6920 6921 set: function( elem, value, extra ) { 6922 var matches, 6923 styles = getStyles( elem ), 6924 6925 // Only read styles.position if the test has a chance to fail 6926 // to avoid forcing a reflow. 6927 scrollboxSizeBuggy = !support.scrollboxSize() && 6928 styles.position === "absolute", 6929 6930 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 6931 boxSizingNeeded = scrollboxSizeBuggy || extra, 6932 isBorderBox = boxSizingNeeded && 6933 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6934 subtract = extra ? 6935 boxModelAdjustment( 6936 elem, 6937 dimension, 6938 extra, 6939 isBorderBox, 6940 styles 6941 ) : 6942 0; 6943 6944 // Account for unreliable border-box dimensions by comparing offset* to computed and 6945 // faking a content-box to get border and padding (gh-3699) 6946 if ( isBorderBox && scrollboxSizeBuggy ) { 6947 subtract -= Math.ceil( 6948 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 6949 parseFloat( styles[ dimension ] ) - 6950 boxModelAdjustment( elem, dimension, "border", false, styles ) - 6951 0.5 6952 ); 6953 } 6954 6955 // Convert to pixels if value adjustment is needed 6956 if ( subtract && ( matches = rcssNum.exec( value ) ) && 6957 ( matches[ 3 ] || "px" ) !== "px" ) { 6958 6959 elem.style[ dimension ] = value; 6960 value = jQuery.css( elem, dimension ); 6961 } 6962 6963 return setPositiveNumber( elem, value, subtract ); 6964 } 6965 }; 6966} ); 6967 6968jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 6969 function( elem, computed ) { 6970 if ( computed ) { 6971 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 6972 elem.getBoundingClientRect().left - 6973 swap( elem, { marginLeft: 0 }, function() { 6974 return elem.getBoundingClientRect().left; 6975 } ) 6976 ) + "px"; 6977 } 6978 } 6979); 6980 6981// These hooks are used by animate to expand properties 6982jQuery.each( { 6983 margin: "", 6984 padding: "", 6985 border: "Width" 6986}, function( prefix, suffix ) { 6987 jQuery.cssHooks[ prefix + suffix ] = { 6988 expand: function( value ) { 6989 var i = 0, 6990 expanded = {}, 6991 6992 // Assumes a single number if not a string 6993 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 6994 6995 for ( ; i < 4; i++ ) { 6996 expanded[ prefix + cssExpand[ i ] + suffix ] = 6997 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 6998 } 6999 7000 return expanded; 7001 } 7002 }; 7003 7004 if ( prefix !== "margin" ) { 7005 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 7006 } 7007} ); 7008 7009jQuery.fn.extend( { 7010 css: function( name, value ) { 7011 return access( this, function( elem, name, value ) { 7012 var styles, len, 7013 map = {}, 7014 i = 0; 7015 7016 if ( Array.isArray( name ) ) { 7017 styles = getStyles( elem ); 7018 len = name.length; 7019 7020 for ( ; i < len; i++ ) { 7021 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 7022 } 7023 7024 return map; 7025 } 7026 7027 return value !== undefined ? 7028 jQuery.style( elem, name, value ) : 7029 jQuery.css( elem, name ); 7030 }, name, value, arguments.length > 1 ); 7031 } 7032} ); 7033 7034 7035function Tween( elem, options, prop, end, easing ) { 7036 return new Tween.prototype.init( elem, options, prop, end, easing ); 7037} 7038jQuery.Tween = Tween; 7039 7040Tween.prototype = { 7041 constructor: Tween, 7042 init: function( elem, options, prop, end, easing, unit ) { 7043 this.elem = elem; 7044 this.prop = prop; 7045 this.easing = easing || jQuery.easing._default; 7046 this.options = options; 7047 this.start = this.now = this.cur(); 7048 this.end = end; 7049 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 7050 }, 7051 cur: function() { 7052 var hooks = Tween.propHooks[ this.prop ]; 7053 7054 return hooks && hooks.get ? 7055 hooks.get( this ) : 7056 Tween.propHooks._default.get( this ); 7057 }, 7058 run: function( percent ) { 7059 var eased, 7060 hooks = Tween.propHooks[ this.prop ]; 7061 7062 if ( this.options.duration ) { 7063 this.pos = eased = jQuery.easing[ this.easing ]( 7064 percent, this.options.duration * percent, 0, 1, this.options.duration 7065 ); 7066 } else { 7067 this.pos = eased = percent; 7068 } 7069 this.now = ( this.end - this.start ) * eased + this.start; 7070 7071 if ( this.options.step ) { 7072 this.options.step.call( this.elem, this.now, this ); 7073 } 7074 7075 if ( hooks && hooks.set ) { 7076 hooks.set( this ); 7077 } else { 7078 Tween.propHooks._default.set( this ); 7079 } 7080 return this; 7081 } 7082}; 7083 7084Tween.prototype.init.prototype = Tween.prototype; 7085 7086Tween.propHooks = { 7087 _default: { 7088 get: function( tween ) { 7089 var result; 7090 7091 // Use a property on the element directly when it is not a DOM element, 7092 // or when there is no matching style property that exists. 7093 if ( tween.elem.nodeType !== 1 || 7094 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 7095 return tween.elem[ tween.prop ]; 7096 } 7097 7098 // Passing an empty string as a 3rd parameter to .css will automatically 7099 // attempt a parseFloat and fallback to a string if the parse fails. 7100 // Simple values such as "10px" are parsed to Float; 7101 // complex values such as "rotate(1rad)" are returned as-is. 7102 result = jQuery.css( tween.elem, tween.prop, "" ); 7103 7104 // Empty strings, null, undefined and "auto" are converted to 0. 7105 return !result || result === "auto" ? 0 : result; 7106 }, 7107 set: function( tween ) { 7108 7109 // Use step hook for back compat. 7110 // Use cssHook if its there. 7111 // Use .style if available and use plain properties where available. 7112 if ( jQuery.fx.step[ tween.prop ] ) { 7113 jQuery.fx.step[ tween.prop ]( tween ); 7114 } else if ( tween.elem.nodeType === 1 && ( 7115 jQuery.cssHooks[ tween.prop ] || 7116 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 7117 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 7118 } else { 7119 tween.elem[ tween.prop ] = tween.now; 7120 } 7121 } 7122 } 7123}; 7124 7125// Support: IE <=9 only 7126// Panic based approach to setting things on disconnected nodes 7127Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 7128 set: function( tween ) { 7129 if ( tween.elem.nodeType && tween.elem.parentNode ) { 7130 tween.elem[ tween.prop ] = tween.now; 7131 } 7132 } 7133}; 7134 7135jQuery.easing = { 7136 linear: function( p ) { 7137 return p; 7138 }, 7139 swing: function( p ) { 7140 return 0.5 - Math.cos( p * Math.PI ) / 2; 7141 }, 7142 _default: "swing" 7143}; 7144 7145jQuery.fx = Tween.prototype.init; 7146 7147// Back compat <1.8 extension point 7148jQuery.fx.step = {}; 7149 7150 7151 7152 7153var 7154 fxNow, inProgress, 7155 rfxtypes = /^(?:toggle|show|hide)$/, 7156 rrun = /queueHooks$/; 7157 7158function schedule() { 7159 if ( inProgress ) { 7160 if ( document.hidden === false && window.requestAnimationFrame ) { 7161 window.requestAnimationFrame( schedule ); 7162 } else { 7163 window.setTimeout( schedule, jQuery.fx.interval ); 7164 } 7165 7166 jQuery.fx.tick(); 7167 } 7168} 7169 7170// Animations created synchronously will run synchronously 7171function createFxNow() { 7172 window.setTimeout( function() { 7173 fxNow = undefined; 7174 } ); 7175 return ( fxNow = Date.now() ); 7176} 7177 7178// Generate parameters to create a standard animation 7179function genFx( type, includeWidth ) { 7180 var which, 7181 i = 0, 7182 attrs = { height: type }; 7183 7184 // If we include width, step value is 1 to do all cssExpand values, 7185 // otherwise step value is 2 to skip over Left and Right 7186 includeWidth = includeWidth ? 1 : 0; 7187 for ( ; i < 4; i += 2 - includeWidth ) { 7188 which = cssExpand[ i ]; 7189 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 7190 } 7191 7192 if ( includeWidth ) { 7193 attrs.opacity = attrs.width = type; 7194 } 7195 7196 return attrs; 7197} 7198 7199function createTween( value, prop, animation ) { 7200 var tween, 7201 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 7202 index = 0, 7203 length = collection.length; 7204 for ( ; index < length; index++ ) { 7205 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 7206 7207 // We're done with this property 7208 return tween; 7209 } 7210 } 7211} 7212 7213function defaultPrefilter( elem, props, opts ) { 7214 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 7215 isBox = "width" in props || "height" in props, 7216 anim = this, 7217 orig = {}, 7218 style = elem.style, 7219 hidden = elem.nodeType && isHiddenWithinTree( elem ), 7220 dataShow = dataPriv.get( elem, "fxshow" ); 7221 7222 // Queue-skipping animations hijack the fx hooks 7223 if ( !opts.queue ) { 7224 hooks = jQuery._queueHooks( elem, "fx" ); 7225 if ( hooks.unqueued == null ) { 7226 hooks.unqueued = 0; 7227 oldfire = hooks.empty.fire; 7228 hooks.empty.fire = function() { 7229 if ( !hooks.unqueued ) { 7230 oldfire(); 7231 } 7232 }; 7233 } 7234 hooks.unqueued++; 7235 7236 anim.always( function() { 7237 7238 // Ensure the complete handler is called before this completes 7239 anim.always( function() { 7240 hooks.unqueued--; 7241 if ( !jQuery.queue( elem, "fx" ).length ) { 7242 hooks.empty.fire(); 7243 } 7244 } ); 7245 } ); 7246 } 7247 7248 // Detect show/hide animations 7249 for ( prop in props ) { 7250 value = props[ prop ]; 7251 if ( rfxtypes.test( value ) ) { 7252 delete props[ prop ]; 7253 toggle = toggle || value === "toggle"; 7254 if ( value === ( hidden ? "hide" : "show" ) ) { 7255 7256 // Pretend to be hidden if this is a "show" and 7257 // there is still data from a stopped show/hide 7258 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 7259 hidden = true; 7260 7261 // Ignore all other no-op show/hide data 7262 } else { 7263 continue; 7264 } 7265 } 7266 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 7267 } 7268 } 7269 7270 // Bail out if this is a no-op like .hide().hide() 7271 propTween = !jQuery.isEmptyObject( props ); 7272 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 7273 return; 7274 } 7275 7276 // Restrict "overflow" and "display" styles during box animations 7277 if ( isBox && elem.nodeType === 1 ) { 7278 7279 // Support: IE <=9 - 11, Edge 12 - 15 7280 // Record all 3 overflow attributes because IE does not infer the shorthand 7281 // from identically-valued overflowX and overflowY and Edge just mirrors 7282 // the overflowX value there. 7283 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 7284 7285 // Identify a display type, preferring old show/hide data over the CSS cascade 7286 restoreDisplay = dataShow && dataShow.display; 7287 if ( restoreDisplay == null ) { 7288 restoreDisplay = dataPriv.get( elem, "display" ); 7289 } 7290 display = jQuery.css( elem, "display" ); 7291 if ( display === "none" ) { 7292 if ( restoreDisplay ) { 7293 display = restoreDisplay; 7294 } else { 7295 7296 // Get nonempty value(s) by temporarily forcing visibility 7297 showHide( [ elem ], true ); 7298 restoreDisplay = elem.style.display || restoreDisplay; 7299 display = jQuery.css( elem, "display" ); 7300 showHide( [ elem ] ); 7301 } 7302 } 7303 7304 // Animate inline elements as inline-block 7305 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 7306 if ( jQuery.css( elem, "float" ) === "none" ) { 7307 7308 // Restore the original display value at the end of pure show/hide animations 7309 if ( !propTween ) { 7310 anim.done( function() { 7311 style.display = restoreDisplay; 7312 } ); 7313 if ( restoreDisplay == null ) { 7314 display = style.display; 7315 restoreDisplay = display === "none" ? "" : display; 7316 } 7317 } 7318 style.display = "inline-block"; 7319 } 7320 } 7321 } 7322 7323 if ( opts.overflow ) { 7324 style.overflow = "hidden"; 7325 anim.always( function() { 7326 style.overflow = opts.overflow[ 0 ]; 7327 style.overflowX = opts.overflow[ 1 ]; 7328 style.overflowY = opts.overflow[ 2 ]; 7329 } ); 7330 } 7331 7332 // Implement show/hide animations 7333 propTween = false; 7334 for ( prop in orig ) { 7335 7336 // General show/hide setup for this element animation 7337 if ( !propTween ) { 7338 if ( dataShow ) { 7339 if ( "hidden" in dataShow ) { 7340 hidden = dataShow.hidden; 7341 } 7342 } else { 7343 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 7344 } 7345 7346 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 7347 if ( toggle ) { 7348 dataShow.hidden = !hidden; 7349 } 7350 7351 // Show elements before animating them 7352 if ( hidden ) { 7353 showHide( [ elem ], true ); 7354 } 7355 7356 /* eslint-disable no-loop-func */ 7357 7358 anim.done( function() { 7359 7360 /* eslint-enable no-loop-func */ 7361 7362 // The final step of a "hide" animation is actually hiding the element 7363 if ( !hidden ) { 7364 showHide( [ elem ] ); 7365 } 7366 dataPriv.remove( elem, "fxshow" ); 7367 for ( prop in orig ) { 7368 jQuery.style( elem, prop, orig[ prop ] ); 7369 } 7370 } ); 7371 } 7372 7373 // Per-property setup 7374 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 7375 if ( !( prop in dataShow ) ) { 7376 dataShow[ prop ] = propTween.start; 7377 if ( hidden ) { 7378 propTween.end = propTween.start; 7379 propTween.start = 0; 7380 } 7381 } 7382 } 7383} 7384 7385function propFilter( props, specialEasing ) { 7386 var index, name, easing, value, hooks; 7387 7388 // camelCase, specialEasing and expand cssHook pass 7389 for ( index in props ) { 7390 name = camelCase( index ); 7391 easing = specialEasing[ name ]; 7392 value = props[ index ]; 7393 if ( Array.isArray( value ) ) { 7394 easing = value[ 1 ]; 7395 value = props[ index ] = value[ 0 ]; 7396 } 7397 7398 if ( index !== name ) { 7399 props[ name ] = value; 7400 delete props[ index ]; 7401 } 7402 7403 hooks = jQuery.cssHooks[ name ]; 7404 if ( hooks && "expand" in hooks ) { 7405 value = hooks.expand( value ); 7406 delete props[ name ]; 7407 7408 // Not quite $.extend, this won't overwrite existing keys. 7409 // Reusing 'index' because we have the correct "name" 7410 for ( index in value ) { 7411 if ( !( index in props ) ) { 7412 props[ index ] = value[ index ]; 7413 specialEasing[ index ] = easing; 7414 } 7415 } 7416 } else { 7417 specialEasing[ name ] = easing; 7418 } 7419 } 7420} 7421 7422function Animation( elem, properties, options ) { 7423 var result, 7424 stopped, 7425 index = 0, 7426 length = Animation.prefilters.length, 7427 deferred = jQuery.Deferred().always( function() { 7428 7429 // Don't match elem in the :animated selector 7430 delete tick.elem; 7431 } ), 7432 tick = function() { 7433 if ( stopped ) { 7434 return false; 7435 } 7436 var currentTime = fxNow || createFxNow(), 7437 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 7438
vendor: 9,542 bytes, lines 7439-7829
7439 // Support: Android 2.3 only 7440 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) 7441 temp = remaining / animation.duration || 0, 7442 percent = 1 - temp, 7443 index = 0, 7444 length = animation.tweens.length; 7445 7446 for ( ; index < length; index++ ) { 7447 animation.tweens[ index ].run( percent ); 7448 } 7449 7450 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 7451 7452 // If there's more to do, yield 7453 if ( percent < 1 && length ) { 7454 return remaining; 7455 } 7456 7457 // If this was an empty animation, synthesize a final progress notification 7458 if ( !length ) { 7459 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7460 } 7461 7462 // Resolve the animation and report its conclusion 7463 deferred.resolveWith( elem, [ animation ] ); 7464 return false; 7465 }, 7466 animation = deferred.promise( { 7467 elem: elem, 7468 props: jQuery.extend( {}, properties ), 7469 opts: jQuery.extend( true, { 7470 specialEasing: {}, 7471 easing: jQuery.easing._default 7472 }, options ), 7473 originalProperties: properties, 7474 originalOptions: options, 7475 startTime: fxNow || createFxNow(), 7476 duration: options.duration, 7477 tweens: [], 7478 createTween: function( prop, end ) { 7479 var tween = jQuery.Tween( elem, animation.opts, prop, end, 7480 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 7481 animation.tweens.push( tween ); 7482 return tween; 7483 }, 7484 stop: function( gotoEnd ) { 7485 var index = 0, 7486 7487 // If we are going to the end, we want to run all the tweens 7488 // otherwise we skip this part 7489 length = gotoEnd ? animation.tweens.length : 0; 7490 if ( stopped ) { 7491 return this; 7492 } 7493 stopped = true; 7494 for ( ; index < length; index++ ) { 7495 animation.tweens[ index ].run( 1 ); 7496 } 7497 7498 // Resolve when we played the last frame; otherwise, reject 7499 if ( gotoEnd ) { 7500 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7501 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 7502 } else { 7503 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 7504 } 7505 return this; 7506 } 7507 } ), 7508 props = animation.props; 7509 7510 propFilter( props, animation.opts.specialEasing ); 7511 7512 for ( ; index < length; index++ ) { 7513 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 7514 if ( result ) { 7515 if ( isFunction( result.stop ) ) { 7516 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 7517 result.stop.bind( result ); 7518 } 7519 return result; 7520 } 7521 } 7522 7523 jQuery.map( props, createTween, animation ); 7524 7525 if ( isFunction( animation.opts.start ) ) { 7526 animation.opts.start.call( elem, animation ); 7527 } 7528 7529 // Attach callbacks from options 7530 animation 7531 .progress( animation.opts.progress ) 7532 .done( animation.opts.done, animation.opts.complete ) 7533 .fail( animation.opts.fail ) 7534 .always( animation.opts.always ); 7535 7536 jQuery.fx.timer( 7537 jQuery.extend( tick, { 7538 elem: elem, 7539 anim: animation, 7540 queue: animation.opts.queue 7541 } ) 7542 ); 7543 7544 return animation; 7545} 7546 7547jQuery.Animation = jQuery.extend( Animation, { 7548 7549 tweeners: { 7550 "*": [ function( prop, value ) { 7551 var tween = this.createTween( prop, value ); 7552 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 7553 return tween; 7554 } ] 7555 }, 7556 7557 tweener: function( props, callback ) { 7558 if ( isFunction( props ) ) { 7559 callback = props; 7560 props = [ "*" ]; 7561 } else { 7562 props = props.match( rnothtmlwhite ); 7563 } 7564 7565 var prop, 7566 index = 0, 7567 length = props.length; 7568 7569 for ( ; index < length; index++ ) { 7570 prop = props[ index ]; 7571 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 7572 Animation.tweeners[ prop ].unshift( callback ); 7573 } 7574 }, 7575 7576 prefilters: [ defaultPrefilter ], 7577 7578 prefilter: function( callback, prepend ) { 7579 if ( prepend ) { 7580 Animation.prefilters.unshift( callback ); 7581 } else { 7582 Animation.prefilters.push( callback ); 7583 } 7584 } 7585} ); 7586 7587jQuery.speed = function( speed, easing, fn ) { 7588 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 7589 complete: fn || !fn && easing || 7590 isFunction( speed ) && speed, 7591 duration: speed, 7592 easing: fn && easing || easing && !isFunction( easing ) && easing 7593 }; 7594 7595 // Go to the end state if fx are off 7596 if ( jQuery.fx.off ) { 7597 opt.duration = 0; 7598 7599 } else { 7600 if ( typeof opt.duration !== "number" ) { 7601 if ( opt.duration in jQuery.fx.speeds ) { 7602 opt.duration = jQuery.fx.speeds[ opt.duration ]; 7603 7604 } else { 7605 opt.duration = jQuery.fx.speeds._default; 7606 } 7607 } 7608 } 7609 7610 // Normalize opt.queue - true/undefined/null -> "fx" 7611 if ( opt.queue == null || opt.queue === true ) { 7612 opt.queue = "fx"; 7613 } 7614 7615 // Queueing 7616 opt.old = opt.complete; 7617 7618 opt.complete = function() { 7619 if ( isFunction( opt.old ) ) { 7620 opt.old.call( this ); 7621 } 7622 7623 if ( opt.queue ) { 7624 jQuery.dequeue( this, opt.queue ); 7625 } 7626 }; 7627 7628 return opt; 7629}; 7630 7631jQuery.fn.extend( { 7632 fadeTo: function( speed, to, easing, callback ) { 7633 7634 // Show any hidden elements after setting opacity to 0 7635 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 7636 7637 // Animate to the value specified 7638 .end().animate( { opacity: to }, speed, easing, callback ); 7639 }, 7640 animate: function( prop, speed, easing, callback ) { 7641 var empty = jQuery.isEmptyObject( prop ), 7642 optall = jQuery.speed( speed, easing, callback ), 7643 doAnimation = function() { 7644 7645 // Operate on a copy of prop so per-property easing won't be lost 7646 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 7647 7648 // Empty animations, or finishing resolves immediately 7649 if ( empty || dataPriv.get( this, "finish" ) ) { 7650 anim.stop( true ); 7651 } 7652 }; 7653 7654 doAnimation.finish = doAnimation; 7655 7656 return empty || optall.queue === false ? 7657 this.each( doAnimation ) : 7658 this.queue( optall.queue, doAnimation ); 7659 }, 7660 stop: function( type, clearQueue, gotoEnd ) { 7661 var stopQueue = function( hooks ) { 7662 var stop = hooks.stop; 7663 delete hooks.stop; 7664 stop( gotoEnd ); 7665 }; 7666 7667 if ( typeof type !== "string" ) { 7668 gotoEnd = clearQueue; 7669 clearQueue = type; 7670 type = undefined; 7671 } 7672 if ( clearQueue ) { 7673 this.queue( type || "fx", [] ); 7674 } 7675 7676 return this.each( function() { 7677 var dequeue = true, 7678 index = type != null && type + "queueHooks", 7679 timers = jQuery.timers, 7680 data = dataPriv.get( this ); 7681 7682 if ( index ) { 7683 if ( data[ index ] && data[ index ].stop ) { 7684 stopQueue( data[ index ] ); 7685 } 7686 } else { 7687 for ( index in data ) { 7688 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 7689 stopQueue( data[ index ] ); 7690 } 7691 } 7692 } 7693 7694 for ( index = timers.length; index--; ) { 7695 if ( timers[ index ].elem === this && 7696 ( type == null || timers[ index ].queue === type ) ) { 7697 7698 timers[ index ].anim.stop( gotoEnd ); 7699 dequeue = false; 7700 timers.splice( index, 1 ); 7701 } 7702 } 7703 7704 // Start the next in the queue if the last step wasn't forced. 7705 // Timers currently will call their complete callbacks, which 7706 // will dequeue but only if they were gotoEnd. 7707 if ( dequeue || !gotoEnd ) { 7708 jQuery.dequeue( this, type ); 7709 } 7710 } ); 7711 }, 7712 finish: function( type ) { 7713 if ( type !== false ) { 7714 type = type || "fx"; 7715 } 7716 return this.each( function() { 7717 var index, 7718 data = dataPriv.get( this ), 7719 queue = data[ type + "queue" ], 7720 hooks = data[ type + "queueHooks" ], 7721 timers = jQuery.timers, 7722 length = queue ? queue.length : 0; 7723 7724 // Enable finishing flag on private data 7725 data.finish = true; 7726 7727 // Empty the queue first 7728 jQuery.queue( this, type, [] ); 7729 7730 if ( hooks && hooks.stop ) { 7731 hooks.stop.call( this, true ); 7732 } 7733 7734 // Look for any active animations, and finish them 7735 for ( index = timers.length; index--; ) { 7736 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 7737 timers[ index ].anim.stop( true ); 7738 timers.splice( index, 1 ); 7739 } 7740 } 7741 7742 // Look for any animations in the old queue and finish them 7743 for ( index = 0; index < length; index++ ) { 7744 if ( queue[ index ] && queue[ index ].finish ) { 7745 queue[ index ].finish.call( this ); 7746 } 7747 } 7748 7749 // Turn off finishing flag 7750 delete data.finish; 7751 } ); 7752 } 7753} ); 7754 7755jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { 7756 var cssFn = jQuery.fn[ name ]; 7757 jQuery.fn[ name ] = function( speed, easing, callback ) { 7758 return speed == null || typeof speed === "boolean" ? 7759 cssFn.apply( this, arguments ) : 7760 this.animate( genFx( name, true ), speed, easing, callback ); 7761 }; 7762} ); 7763 7764// Generate shortcuts for custom animations 7765jQuery.each( { 7766 slideDown: genFx( "show" ), 7767 slideUp: genFx( "hide" ), 7768 slideToggle: genFx( "toggle" ), 7769 fadeIn: { opacity: "show" }, 7770 fadeOut: { opacity: "hide" }, 7771 fadeToggle: { opacity: "toggle" } 7772}, function( name, props ) { 7773 jQuery.fn[ name ] = function( speed, easing, callback ) { 7774 return this.animate( props, speed, easing, callback ); 7775 }; 7776} ); 7777 7778jQuery.timers = []; 7779jQuery.fx.tick = function() { 7780 var timer, 7781 i = 0, 7782 timers = jQuery.timers; 7783 7784 fxNow = Date.now(); 7785 7786 for ( ; i < timers.length; i++ ) { 7787 timer = timers[ i ]; 7788 7789 // Run the timer and safely remove it when done (allowing for external removal) 7790 if ( !timer() && timers[ i ] === timer ) { 7791 timers.splice( i--, 1 ); 7792 } 7793 } 7794 7795 if ( !timers.length ) { 7796 jQuery.fx.stop(); 7797 } 7798 fxNow = undefined; 7799}; 7800 7801jQuery.fx.timer = function( timer ) { 7802 jQuery.timers.push( timer ); 7803 jQuery.fx.start(); 7804}; 7805 7806jQuery.fx.interval = 13; 7807jQuery.fx.start = function() { 7808 if ( inProgress ) { 7809 return; 7810 } 7811 7812 inProgress = true; 7813 schedule(); 7814}; 7815 7816jQuery.fx.stop = function() { 7817 inProgress = null; 7818}; 7819 7820jQuery.fx.speeds = { 7821 slow: 600, 7822 fast: 200, 7823 7824 // Default speed 7825 _default: 400 7826}; 7827 7828 7829// Based off of the plugin by Clint Helfers, with permission.
vendor: 5,177 bytes, lines 7830-8050
7830jQuery.fn.delay = function( time, type ) { 7831 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 7832 type = type || "fx"; 7833 7834 return this.queue( type, function( next, hooks ) { 7835 var timeout = window.setTimeout( next, time ); 7836 hooks.stop = function() { 7837 window.clearTimeout( timeout ); 7838 }; 7839 } ); 7840}; 7841 7842 7843( function() { 7844 var input = document.createElement( "input" ), 7845 select = document.createElement( "select" ), 7846 opt = select.appendChild( document.createElement( "option" ) ); 7847 7848 input.type = "checkbox"; 7849 7850 // Support: Android <=4.3 only 7851 // Default value for a checkbox should be "on" 7852 support.checkOn = input.value !== ""; 7853 7854 // Support: IE <=11 only 7855 // Must access selectedIndex to make default options select 7856 support.optSelected = opt.selected; 7857 7858 // Support: IE <=11 only 7859 // An input loses its value after becoming a radio 7860 input = document.createElement( "input" ); 7861 input.value = "t"; 7862 input.type = "radio"; 7863 support.radioValue = input.value === "t"; 7864} )(); 7865 7866 7867var boolHook, 7868 attrHandle = jQuery.expr.attrHandle; 7869 7870jQuery.fn.extend( { 7871 attr: function( name, value ) { 7872 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 7873 }, 7874 7875 removeAttr: function( name ) { 7876 return this.each( function() { 7877 jQuery.removeAttr( this, name ); 7878 } ); 7879 } 7880} ); 7881 7882jQuery.extend( { 7883 attr: function( elem, name, value ) { 7884 var ret, hooks, 7885 nType = elem.nodeType; 7886 7887 // Don't get/set attributes on text, comment and attribute nodes 7888 if ( nType === 3 || nType === 8 || nType === 2 ) { 7889 return; 7890 } 7891 7892 // Fallback to prop when attributes are not supported 7893 if ( typeof elem.getAttribute === "undefined" ) { 7894 return jQuery.prop( elem, name, value ); 7895 } 7896 7897 // Attribute hooks are determined by the lowercase version 7898 // Grab necessary hook if one is defined 7899 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 7900 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 7901 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 7902 } 7903 7904 if ( value !== undefined ) { 7905 if ( value === null ) { 7906 jQuery.removeAttr( elem, name ); 7907 return; 7908 } 7909 7910 if ( hooks && "set" in hooks && 7911 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 7912 return ret; 7913 } 7914 7915 elem.setAttribute( name, value + "" ); 7916 return value; 7917 } 7918 7919 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 7920 return ret; 7921 } 7922 7923 ret = jQuery.find.attr( elem, name ); 7924 7925 // Non-existent attributes return null, we normalize to undefined 7926 return ret == null ? undefined : ret; 7927 }, 7928 7929 attrHooks: { 7930 type: { 7931 set: function( elem, value ) { 7932 if ( !support.radioValue && value === "radio" && 7933 nodeName( elem, "input" ) ) { 7934 var val = elem.value; 7935 elem.setAttribute( "type", value ); 7936 if ( val ) { 7937 elem.value = val; 7938 } 7939 return value; 7940 } 7941 } 7942 } 7943 }, 7944 7945 removeAttr: function( elem, value ) { 7946 var name, 7947 i = 0, 7948 7949 // Attribute names can contain non-HTML whitespace characters 7950 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 7951 attrNames = value && value.match( rnothtmlwhite ); 7952 7953 if ( attrNames && elem.nodeType === 1 ) { 7954 while ( ( name = attrNames[ i++ ] ) ) { 7955 elem.removeAttribute( name ); 7956 } 7957 } 7958 } 7959} ); 7960 7961// Hooks for boolean attributes 7962boolHook = { 7963 set: function( elem, value, name ) { 7964 if ( value === false ) { 7965 7966 // Remove boolean attributes when set to false 7967 jQuery.removeAttr( elem, name ); 7968 } else { 7969 elem.setAttribute( name, name ); 7970 } 7971 return name; 7972 } 7973}; 7974 7975jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { 7976 var getter = attrHandle[ name ] || jQuery.find.attr; 7977 7978 attrHandle[ name ] = function( elem, name, isXML ) { 7979 var ret, handle, 7980 lowercaseName = name.toLowerCase(); 7981 7982 if ( !isXML ) { 7983 7984 // Avoid an infinite loop by temporarily removing this function from the getter 7985 handle = attrHandle[ lowercaseName ]; 7986 attrHandle[ lowercaseName ] = ret; 7987 ret = getter( elem, name, isXML ) != null ? 7988 lowercaseName : 7989 null; 7990 attrHandle[ lowercaseName ] = handle; 7991 } 7992 return ret; 7993 }; 7994} ); 7995 7996 7997 7998 7999var rfocusable = /^(?:input|select|textarea|button)$/i, 8000 rclickable = /^(?:a|area)$/i; 8001 8002jQuery.fn.extend( { 8003 prop: function( name, value ) { 8004 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 8005 }, 8006 8007 removeProp: function( name ) { 8008 return this.each( function() { 8009 delete this[ jQuery.propFix[ name ] || name ]; 8010 } ); 8011 } 8012} ); 8013 8014jQuery.extend( { 8015 prop: function( elem, name, value ) { 8016 var ret, hooks, 8017 nType = elem.nodeType; 8018 8019 // Don't get/set properties on text, comment and attribute nodes 8020 if ( nType === 3 || nType === 8 || nType === 2 ) { 8021 return; 8022 } 8023 8024 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 8025 8026 // Fix name and attach hooks 8027 name = jQuery.propFix[ name ] || name; 8028 hooks = jQuery.propHooks[ name ]; 8029 } 8030 8031 if ( value !== undefined ) { 8032 if ( hooks && "set" in hooks && 8033 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 8034 return ret; 8035 } 8036 8037 return ( elem[ name ] = value ); 8038 } 8039 8040 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 8041 return ret; 8042 } 8043 8044 return elem[ name ]; 8045 }, 8046 8047 propHooks: { 8048 tabIndex: { 8049 get: function( elem ) { 8050
vendor: 6,126 bytes, lines 8051-8310
8051 // Support: IE <=9 - 11 only 8052 // elem.tabIndex doesn't always return the 8053 // correct value when it hasn't been explicitly set 8054 // Use proper attribute retrieval (trac-12072) 8055 var tabindex = jQuery.find.attr( elem, "tabindex" ); 8056 8057 if ( tabindex ) { 8058 return parseInt( tabindex, 10 ); 8059 } 8060 8061 if ( 8062 rfocusable.test( elem.nodeName ) || 8063 rclickable.test( elem.nodeName ) && 8064 elem.href 8065 ) { 8066 return 0; 8067 } 8068 8069 return -1; 8070 } 8071 } 8072 }, 8073 8074 propFix: { 8075 "for": "htmlFor", 8076 "class": "className" 8077 } 8078} ); 8079 8080// Support: IE <=11 only 8081// Accessing the selectedIndex property 8082// forces the browser to respect setting selected 8083// on the option 8084// The getter ensures a default option is selected 8085// when in an optgroup 8086// eslint rule "no-unused-expressions" is disabled for this code 8087// since it considers such accessions noop 8088if ( !support.optSelected ) { 8089 jQuery.propHooks.selected = { 8090 get: function( elem ) { 8091 8092 /* eslint no-unused-expressions: "off" */ 8093 8094 var parent = elem.parentNode; 8095 if ( parent && parent.parentNode ) { 8096 parent.parentNode.selectedIndex; 8097 } 8098 return null; 8099 }, 8100 set: function( elem ) { 8101 8102 /* eslint no-unused-expressions: "off" */ 8103 8104 var parent = elem.parentNode; 8105 if ( parent ) { 8106 parent.selectedIndex; 8107 8108 if ( parent.parentNode ) { 8109 parent.parentNode.selectedIndex; 8110 } 8111 } 8112 } 8113 }; 8114} 8115 8116jQuery.each( [ 8117 "tabIndex", 8118 "readOnly", 8119 "maxLength", 8120 "cellSpacing", 8121 "cellPadding", 8122 "rowSpan", 8123 "colSpan", 8124 "useMap", 8125 "frameBorder", 8126 "contentEditable" 8127], function() { 8128 jQuery.propFix[ this.toLowerCase() ] = this; 8129} ); 8130 8131 8132 8133 8134 // Strip and collapse whitespace according to HTML spec 8135 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 8136 function stripAndCollapse( value ) { 8137 var tokens = value.match( rnothtmlwhite ) || []; 8138 return tokens.join( " " ); 8139 } 8140 8141 8142function getClass( elem ) { 8143 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 8144} 8145 8146function classesToArray( value ) { 8147 if ( Array.isArray( value ) ) { 8148 return value; 8149 } 8150 if ( typeof value === "string" ) { 8151 return value.match( rnothtmlwhite ) || []; 8152 } 8153 return []; 8154} 8155 8156jQuery.fn.extend( { 8157 addClass: function( value ) { 8158 var classNames, cur, curValue, className, i, finalValue; 8159 8160 if ( isFunction( value ) ) { 8161 return this.each( function( j ) { 8162 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 8163 } ); 8164 } 8165 8166 classNames = classesToArray( value ); 8167 8168 if ( classNames.length ) { 8169 return this.each( function() { 8170 curValue = getClass( this ); 8171 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 8172 8173 if ( cur ) { 8174 for ( i = 0; i < classNames.length; i++ ) { 8175 className = classNames[ i ]; 8176 if ( cur.indexOf( " " + className + " " ) < 0 ) { 8177 cur += className + " "; 8178 } 8179 } 8180 8181 // Only assign if different to avoid unneeded rendering. 8182 finalValue = stripAndCollapse( cur ); 8183 if ( curValue !== finalValue ) { 8184 this.setAttribute( "class", finalValue ); 8185 } 8186 } 8187 } ); 8188 } 8189 8190 return this; 8191 }, 8192 8193 removeClass: function( value ) { 8194 var classNames, cur, curValue, className, i, finalValue; 8195 8196 if ( isFunction( value ) ) { 8197 return this.each( function( j ) { 8198 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 8199 } ); 8200 } 8201 8202 if ( !arguments.length ) { 8203 return this.attr( "class", "" ); 8204 } 8205 8206 classNames = classesToArray( value ); 8207 8208 if ( classNames.length ) { 8209 return this.each( function() { 8210 curValue = getClass( this ); 8211 8212 // This expression is here for better compressibility (see addClass) 8213 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 8214 8215 if ( cur ) { 8216 for ( i = 0; i < classNames.length; i++ ) { 8217 className = classNames[ i ]; 8218 8219 // Remove *all* instances 8220 while ( cur.indexOf( " " + className + " " ) > -1 ) { 8221 cur = cur.replace( " " + className + " ", " " ); 8222 } 8223 } 8224 8225 // Only assign if different to avoid unneeded rendering. 8226 finalValue = stripAndCollapse( cur ); 8227 if ( curValue !== finalValue ) { 8228 this.setAttribute( "class", finalValue ); 8229 } 8230 } 8231 } ); 8232 } 8233 8234 return this; 8235 }, 8236 8237 toggleClass: function( value, stateVal ) { 8238 var classNames, className, i, self, 8239 type = typeof value, 8240 isValidValue = type === "string" || Array.isArray( value ); 8241 8242 if ( isFunction( value ) ) { 8243 return this.each( function( i ) { 8244 jQuery( this ).toggleClass( 8245 value.call( this, i, getClass( this ), stateVal ), 8246 stateVal 8247 ); 8248 } ); 8249 } 8250 8251 if ( typeof stateVal === "boolean" && isValidValue ) { 8252 return stateVal ? this.addClass( value ) : this.removeClass( value ); 8253 } 8254 8255 classNames = classesToArray( value ); 8256 8257 return this.each( function() { 8258 if ( isValidValue ) { 8259 8260 // Toggle individual class names 8261 self = jQuery( this ); 8262 8263 for ( i = 0; i < classNames.length; i++ ) { 8264 className = classNames[ i ]; 8265 8266 // Check each className given, space separated list 8267 if ( self.hasClass( className ) ) { 8268 self.removeClass( className ); 8269 } else { 8270 self.addClass( className ); 8271 } 8272 } 8273 8274 // Toggle whole class name 8275 } else if ( value === undefined || type === "boolean" ) { 8276 className = getClass( this ); 8277 if ( className ) { 8278 8279 // Store className if set 8280 dataPriv.set( this, "__className__", className ); 8281 } 8282 8283 // If the element has a class name or if we're passed `false`, 8284 // then remove the whole classname (if there was one, the above saved it). 8285 // Otherwise bring back whatever was previously saved (if anything), 8286 // falling back to the empty string if nothing was stored. 8287 if ( this.setAttribute ) { 8288 this.setAttribute( "class", 8289 className || value === false ? 8290 "" : 8291 dataPriv.get( this, "__className__" ) || "" 8292 ); 8293 } 8294 } 8295 } ); 8296 }, 8297 8298 hasClass: function( selector ) { 8299 var className, elem, 8300 i = 0; 8301 8302 className = " " + selector + " "; 8303 while ( ( elem = this[ i++ ] ) ) { 8304 if ( elem.nodeType === 1 && 8305 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 8306 return true; 8307 } 8308 } 8309 8310 return false;
vendor: 1,385 bytes, lines 8311-8380
8311 } 8312} ); 8313 8314 8315 8316 8317var rreturn = /\r/g; 8318 8319jQuery.fn.extend( { 8320 val: function( value ) { 8321 var hooks, ret, valueIsFunction, 8322 elem = this[ 0 ]; 8323 8324 if ( !arguments.length ) { 8325 if ( elem ) { 8326 hooks = jQuery.valHooks[ elem.type ] || 8327 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 8328 8329 if ( hooks && 8330 "get" in hooks && 8331 ( ret = hooks.get( elem, "value" ) ) !== undefined 8332 ) { 8333 return ret; 8334 } 8335 8336 ret = elem.value; 8337 8338 // Handle most common string cases 8339 if ( typeof ret === "string" ) { 8340 return ret.replace( rreturn, "" ); 8341 } 8342 8343 // Handle cases where value is null/undef or number 8344 return ret == null ? "" : ret; 8345 } 8346 8347 return; 8348 } 8349 8350 valueIsFunction = isFunction( value ); 8351 8352 return this.each( function( i ) { 8353 var val; 8354 8355 if ( this.nodeType !== 1 ) { 8356 return; 8357 } 8358 8359 if ( valueIsFunction ) { 8360 val = value.call( this, i, jQuery( this ).val() ); 8361 } else { 8362 val = value; 8363 } 8364 8365 // Treat null/undefined as ""; convert numbers to string 8366 if ( val == null ) { 8367 val = ""; 8368 8369 } else if ( typeof val === "number" ) { 8370 val += ""; 8371 8372 } else if ( Array.isArray( val ) ) { 8373 val = jQuery.map( val, function( value ) { 8374 return value == null ? "" : value + ""; 8375 } ); 8376 } 8377 8378 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 8379 8380 // If set returns undefined, fall back to normal setting
vendor: 4,458 bytes, lines 8381-8566
8381 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 8382 this.value = val; 8383 } 8384 } ); 8385 } 8386} ); 8387 8388jQuery.extend( { 8389 valHooks: { 8390 option: { 8391 get: function( elem ) { 8392 8393 var val = jQuery.find.attr( elem, "value" ); 8394 return val != null ? 8395 val : 8396 8397 // Support: IE <=10 - 11 only 8398 // option.text throws exceptions (trac-14686, trac-14858) 8399 // Strip and collapse whitespace 8400 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 8401 stripAndCollapse( jQuery.text( elem ) ); 8402 } 8403 }, 8404 select: { 8405 get: function( elem ) { 8406 var value, option, i, 8407 options = elem.options, 8408 index = elem.selectedIndex, 8409 one = elem.type === "select-one", 8410 values = one ? null : [], 8411 max = one ? index + 1 : options.length; 8412 8413 if ( index < 0 ) { 8414 i = max; 8415 8416 } else { 8417 i = one ? index : 0; 8418 } 8419 8420 // Loop through all the selected options 8421 for ( ; i < max; i++ ) { 8422 option = options[ i ]; 8423 8424 // Support: IE <=9 only 8425 // IE8-9 doesn't update selected after form reset (trac-2551) 8426 if ( ( option.selected || i === index ) && 8427 8428 // Don't return options that are disabled or in a disabled optgroup 8429 !option.disabled && 8430 ( !option.parentNode.disabled || 8431 !nodeName( option.parentNode, "optgroup" ) ) ) { 8432 8433 // Get the specific value for the option 8434 value = jQuery( option ).val(); 8435 8436 // We don't need an array for one selects 8437 if ( one ) { 8438 return value; 8439 } 8440 8441 // Multi-Selects return an array 8442 values.push( value ); 8443 } 8444 } 8445 8446 return values; 8447 }, 8448 8449 set: function( elem, value ) { 8450 var optionSet, option, 8451 options = elem.options, 8452 values = jQuery.makeArray( value ), 8453 i = options.length; 8454 8455 while ( i-- ) { 8456 option = options[ i ]; 8457 8458 /* eslint-disable no-cond-assign */ 8459 8460 if ( option.selected = 8461 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 8462 ) { 8463 optionSet = true; 8464 } 8465 8466 /* eslint-enable no-cond-assign */ 8467 } 8468 8469 // Force browsers to behave consistently when non-matching value is set 8470 if ( !optionSet ) { 8471 elem.selectedIndex = -1; 8472 } 8473 return values; 8474 } 8475 } 8476 } 8477} ); 8478 8479// Radios and checkboxes getter/setter 8480jQuery.each( [ "radio", "checkbox" ], function() { 8481 jQuery.valHooks[ this ] = { 8482 set: function( elem, value ) { 8483 if ( Array.isArray( value ) ) { 8484 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 8485 } 8486 } 8487 }; 8488 if ( !support.checkOn ) { 8489 jQuery.valHooks[ this ].get = function( elem ) { 8490 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 8491 }; 8492 } 8493} ); 8494 8495 8496 8497 8498// Return jQuery for attributes-only inclusion 8499var location = window.location; 8500 8501var nonce = { guid: Date.now() }; 8502 8503var rquery = ( /\?/ ); 8504 8505 8506 8507// Cross-browser xml parsing 8508jQuery.parseXML = function( data ) { 8509 var xml, parserErrorElem; 8510 if ( !data || typeof data !== "string" ) { 8511 return null; 8512 } 8513 8514 // Support: IE 9 - 11 only 8515 // IE throws on parseFromString with invalid input. 8516 try { 8517 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 8518 } catch ( e ) {} 8519 8520 parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; 8521 if ( !xml || parserErrorElem ) { 8522 jQuery.error( "Invalid XML: " + ( 8523 parserErrorElem ? 8524 jQuery.map( parserErrorElem.childNodes, function( el ) { 8525 return el.textContent; 8526 } ).join( "\n" ) : 8527 data 8528 ) ); 8529 } 8530 return xml; 8531}; 8532 8533 8534var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 8535 stopPropagationCallback = function( e ) { 8536 e.stopPropagation(); 8537 }; 8538 8539jQuery.extend( jQuery.event, { 8540 8541 trigger: function( event, data, elem, onlyHandlers ) { 8542 8543 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 8544 eventPath = [ elem || document ], 8545 type = hasOwn.call( event, "type" ) ? event.type : event, 8546 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 8547 8548 cur = lastElement = tmp = elem = elem || document; 8549 8550 // Don't do events on text and comment nodes 8551 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 8552 return; 8553 } 8554 8555 // focus/blur morphs to focusin/out; ensure we're not firing them right now 8556 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 8557 return; 8558 } 8559 8560 if ( type.indexOf( "." ) > -1 ) { 8561 8562 // Namespaced trigger; create a regexp to match event type in handle() 8563 namespaces = type.split( "." ); 8564 type = namespaces.shift(); 8565 namespaces.sort(); 8566 }
vendor: 6,524 bytes, lines 8567-8816
8567 ontype = type.indexOf( ":" ) < 0 && "on" + type; 8568 8569 // Caller can pass in a jQuery.Event object, Object, or just an event type string 8570 event = event[ jQuery.expando ] ? 8571 event : 8572 new jQuery.Event( type, typeof event === "object" && event ); 8573 8574 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 8575 event.isTrigger = onlyHandlers ? 2 : 3; 8576 event.namespace = namespaces.join( "." ); 8577 event.rnamespace = event.namespace ? 8578 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 8579 null; 8580 8581 // Clean up the event in case it is being reused 8582 event.result = undefined; 8583 if ( !event.target ) { 8584 event.target = elem; 8585 } 8586 8587 // Clone any incoming data and prepend the event, creating the handler arg list 8588 data = data == null ? 8589 [ event ] : 8590 jQuery.makeArray( data, [ event ] ); 8591 8592 // Allow special events to draw outside the lines 8593 special = jQuery.event.special[ type ] || {}; 8594 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 8595 return; 8596 } 8597 8598 // Determine event propagation path in advance, per W3C events spec (trac-9951) 8599 // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) 8600 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 8601 8602 bubbleType = special.delegateType || type; 8603 if ( !rfocusMorph.test( bubbleType + type ) ) { 8604 cur = cur.parentNode; 8605 } 8606 for ( ; cur; cur = cur.parentNode ) { 8607 eventPath.push( cur ); 8608 tmp = cur; 8609 } 8610 8611 // Only add window if we got to document (e.g., not plain obj or detached DOM) 8612 if ( tmp === ( elem.ownerDocument || document ) ) { 8613 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 8614 } 8615 } 8616 8617 // Fire handlers on the event path 8618 i = 0; 8619 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 8620 lastElement = cur; 8621 event.type = i > 1 ? 8622 bubbleType : 8623 special.bindType || type; 8624 8625 // jQuery handler 8626 handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && 8627 dataPriv.get( cur, "handle" ); 8628 if ( handle ) { 8629 handle.apply( cur, data ); 8630 } 8631 8632 // Native handler 8633 handle = ontype && cur[ ontype ]; 8634 if ( handle && handle.apply && acceptData( cur ) ) { 8635 event.result = handle.apply( cur, data ); 8636 if ( event.result === false ) { 8637 event.preventDefault(); 8638 } 8639 } 8640 } 8641 event.type = type; 8642 8643 // If nobody prevented the default action, do it now 8644 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 8645 8646 if ( ( !special._default || 8647 special._default.apply( eventPath.pop(), data ) === false ) && 8648 acceptData( elem ) ) { 8649 8650 // Call a native DOM method on the target with the same name as the event. 8651 // Don't do default actions on window, that's where global variables be (trac-6170) 8652 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 8653 8654 // Don't re-trigger an onFOO event when we call its FOO() method 8655 tmp = elem[ ontype ]; 8656 8657 if ( tmp ) { 8658 elem[ ontype ] = null; 8659 } 8660 8661 // Prevent re-triggering of the same event, since we already bubbled it above 8662 jQuery.event.triggered = type; 8663 8664 if ( event.isPropagationStopped() ) { 8665 lastElement.addEventListener( type, stopPropagationCallback ); 8666 } 8667 8668 elem[ type ](); 8669 8670 if ( event.isPropagationStopped() ) { 8671 lastElement.removeEventListener( type, stopPropagationCallback ); 8672 } 8673 8674 jQuery.event.triggered = undefined; 8675 8676 if ( tmp ) { 8677 elem[ ontype ] = tmp; 8678 } 8679 } 8680 } 8681 } 8682 8683 return event.result; 8684 }, 8685 8686 // Piggyback on a donor event to simulate a different one 8687 // Used only for `focus(in | out)` events 8688 simulate: function( type, elem, event ) { 8689 var e = jQuery.extend( 8690 new jQuery.Event(), 8691 event, 8692 { 8693 type: type, 8694 isSimulated: true 8695 } 8696 ); 8697 8698 jQuery.event.trigger( e, null, elem ); 8699 } 8700 8701} ); 8702 8703jQuery.fn.extend( { 8704 8705 trigger: function( type, data ) { 8706 return this.each( function() { 8707 jQuery.event.trigger( type, data, this ); 8708 } ); 8709 }, 8710 triggerHandler: function( type, data ) { 8711 var elem = this[ 0 ]; 8712 if ( elem ) { 8713 return jQuery.event.trigger( type, data, elem, true ); 8714 } 8715 } 8716} ); 8717 8718 8719var 8720 rbracket = /\[\]$/, 8721 rCRLF = /\r?\n/g, 8722 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 8723 rsubmittable = /^(?:input|select|textarea|keygen)/i; 8724 8725function buildParams( prefix, obj, traditional, add ) { 8726 var name; 8727 8728 if ( Array.isArray( obj ) ) { 8729 8730 // Serialize array item. 8731 jQuery.each( obj, function( i, v ) { 8732 if ( traditional || rbracket.test( prefix ) ) { 8733 8734 // Treat each array item as a scalar. 8735 add( prefix, v ); 8736 8737 } else { 8738 8739 // Item is non-scalar (array or object), encode its numeric index. 8740 buildParams( 8741 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 8742 v, 8743 traditional, 8744 add 8745 ); 8746 } 8747 } ); 8748 8749 } else if ( !traditional && toType( obj ) === "object" ) { 8750 8751 // Serialize object item. 8752 for ( name in obj ) { 8753 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 8754 } 8755 8756 } else { 8757 8758 // Serialize scalar item. 8759 add( prefix, obj ); 8760 } 8761} 8762 8763// Serialize an array of form elements or a set of 8764// key/values into a query string 8765jQuery.param = function( a, traditional ) { 8766 var prefix, 8767 s = [], 8768 add = function( key, valueOrFunction ) { 8769 8770 // If value is a function, invoke it and use its return value 8771 var value = isFunction( valueOrFunction ) ? 8772 valueOrFunction() : 8773 valueOrFunction; 8774 8775 s[ s.length ] = encodeURIComponent( key ) + "=" + 8776 encodeURIComponent( value == null ? "" : value ); 8777 }; 8778 8779 if ( a == null ) { 8780 return ""; 8781 } 8782 8783 // If an array was passed in, assume that it is an array of form elements. 8784 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 8785 8786 // Serialize the form elements 8787 jQuery.each( a, function() { 8788 add( this.name, this.value ); 8789 } ); 8790 8791 } else { 8792 8793 // If traditional, encode the "old" way (the way 1.3.2 or older 8794 // did it), otherwise encode params recursively. 8795 for ( prefix in a ) { 8796 buildParams( prefix, a[ prefix ], traditional, add ); 8797 } 8798 } 8799 8800 // Return the resulting serialization 8801 return s.join( "&" ); 8802}; 8803 8804jQuery.fn.extend( { 8805 serialize: function() { 8806 return jQuery.param( this.serializeArray() ); 8807 }, 8808 serializeArray: function() { 8809 return this.map( function() { 8810 8811 // Can add propHook for "elements" to filter or add form elements 8812 var elements = jQuery.prop( this, "elements" ); 8813 return elements ? jQuery.makeArray( elements ) : this; 8814 } ).filter( function() { 8815 var type = this.type; 8816
vendor: 32,437 bytes, lines 8817-10070
8817 // Use .is( ":disabled" ) so that fieldset[disabled] works 8818 return this.name && !jQuery( this ).is( ":disabled" ) && 8819 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 8820 ( this.checked || !rcheckableType.test( type ) ); 8821 } ).map( function( _i, elem ) { 8822 var val = jQuery( this ).val(); 8823 8824 if ( val == null ) { 8825 return null; 8826 } 8827 8828 if ( Array.isArray( val ) ) { 8829 return jQuery.map( val, function( val ) { 8830 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 8831 } ); 8832 } 8833 8834 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 8835 } ).get(); 8836 } 8837} ); 8838 8839 8840var 8841 r20 = /%20/g, 8842 rhash = /#.*$/, 8843 rantiCache = /([?&])_=[^&]*/, 8844 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 8845 8846 // trac-7653, trac-8125, trac-8152: local protocol detection 8847 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 8848 rnoContent = /^(?:GET|HEAD)$/, 8849 rprotocol = /^\/\//, 8850 8851 /* Prefilters 8852 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 8853 * 2) These are called: 8854 * - BEFORE asking for a transport 8855 * - AFTER param serialization (s.data is a string if s.processData is true) 8856 * 3) key is the dataType 8857 * 4) the catchall symbol "*" can be used 8858 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 8859 */ 8860 prefilters = {}, 8861 8862 /* Transports bindings 8863 * 1) key is the dataType 8864 * 2) the catchall symbol "*" can be used 8865 * 3) selection will start with transport dataType and THEN go to "*" if needed 8866 */ 8867 transports = {}, 8868 8869 // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression 8870 allTypes = "*/".concat( "*" ), 8871 8872 // Anchor tag for parsing the document origin 8873 originAnchor = document.createElement( "a" ); 8874 8875originAnchor.href = location.href; 8876 8877// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 8878function addToPrefiltersOrTransports( structure ) { 8879 8880 // dataTypeExpression is optional and defaults to "*" 8881 return function( dataTypeExpression, func ) { 8882 8883 if ( typeof dataTypeExpression !== "string" ) { 8884 func = dataTypeExpression; 8885 dataTypeExpression = "*"; 8886 } 8887 8888 var dataType, 8889 i = 0, 8890 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 8891 8892 if ( isFunction( func ) ) { 8893 8894 // For each dataType in the dataTypeExpression 8895 while ( ( dataType = dataTypes[ i++ ] ) ) { 8896 8897 // Prepend if requested 8898 if ( dataType[ 0 ] === "+" ) { 8899 dataType = dataType.slice( 1 ) || "*"; 8900 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 8901 8902 // Otherwise append 8903 } else { 8904 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 8905 } 8906 } 8907 } 8908 }; 8909} 8910 8911// Base inspection function for prefilters and transports 8912function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 8913 8914 var inspected = {}, 8915 seekingTransport = ( structure === transports ); 8916 8917 function inspect( dataType ) { 8918 var selected; 8919 inspected[ dataType ] = true; 8920 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 8921 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 8922 if ( typeof dataTypeOrTransport === "string" && 8923 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 8924 8925 options.dataTypes.unshift( dataTypeOrTransport ); 8926 inspect( dataTypeOrTransport ); 8927 return false; 8928 } else if ( seekingTransport ) { 8929 return !( selected = dataTypeOrTransport ); 8930 } 8931 } ); 8932 return selected; 8933 } 8934 8935 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 8936} 8937 8938// A special extend for ajax options 8939// that takes "flat" options (not to be deep extended) 8940// Fixes trac-9887 8941function ajaxExtend( target, src ) { 8942 var key, deep, 8943 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 8944 8945 for ( key in src ) { 8946 if ( src[ key ] !== undefined ) { 8947 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 8948 } 8949 } 8950 if ( deep ) { 8951 jQuery.extend( true, target, deep ); 8952 } 8953 8954 return target; 8955} 8956 8957/* Handles responses to an ajax request: 8958 * - finds the right dataType (mediates between content-type and expected dataType) 8959 * - returns the corresponding response 8960 */ 8961function ajaxHandleResponses( s, jqXHR, responses ) { 8962 8963 var ct, type, finalDataType, firstDataType, 8964 contents = s.contents, 8965 dataTypes = s.dataTypes; 8966 8967 // Remove auto dataType and get content-type in the process 8968 while ( dataTypes[ 0 ] === "*" ) { 8969 dataTypes.shift(); 8970 if ( ct === undefined ) { 8971 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 8972 } 8973 } 8974 8975 // Check if we're dealing with a known content-type 8976 if ( ct ) { 8977 for ( type in contents ) { 8978 if ( contents[ type ] && contents[ type ].test( ct ) ) { 8979 dataTypes.unshift( type ); 8980 break; 8981 } 8982 } 8983 } 8984 8985 // Check to see if we have a response for the expected dataType 8986 if ( dataTypes[ 0 ] in responses ) { 8987 finalDataType = dataTypes[ 0 ]; 8988 } else { 8989 8990 // Try convertible dataTypes 8991 for ( type in responses ) { 8992 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 8993 finalDataType = type; 8994 break; 8995 } 8996 if ( !firstDataType ) { 8997 firstDataType = type; 8998 } 8999 } 9000 9001 // Or just use first one 9002 finalDataType = finalDataType || firstDataType; 9003 } 9004 9005 // If we found a dataType 9006 // We add the dataType to the list if needed 9007 // and return the corresponding response 9008 if ( finalDataType ) { 9009 if ( finalDataType !== dataTypes[ 0 ] ) { 9010 dataTypes.unshift( finalDataType ); 9011 } 9012 return responses[ finalDataType ]; 9013 } 9014} 9015 9016/* Chain conversions given the request and the original response 9017 * Also sets the responseXXX fields on the jqXHR instance 9018 */ 9019function ajaxConvert( s, response, jqXHR, isSuccess ) { 9020 var conv2, current, conv, tmp, prev, 9021 converters = {}, 9022 9023 // Work with a copy of dataTypes in case we need to modify it for conversion 9024 dataTypes = s.dataTypes.slice(); 9025 9026 // Create converters map with lowercased keys 9027 if ( dataTypes[ 1 ] ) { 9028 for ( conv in s.converters ) { 9029 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 9030 } 9031 } 9032 9033 current = dataTypes.shift(); 9034 9035 // Convert to each sequential dataType 9036 while ( current ) { 9037 9038 if ( s.responseFields[ current ] ) { 9039 jqXHR[ s.responseFields[ current ] ] = response; 9040 } 9041 9042 // Apply the dataFilter if provided 9043 if ( !prev && isSuccess && s.dataFilter ) { 9044 response = s.dataFilter( response, s.dataType ); 9045 } 9046 9047 prev = current; 9048 current = dataTypes.shift(); 9049 9050 if ( current ) { 9051 9052 // There's only work to do if current dataType is non-auto 9053 if ( current === "*" ) { 9054 9055 current = prev; 9056 9057 // Convert response if prev dataType is non-auto and differs from current 9058 } else if ( prev !== "*" && prev !== current ) { 9059 9060 // Seek a direct converter 9061 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 9062 9063 // If none found, seek a pair 9064 if ( !conv ) { 9065 for ( conv2 in converters ) { 9066 9067 // If conv2 outputs current 9068 tmp = conv2.split( " " ); 9069 if ( tmp[ 1 ] === current ) { 9070 9071 // If prev can be converted to accepted input 9072 conv = converters[ prev + " " + tmp[ 0 ] ] || 9073 converters[ "* " + tmp[ 0 ] ]; 9074 if ( conv ) { 9075 9076 // Condense equivalence converters 9077 if ( conv === true ) { 9078 conv = converters[ conv2 ]; 9079 9080 // Otherwise, insert the intermediate dataType 9081 } else if ( converters[ conv2 ] !== true ) { 9082 current = tmp[ 0 ]; 9083 dataTypes.unshift( tmp[ 1 ] ); 9084 } 9085 break; 9086 } 9087 } 9088 } 9089 } 9090 9091 // Apply converter (if not an equivalence) 9092 if ( conv !== true ) { 9093 9094 // Unless errors are allowed to bubble, catch and return them 9095 if ( conv && s.throws ) { 9096 response = conv( response ); 9097 } else { 9098 try { 9099 response = conv( response ); 9100 } catch ( e ) { 9101 return { 9102 state: "parsererror", 9103 error: conv ? e : "No conversion from " + prev + " to " + current 9104 }; 9105 } 9106 } 9107 } 9108 } 9109 } 9110 } 9111 9112 return { state: "success", data: response }; 9113} 9114 9115jQuery.extend( { 9116 9117 // Counter for holding the number of active queries 9118 active: 0, 9119 9120 // Last-Modified header cache for next request 9121 lastModified: {}, 9122 etag: {}, 9123 9124 ajaxSettings: { 9125 url: location.href, 9126 type: "GET", 9127 isLocal: rlocalProtocol.test( location.protocol ), 9128 global: true, 9129 processData: true, 9130 async: true, 9131 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 9132 9133 /* 9134 timeout: 0, 9135 data: null, 9136 dataType: null, 9137 username: null, 9138 password: null, 9139 cache: null, 9140 throws: false, 9141 traditional: false, 9142 headers: {}, 9143 */ 9144 9145 accepts: { 9146 "*": allTypes, 9147 text: "text/plain", 9148 html: "text/html", 9149 xml: "application/xml, text/xml", 9150 json: "application/json, text/javascript" 9151 }, 9152 9153 contents: { 9154 xml: /\bxml\b/, 9155 html: /\bhtml/, 9156 json: /\bjson\b/ 9157 }, 9158 9159 responseFields: { 9160 xml: "responseXML", 9161 text: "responseText", 9162 json: "responseJSON" 9163 }, 9164 9165 // Data converters 9166 // Keys separate source (or catchall "*") and destination types with a single space 9167 converters: { 9168 9169 // Convert anything to text 9170 "* text": String, 9171 9172 // Text to html (true = no transformation) 9173 "text html": true, 9174 9175 // Evaluate text as a json expression 9176 "text json": JSON.parse, 9177 9178 // Parse text as xml 9179 "text xml": jQuery.parseXML 9180 }, 9181 9182 // For options that shouldn't be deep extended: 9183 // you can add your own custom options here if 9184 // and when you create one that shouldn't be 9185 // deep extended (see ajaxExtend) 9186 flatOptions: { 9187 url: true, 9188 context: true 9189 } 9190 }, 9191 9192 // Creates a full fledged settings object into target 9193 // with both ajaxSettings and settings fields. 9194 // If target is omitted, writes into ajaxSettings. 9195 ajaxSetup: function( target, settings ) { 9196 return settings ? 9197 9198 // Building a settings object 9199 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 9200 9201 // Extending ajaxSettings 9202 ajaxExtend( jQuery.ajaxSettings, target ); 9203 }, 9204 9205 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 9206 ajaxTransport: addToPrefiltersOrTransports( transports ), 9207 9208 // Main method 9209 ajax: function( url, options ) { 9210 9211 // If url is an object, simulate pre-1.5 signature 9212 if ( typeof url === "object" ) { 9213 options = url; 9214 url = undefined; 9215 } 9216 9217 // Force options to be an object 9218 options = options || {}; 9219 9220 var transport, 9221 9222 // URL without anti-cache param 9223 cacheURL, 9224 9225 // Response headers 9226 responseHeadersString, 9227 responseHeaders, 9228 9229 // timeout handle 9230 timeoutTimer, 9231 9232 // Url cleanup var 9233 urlAnchor, 9234 9235 // Request state (becomes false upon send and true upon completion) 9236 completed, 9237 9238 // To know if global events are to be dispatched 9239 fireGlobals, 9240 9241 // Loop variable 9242 i, 9243 9244 // uncached part of the url 9245 uncached, 9246 9247 // Create the final options object 9248 s = jQuery.ajaxSetup( {}, options ), 9249 9250 // Callbacks context 9251 callbackContext = s.context || s, 9252 9253 // Context for global events is callbackContext if it is a DOM node or jQuery collection 9254 globalEventContext = s.context && 9255 ( callbackContext.nodeType || callbackContext.jquery ) ? 9256 jQuery( callbackContext ) : 9257 jQuery.event, 9258 9259 // Deferreds 9260 deferred = jQuery.Deferred(), 9261 completeDeferred = jQuery.Callbacks( "once memory" ), 9262 9263 // Status-dependent callbacks 9264 statusCode = s.statusCode || {}, 9265 9266 // Headers (they are sent all at once) 9267 requestHeaders = {}, 9268 requestHeadersNames = {}, 9269 9270 // Default abort message 9271 strAbort = "canceled", 9272 9273 // Fake xhr 9274 jqXHR = { 9275 readyState: 0, 9276 9277 // Builds headers hashtable if needed 9278 getResponseHeader: function( key ) { 9279 var match; 9280 if ( completed ) { 9281 if ( !responseHeaders ) { 9282 responseHeaders = {}; 9283 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 9284 responseHeaders[ match[ 1 ].toLowerCase() + " " ] = 9285 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 9286 .concat( match[ 2 ] ); 9287 } 9288 } 9289 match = responseHeaders[ key.toLowerCase() + " " ]; 9290 } 9291 return match == null ? null : match.join( ", " ); 9292 }, 9293 9294 // Raw string 9295 getAllResponseHeaders: function() { 9296 return completed ? responseHeadersString : null; 9297 }, 9298 9299 // Caches the header 9300 setRequestHeader: function( name, value ) { 9301 if ( completed == null ) { 9302 name = requestHeadersNames[ name.toLowerCase() ] = 9303 requestHeadersNames[ name.toLowerCase() ] || name; 9304 requestHeaders[ name ] = value; 9305 } 9306 return this; 9307 }, 9308 9309 // Overrides response content-type header 9310 overrideMimeType: function( type ) { 9311 if ( completed == null ) { 9312 s.mimeType = type; 9313 } 9314 return this; 9315 }, 9316 9317 // Status-dependent callbacks 9318 statusCode: function( map ) { 9319 var code; 9320 if ( map ) { 9321 if ( completed ) { 9322 9323 // Execute the appropriate callbacks 9324 jqXHR.always( map[ jqXHR.status ] ); 9325 } else { 9326 9327 // Lazy-add the new callbacks in a way that preserves old ones 9328 for ( code in map ) { 9329 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 9330 } 9331 } 9332 } 9333 return this; 9334 }, 9335 9336 // Cancel the request 9337 abort: function( statusText ) { 9338 var finalText = statusText || strAbort; 9339 if ( transport ) { 9340 transport.abort( finalText ); 9341 } 9342 done( 0, finalText ); 9343 return this; 9344 } 9345 }; 9346 9347 // Attach deferreds 9348 deferred.promise( jqXHR ); 9349 9350 // Add protocol if not provided (prefilters might expect it) 9351 // Handle falsy url in the settings object (trac-10093: consistency with old signature) 9352 // We also use the url parameter if available 9353 s.url = ( ( url || s.url || location.href ) + "" ) 9354 .replace( rprotocol, location.protocol + "//" ); 9355 9356 // Alias method option to type as per ticket trac-12004 9357 s.type = options.method || options.type || s.method || s.type; 9358 9359 // Extract dataTypes list 9360 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 9361 9362 // A cross-domain request is in order when the origin doesn't match the current origin. 9363 if ( s.crossDomain == null ) { 9364 urlAnchor = document.createElement( "a" ); 9365 9366 // Support: IE <=8 - 11, Edge 12 - 15 9367 // IE throws exception on accessing the href property if url is malformed, 9368 // e.g. http://example.com:80x/ 9369 try { 9370 urlAnchor.href = s.url; 9371 9372 // Support: IE <=8 - 11 only 9373 // Anchor's host property isn't correctly set when s.url is relative 9374 urlAnchor.href = urlAnchor.href; 9375 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 9376 urlAnchor.protocol + "//" + urlAnchor.host; 9377 } catch ( e ) { 9378 9379 // If there is an error parsing the URL, assume it is crossDomain, 9380 // it can be rejected by the transport if it is invalid 9381 s.crossDomain = true; 9382 } 9383 } 9384 9385 // Convert data if not already a string 9386 if ( s.data && s.processData && typeof s.data !== "string" ) { 9387 s.data = jQuery.param( s.data, s.traditional ); 9388 } 9389 9390 // Apply prefilters 9391 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 9392 9393 // If request was aborted inside a prefilter, stop there 9394 if ( completed ) { 9395 return jqXHR; 9396 } 9397 9398 // We can fire global events as of now if asked to 9399 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118) 9400 fireGlobals = jQuery.event && s.global; 9401 9402 // Watch for a new set of requests 9403 if ( fireGlobals && jQuery.active++ === 0 ) { 9404 jQuery.event.trigger( "ajaxStart" ); 9405 } 9406 9407 // Uppercase the type 9408 s.type = s.type.toUpperCase(); 9409 9410 // Determine if request has content 9411 s.hasContent = !rnoContent.test( s.type ); 9412 9413 // Save the URL in case we're toying with the If-Modified-Since 9414 // and/or If-None-Match header later on 9415 // Remove hash to simplify url manipulation 9416 cacheURL = s.url.replace( rhash, "" ); 9417 9418 // More options handling for requests with no content 9419 if ( !s.hasContent ) { 9420 9421 // Remember the hash so we can put it back 9422 uncached = s.url.slice( cacheURL.length ); 9423 9424 // If data is available and should be processed, append data to url 9425 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 9426 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 9427 9428 // trac-9682: remove data so that it's not used in an eventual retry 9429 delete s.data; 9430 } 9431 9432 // Add or update anti-cache param if needed 9433 if ( s.cache === false ) { 9434 cacheURL = cacheURL.replace( rantiCache, "$1" ); 9435 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + 9436 uncached; 9437 } 9438 9439 // Put hash and anti-cache on the URL that will be requested (gh-1732) 9440 s.url = cacheURL + uncached; 9441 9442 // Change '%20' to '+' if this is encoded form body content (gh-2658) 9443 } else if ( s.data && s.processData && 9444 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 9445 s.data = s.data.replace( r20, "+" ); 9446 } 9447 9448 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9449 if ( s.ifModified ) { 9450 if ( jQuery.lastModified[ cacheURL ] ) { 9451 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 9452 } 9453 if ( jQuery.etag[ cacheURL ] ) { 9454 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 9455 } 9456 } 9457 9458 // Set the correct header, if data is being sent 9459 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 9460 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 9461 } 9462 9463 // Set the Accepts header for the server, depending on the dataType 9464 jqXHR.setRequestHeader( 9465 "Accept", 9466 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 9467 s.accepts[ s.dataTypes[ 0 ] ] + 9468 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 9469 s.accepts[ "*" ] 9470 ); 9471 9472 // Check for headers option 9473 for ( i in s.headers ) { 9474 jqXHR.setRequestHeader( i, s.headers[ i ] ); 9475 } 9476 9477 // Allow custom headers/mimetypes and early abort 9478 if ( s.beforeSend && 9479 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 9480 9481 // Abort if not done already and return 9482 return jqXHR.abort(); 9483 } 9484 9485 // Aborting is no longer a cancellation 9486 strAbort = "abort"; 9487 9488 // Install callbacks on deferreds 9489 completeDeferred.add( s.complete ); 9490 jqXHR.done( s.success ); 9491 jqXHR.fail( s.error ); 9492 9493 // Get transport 9494 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 9495 9496 // If no transport, we auto-abort 9497 if ( !transport ) { 9498 done( -1, "No Transport" ); 9499 } else { 9500 jqXHR.readyState = 1; 9501 9502 // Send global event 9503 if ( fireGlobals ) { 9504 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 9505 } 9506 9507 // If request was aborted inside ajaxSend, stop there 9508 if ( completed ) { 9509 return jqXHR; 9510 } 9511 9512 // Timeout 9513 if ( s.async && s.timeout > 0 ) { 9514 timeoutTimer = window.setTimeout( function() { 9515 jqXHR.abort( "timeout" ); 9516 }, s.timeout ); 9517 } 9518 9519 try { 9520 completed = false; 9521 transport.send( requestHeaders, done ); 9522 } catch ( e ) { 9523 9524 // Rethrow post-completion exceptions 9525 if ( completed ) { 9526 throw e; 9527 } 9528 9529 // Propagate others as results 9530 done( -1, e ); 9531 } 9532 } 9533 9534 // Callback for when everything is done 9535 function done( status, nativeStatusText, responses, headers ) { 9536 var isSuccess, success, error, response, modified, 9537 statusText = nativeStatusText; 9538 9539 // Ignore repeat invocations 9540 if ( completed ) { 9541 return; 9542 } 9543 9544 completed = true; 9545 9546 // Clear timeout if it exists 9547 if ( timeoutTimer ) { 9548 window.clearTimeout( timeoutTimer ); 9549 } 9550 9551 // Dereference transport for early garbage collection 9552 // (no matter how long the jqXHR object will be used) 9553 transport = undefined; 9554 9555 // Cache response headers 9556 responseHeadersString = headers || ""; 9557 9558 // Set readyState 9559 jqXHR.readyState = status > 0 ? 4 : 0; 9560 9561 // Determine if successful 9562 isSuccess = status >= 200 && status < 300 || status === 304; 9563 9564 // Get response data 9565 if ( responses ) { 9566 response = ajaxHandleResponses( s, jqXHR, responses ); 9567 } 9568 9569 // Use a noop converter for missing script but not if jsonp 9570 if ( !isSuccess && 9571 jQuery.inArray( "script", s.dataTypes ) > -1 && 9572 jQuery.inArray( "json", s.dataTypes ) < 0 ) { 9573 s.converters[ "text script" ] = function() {}; 9574 } 9575 9576 // Convert no matter what (that way responseXXX fields are always set) 9577 response = ajaxConvert( s, response, jqXHR, isSuccess ); 9578 9579 // If successful, handle type chaining 9580 if ( isSuccess ) { 9581 9582 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9583 if ( s.ifModified ) { 9584 modified = jqXHR.getResponseHeader( "Last-Modified" ); 9585 if ( modified ) { 9586 jQuery.lastModified[ cacheURL ] = modified; 9587 } 9588 modified = jqXHR.getResponseHeader( "etag" ); 9589 if ( modified ) { 9590 jQuery.etag[ cacheURL ] = modified; 9591 } 9592 } 9593 9594 // if no content 9595 if ( status === 204 || s.type === "HEAD" ) { 9596 statusText = "nocontent"; 9597 9598 // if not modified 9599 } else if ( status === 304 ) { 9600 statusText = "notmodified"; 9601 9602 // If we have data, let's convert it 9603 } else { 9604 statusText = response.state; 9605 success = response.data; 9606 error = response.error; 9607 isSuccess = !error; 9608 } 9609 } else { 9610 9611 // Extract error from statusText and normalize for non-aborts 9612 error = statusText; 9613 if ( status || !statusText ) { 9614 statusText = "error"; 9615 if ( status < 0 ) { 9616 status = 0; 9617 } 9618 } 9619 } 9620 9621 // Set data for the fake xhr object 9622 jqXHR.status = status; 9623 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 9624 9625 // Success/Error 9626 if ( isSuccess ) { 9627 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 9628 } else { 9629 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 9630 } 9631 9632 // Status-dependent callbacks 9633 jqXHR.statusCode( statusCode ); 9634 statusCode = undefined; 9635 9636 if ( fireGlobals ) { 9637 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 9638 [ jqXHR, s, isSuccess ? success : error ] ); 9639 } 9640 9641 // Complete 9642 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 9643 9644 if ( fireGlobals ) { 9645 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 9646 9647 // Handle the global AJAX counter 9648 if ( !( --jQuery.active ) ) { 9649 jQuery.event.trigger( "ajaxStop" ); 9650 } 9651 } 9652 } 9653 9654 return jqXHR; 9655 }, 9656 9657 getJSON: function( url, data, callback ) { 9658 return jQuery.get( url, data, callback, "json" ); 9659 }, 9660 9661 getScript: function( url, callback ) { 9662 return jQuery.get( url, undefined, callback, "script" ); 9663 } 9664} ); 9665 9666jQuery.each( [ "get", "post" ], function( _i, method ) { 9667 jQuery[ method ] = function( url, data, callback, type ) { 9668 9669 // Shift arguments if data argument was omitted 9670 if ( isFunction( data ) ) { 9671 type = type || callback; 9672 callback = data; 9673 data = undefined; 9674 } 9675 9676 // The url can be an options object (which then must have .url) 9677 return jQuery.ajax( jQuery.extend( { 9678 url: url, 9679 type: method, 9680 dataType: type, 9681 data: data, 9682 success: callback 9683 }, jQuery.isPlainObject( url ) && url ) ); 9684 }; 9685} ); 9686 9687jQuery.ajaxPrefilter( function( s ) { 9688 var i; 9689 for ( i in s.headers ) { 9690 if ( i.toLowerCase() === "content-type" ) { 9691 s.contentType = s.headers[ i ] || ""; 9692 } 9693 } 9694} ); 9695 9696 9697jQuery._evalUrl = function( url, options, doc ) { 9698 return jQuery.ajax( { 9699 url: url, 9700 9701 // Make this explicit, since user can override this through ajaxSetup (trac-11264) 9702 type: "GET", 9703 dataType: "script", 9704 cache: true, 9705 async: false, 9706 global: false, 9707 9708 // Only evaluate the response if it is successful (gh-4126) 9709 // dataFilter is not invoked for failure responses, so using it instead 9710 // of the default converter is kludgy but it works. 9711 converters: { 9712 "text script": function() {} 9713 }, 9714 dataFilter: function( response ) { 9715 jQuery.globalEval( response, options, doc ); 9716 } 9717 } ); 9718}; 9719 9720 9721jQuery.fn.extend( { 9722 wrapAll: function( html ) { 9723 var wrap; 9724 9725 if ( this[ 0 ] ) { 9726 if ( isFunction( html ) ) { 9727 html = html.call( this[ 0 ] ); 9728 } 9729 9730 // The elements to wrap the target around 9731 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 9732 9733 if ( this[ 0 ].parentNode ) { 9734 wrap.insertBefore( this[ 0 ] ); 9735 } 9736 9737 wrap.map( function() { 9738 var elem = this; 9739 9740 while ( elem.firstElementChild ) { 9741 elem = elem.firstElementChild; 9742 } 9743 9744 return elem; 9745 } ).append( this ); 9746 } 9747 9748 return this; 9749 }, 9750 9751 wrapInner: function( html ) { 9752 if ( isFunction( html ) ) { 9753 return this.each( function( i ) { 9754 jQuery( this ).wrapInner( html.call( this, i ) ); 9755 } ); 9756 } 9757 9758 return this.each( function() { 9759 var self = jQuery( this ), 9760 contents = self.contents(); 9761 9762 if ( contents.length ) { 9763 contents.wrapAll( html ); 9764 9765 } else { 9766 self.append( html ); 9767 } 9768 } ); 9769 }, 9770 9771 wrap: function( html ) { 9772 var htmlIsFunction = isFunction( html ); 9773 9774 return this.each( function( i ) { 9775 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 9776 } ); 9777 }, 9778 9779 unwrap: function( selector ) { 9780 this.parent( selector ).not( "body" ).each( function() { 9781 jQuery( this ).replaceWith( this.childNodes ); 9782 } ); 9783 return this; 9784 } 9785} ); 9786 9787 9788jQuery.expr.pseudos.hidden = function( elem ) { 9789 return !jQuery.expr.pseudos.visible( elem ); 9790}; 9791jQuery.expr.pseudos.visible = function( elem ) { 9792 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 9793}; 9794 9795 9796 9797 9798jQuery.ajaxSettings.xhr = function() { 9799 try { 9800 return new window.XMLHttpRequest(); 9801 } catch ( e ) {} 9802}; 9803 9804var xhrSuccessStatus = { 9805 9806 // File protocol always yields status code 0, assume 200 9807 0: 200, 9808 9809 // Support: IE <=9 only 9810 // trac-1450: sometimes IE returns 1223 when it should be 204 9811 1223: 204 9812 }, 9813 xhrSupported = jQuery.ajaxSettings.xhr(); 9814 9815support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 9816support.ajax = xhrSupported = !!xhrSupported; 9817 9818jQuery.ajaxTransport( function( options ) { 9819 var callback, errorCallback; 9820 9821 // Cross domain only allowed if supported through XMLHttpRequest 9822 if ( support.cors || xhrSupported && !options.crossDomain ) { 9823 return { 9824 send: function( headers, complete ) { 9825 var i, 9826 xhr = options.xhr(); 9827 9828 xhr.open( 9829 options.type, 9830 options.url, 9831 options.async, 9832 options.username, 9833 options.password 9834 ); 9835 9836 // Apply custom fields if provided 9837 if ( options.xhrFields ) { 9838 for ( i in options.xhrFields ) { 9839 xhr[ i ] = options.xhrFields[ i ]; 9840 } 9841 } 9842 9843 // Override mime type if needed 9844 if ( options.mimeType && xhr.overrideMimeType ) { 9845 xhr.overrideMimeType( options.mimeType ); 9846 } 9847 9848 // X-Requested-With header 9849 // For cross-domain requests, seeing as conditions for a preflight are 9850 // akin to a jigsaw puzzle, we simply never set it to be sure. 9851 // (it can always be set on a per-request basis or even using ajaxSetup) 9852 // For same-domain requests, won't change header if already provided. 9853 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 9854 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 9855 } 9856 9857 // Set headers 9858 for ( i in headers ) { 9859 xhr.setRequestHeader( i, headers[ i ] ); 9860 } 9861 9862 // Callback 9863 callback = function( type ) { 9864 return function() { 9865 if ( callback ) { 9866 callback = errorCallback = xhr.onload = 9867 xhr.onerror = xhr.onabort = xhr.ontimeout = 9868 xhr.onreadystatechange = null; 9869 9870 if ( type === "abort" ) { 9871 xhr.abort(); 9872 } else if ( type === "error" ) { 9873 9874 // Support: IE <=9 only 9875 // On a manual native abort, IE9 throws 9876 // errors on any property access that is not readyState 9877 if ( typeof xhr.status !== "number" ) { 9878 complete( 0, "error" ); 9879 } else { 9880 complete( 9881 9882 // File: protocol always yields status 0; see trac-8605, trac-14207 9883 xhr.status, 9884 xhr.statusText 9885 ); 9886 } 9887 } else { 9888 complete( 9889 xhrSuccessStatus[ xhr.status ] || xhr.status, 9890 xhr.statusText, 9891 9892 // Support: IE <=9 only 9893 // IE9 has no XHR2 but throws on binary (trac-11426) 9894 // For XHR2 non-text, let the caller handle it (gh-2498) 9895 ( xhr.responseType || "text" ) !== "text" || 9896 typeof xhr.responseText !== "string" ? 9897 { binary: xhr.response } : 9898 { text: xhr.responseText }, 9899 xhr.getAllResponseHeaders() 9900 ); 9901 } 9902 } 9903 }; 9904 }; 9905 9906 // Listen to events 9907 xhr.onload = callback(); 9908 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 9909 9910 // Support: IE 9 only 9911 // Use onreadystatechange to replace onabort 9912 // to handle uncaught aborts 9913 if ( xhr.onabort !== undefined ) { 9914 xhr.onabort = errorCallback; 9915 } else { 9916 xhr.onreadystatechange = function() { 9917 9918 // Check readyState before timeout as it changes 9919 if ( xhr.readyState === 4 ) { 9920 9921 // Allow onerror to be called first, 9922 // but that will not handle a native abort 9923 // Also, save errorCallback to a variable 9924 // as xhr.onerror cannot be accessed 9925 window.setTimeout( function() { 9926 if ( callback ) { 9927 errorCallback(); 9928 } 9929 } ); 9930 } 9931 }; 9932 } 9933 9934 // Create the abort callback 9935 callback = callback( "abort" ); 9936 9937 try { 9938 9939 // Do send the request (this may raise an exception) 9940 xhr.send( options.hasContent && options.data || null ); 9941 } catch ( e ) { 9942 9943 // trac-14683: Only rethrow if this hasn't been notified as an error yet 9944 if ( callback ) { 9945 throw e; 9946 } 9947 } 9948 }, 9949 9950 abort: function() { 9951 if ( callback ) { 9952 callback(); 9953 } 9954 } 9955 }; 9956 } 9957} ); 9958 9959 9960 9961 9962// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 9963jQuery.ajaxPrefilter( function( s ) { 9964 if ( s.crossDomain ) { 9965 s.contents.script = false; 9966 } 9967} ); 9968 9969// Install script dataType 9970jQuery.ajaxSetup( { 9971 accepts: { 9972 script: "text/javascript, application/javascript, " + 9973 "application/ecmascript, application/x-ecmascript" 9974 }, 9975 contents: { 9976 script: /\b(?:java|ecma)script\b/ 9977 }, 9978 converters: { 9979 "text script": function( text ) { 9980 jQuery.globalEval( text ); 9981 return text; 9982 } 9983 } 9984} ); 9985 9986// Handle cache's special case and crossDomain 9987jQuery.ajaxPrefilter( "script", function( s ) { 9988 if ( s.cache === undefined ) { 9989 s.cache = false; 9990 } 9991 if ( s.crossDomain ) { 9992 s.type = "GET"; 9993 } 9994} ); 9995 9996// Bind script tag hack transport 9997jQuery.ajaxTransport( "script", function( s ) { 9998 9999 // This transport only deals with cross domain or forced-by-attrs requests 10000 if ( s.crossDomain || s.scriptAttrs ) { 10001 var script, callback; 10002 return { 10003 send: function( _, complete ) { 10004 script = jQuery( "<script>" ) 10005 .attr( s.scriptAttrs || {} ) 10006 .prop( { charset: s.scriptCharset, src: s.url } ) 10007 .on( "load error", callback = function( evt ) { 10008 script.remove(); 10009 callback = null; 10010 if ( evt ) { 10011 complete( evt.type === "error" ? 404 : 200, evt.type ); 10012 } 10013 } ); 10014 10015 // Use native DOM manipulation to avoid our domManip AJAX trickery 10016 document.head.appendChild( script[ 0 ] ); 10017 }, 10018 abort: function() { 10019 if ( callback ) { 10020 callback(); 10021 } 10022 } 10023 }; 10024 } 10025} ); 10026 10027 10028 10029 10030var oldCallbacks = [], 10031 rjsonp = /(=)\?(?=&|$)|\?\?/; 10032 10033// Default jsonp settings 10034jQuery.ajaxSetup( { 10035 jsonp: "callback", 10036 jsonpCallback: function() { 10037 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 10038 this[ callback ] = true; 10039 return callback; 10040 } 10041} ); 10042 10043// Detect, normalize options and install callbacks for jsonp requests 10044jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 10045 10046 var callbackName, overwritten, responseContainer, 10047 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 10048 "url" : 10049 typeof s.data === "string" && 10050 ( s.contentType || "" ) 10051 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 10052 rjsonp.test( s.data ) && "data" 10053 ); 10054 10055 // Handle iff the expected data type is "jsonp" or we have a parameter to set 10056 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 10057 10058 // Get callback name, remembering preexisting value associated with it 10059 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 10060 s.jsonpCallback() : 10061 s.jsonpCallback; 10062 10063 // Insert callback into url or form data 10064 if ( jsonProp ) { 10065 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 10066 } else if ( s.jsonp !== false ) { 10067 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 10068 } 10069 10070 // Use data converter to retrieve json after script execution
vendor: 8,362 bytes, lines 10071-10382
10071 s.converters[ "script json" ] = function() { 10072 if ( !responseContainer ) { 10073 jQuery.error( callbackName + " was not called" ); 10074 } 10075 return responseContainer[ 0 ]; 10076 }; 10077 10078 // Force json dataType 10079 s.dataTypes[ 0 ] = "json"; 10080 10081 // Install callback 10082 overwritten = window[ callbackName ]; 10083 window[ callbackName ] = function() { 10084 responseContainer = arguments; 10085 }; 10086 10087 // Clean-up function (fires after converters) 10088 jqXHR.always( function() { 10089 10090 // If previous value didn't exist - remove it 10091 if ( overwritten === undefined ) { 10092 jQuery( window ).removeProp( callbackName ); 10093 10094 // Otherwise restore preexisting value 10095 } else { 10096 window[ callbackName ] = overwritten; 10097 } 10098 10099 // Save back as free 10100 if ( s[ callbackName ] ) { 10101 10102 // Make sure that re-using the options doesn't screw things around 10103 s.jsonpCallback = originalSettings.jsonpCallback; 10104 10105 // Save the callback name for future use 10106 oldCallbacks.push( callbackName ); 10107 } 10108 10109 // Call if it was a function and we have a response 10110 if ( responseContainer && isFunction( overwritten ) ) { 10111 overwritten( responseContainer[ 0 ] ); 10112 } 10113 10114 responseContainer = overwritten = undefined; 10115 } ); 10116 10117 // Delegate to script 10118 return "script"; 10119 } 10120} ); 10121 10122 10123 10124 10125// Support: Safari 8 only 10126// In Safari 8 documents created via document.implementation.createHTMLDocument 10127// collapse sibling forms: the second one becomes a child of the first one. 10128// Because of that, this security measure has to be disabled in Safari 8. 10129// https://bugs.webkit.org/show_bug.cgi?id=137337 10130support.createHTMLDocument = ( function() { 10131 var body = document.implementation.createHTMLDocument( "" ).body; 10132 body.innerHTML = "<form></form><form></form>"; 10133 return body.childNodes.length === 2; 10134} )(); 10135 10136 10137// Argument "data" should be string of html 10138// context (optional): If specified, the fragment will be created in this context, 10139// defaults to document 10140// keepScripts (optional): If true, will include scripts passed in the html string 10141jQuery.parseHTML = function( data, context, keepScripts ) { 10142 if ( typeof data !== "string" ) { 10143 return []; 10144 } 10145 if ( typeof context === "boolean" ) { 10146 keepScripts = context; 10147 context = false; 10148 } 10149 10150 var base, parsed, scripts; 10151 10152 if ( !context ) { 10153 10154 // Stop scripts or inline event handlers from being executed immediately 10155 // by using document.implementation 10156 if ( support.createHTMLDocument ) { 10157 context = document.implementation.createHTMLDocument( "" ); 10158 10159 // Set the base href for the created document 10160 // so any parsed elements with URLs 10161 // are based on the document's URL (gh-2965) 10162 base = context.createElement( "base" ); 10163 base.href = document.location.href; 10164 context.head.appendChild( base ); 10165 } else { 10166 context = document; 10167 } 10168 } 10169 10170 parsed = rsingleTag.exec( data ); 10171 scripts = !keepScripts && []; 10172 10173 // Single tag 10174 if ( parsed ) { 10175 return [ context.createElement( parsed[ 1 ] ) ]; 10176 } 10177 10178 parsed = buildFragment( [ data ], context, scripts ); 10179 10180 if ( scripts && scripts.length ) { 10181 jQuery( scripts ).remove(); 10182 } 10183 10184 return jQuery.merge( [], parsed.childNodes ); 10185}; 10186 10187 10188/** 10189 * Load a url into a page 10190 */ 10191jQuery.fn.load = function( url, params, callback ) { 10192 var selector, type, response, 10193 self = this, 10194 off = url.indexOf( " " ); 10195 10196 if ( off > -1 ) { 10197 selector = stripAndCollapse( url.slice( off ) ); 10198 url = url.slice( 0, off ); 10199 } 10200 10201 // If it's a function 10202 if ( isFunction( params ) ) { 10203 10204 // We assume that it's the callback 10205 callback = params; 10206 params = undefined; 10207 10208 // Otherwise, build a param string 10209 } else if ( params && typeof params === "object" ) { 10210 type = "POST"; 10211 } 10212 10213 // If we have elements to modify, make the request 10214 if ( self.length > 0 ) { 10215 jQuery.ajax( { 10216 url: url, 10217 10218 // If "type" variable is undefined, then "GET" method will be used. 10219 // Make value of this field explicit since 10220 // user can override it through ajaxSetup method 10221 type: type || "GET", 10222 dataType: "html", 10223 data: params 10224 } ).done( function( responseText ) { 10225 10226 // Save response for use in complete callback 10227 response = arguments; 10228 10229 self.html( selector ? 10230 10231 // If a selector was specified, locate the right elements in a dummy div 10232 // Exclude scripts to avoid IE 'Permission Denied' errors 10233 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 10234 10235 // Otherwise use the full result 10236 responseText ); 10237 10238 // If the request succeeds, this function gets "data", "status", "jqXHR" 10239 // but they are ignored because response was set above. 10240 // If it fails, this function gets "jqXHR", "status", "error" 10241 } ).always( callback && function( jqXHR, status ) { 10242 self.each( function() { 10243 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 10244 } ); 10245 } ); 10246 } 10247 10248 return this; 10249}; 10250 10251 10252 10253 10254jQuery.expr.pseudos.animated = function( elem ) { 10255 return jQuery.grep( jQuery.timers, function( fn ) { 10256 return elem === fn.elem; 10257 } ).length; 10258}; 10259 10260 10261 10262 10263jQuery.offset = { 10264 setOffset: function( elem, options, i ) { 10265 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 10266 position = jQuery.css( elem, "position" ), 10267 curElem = jQuery( elem ), 10268 props = {}; 10269 10270 // Set position first, in-case top/left are set even on static elem 10271 if ( position === "static" ) { 10272 elem.style.position = "relative"; 10273 } 10274 10275 curOffset = curElem.offset(); 10276 curCSSTop = jQuery.css( elem, "top" ); 10277 curCSSLeft = jQuery.css( elem, "left" ); 10278 calculatePosition = ( position === "absolute" || position === "fixed" ) && 10279 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 10280 10281 // Need to be able to calculate position if either 10282 // top or left is auto and position is either absolute or fixed 10283 if ( calculatePosition ) { 10284 curPosition = curElem.position(); 10285 curTop = curPosition.top; 10286 curLeft = curPosition.left; 10287 10288 } else { 10289 curTop = parseFloat( curCSSTop ) || 0; 10290 curLeft = parseFloat( curCSSLeft ) || 0; 10291 } 10292 10293 if ( isFunction( options ) ) { 10294 10295 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 10296 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 10297 } 10298 10299 if ( options.top != null ) { 10300 props.top = ( options.top - curOffset.top ) + curTop; 10301 } 10302 if ( options.left != null ) { 10303 props.left = ( options.left - curOffset.left ) + curLeft; 10304 } 10305 10306 if ( "using" in options ) { 10307 options.using.call( elem, props ); 10308 10309 } else { 10310 curElem.css( props ); 10311 } 10312 } 10313}; 10314 10315jQuery.fn.extend( { 10316 10317 // offset() relates an element's border box to the document origin 10318 offset: function( options ) { 10319 10320 // Preserve chaining for setter 10321 if ( arguments.length ) { 10322 return options === undefined ? 10323 this : 10324 this.each( function( i ) { 10325 jQuery.offset.setOffset( this, options, i ); 10326 } ); 10327 } 10328 10329 var rect, win, 10330 elem = this[ 0 ]; 10331 10332 if ( !elem ) { 10333 return; 10334 } 10335 10336 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 10337 // Support: IE <=11 only 10338 // Running getBoundingClientRect on a 10339 // disconnected node in IE throws an error 10340 if ( !elem.getClientRects().length ) { 10341 return { top: 0, left: 0 }; 10342 } 10343 10344 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 10345 rect = elem.getBoundingClientRect(); 10346 win = elem.ownerDocument.defaultView; 10347 return { 10348 top: rect.top + win.pageYOffset, 10349 left: rect.left + win.pageXOffset 10350 }; 10351 }, 10352 10353 // position() relates an element's margin box to its offset parent's padding box 10354 // This corresponds to the behavior of CSS absolute positioning 10355 position: function() { 10356 if ( !this[ 0 ] ) { 10357 return; 10358 } 10359 10360 var offsetParent, offset, doc, 10361 elem = this[ 0 ], 10362 parentOffset = { top: 0, left: 0 }; 10363 10364 // position:fixed elements are offset from the viewport, which itself always has zero offset 10365 if ( jQuery.css( elem, "position" ) === "fixed" ) { 10366 10367 // Assume position:fixed implies availability of getBoundingClientRect 10368 offset = elem.getBoundingClientRect(); 10369 10370 } else { 10371 offset = this.offset(); 10372 10373 // Account for the *real* offset parent, which can be the document or its root element 10374 // when a statically positioned element is identified 10375 doc = elem.ownerDocument; 10376 offsetParent = elem.offsetParent || doc.documentElement; 10377 while ( offsetParent && 10378 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 10379 jQuery.css( offsetParent, "position" ) === "static" ) { 10380 10381 offsetParent = offsetParent.parentNode; 10382 }
vendor: 8,818 bytes, lines 10383-10676
10383 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 10384 10385 // Incorporate borders into its offset, since they are outside its content origin 10386 parentOffset = jQuery( offsetParent ).offset(); 10387 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 10388 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 10389 } 10390 } 10391 10392 // Subtract parent offsets and element margins 10393 return { 10394 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 10395 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 10396 }; 10397 }, 10398 10399 // This method will return documentElement in the following cases: 10400 // 1) For the element inside the iframe without offsetParent, this method will return 10401 // documentElement of the parent window 10402 // 2) For the hidden or detached element 10403 // 3) For body or html element, i.e. in case of the html node - it will return itself 10404 // 10405 // but those exceptions were never presented as a real life use-cases 10406 // and might be considered as more preferable results. 10407 // 10408 // This logic, however, is not guaranteed and can change at any point in the future 10409 offsetParent: function() { 10410 return this.map( function() { 10411 var offsetParent = this.offsetParent; 10412 10413 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 10414 offsetParent = offsetParent.offsetParent; 10415 } 10416 10417 return offsetParent || documentElement; 10418 } ); 10419 } 10420} ); 10421 10422// Create scrollLeft and scrollTop methods 10423jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 10424 var top = "pageYOffset" === prop; 10425 10426 jQuery.fn[ method ] = function( val ) { 10427 return access( this, function( elem, method, val ) { 10428 10429 // Coalesce documents and windows 10430 var win; 10431 if ( isWindow( elem ) ) { 10432 win = elem; 10433 } else if ( elem.nodeType === 9 ) { 10434 win = elem.defaultView; 10435 } 10436 10437 if ( val === undefined ) { 10438 return win ? win[ prop ] : elem[ method ]; 10439 } 10440 10441 if ( win ) { 10442 win.scrollTo( 10443 !top ? val : win.pageXOffset, 10444 top ? val : win.pageYOffset 10445 ); 10446 10447 } else { 10448 elem[ method ] = val; 10449 } 10450 }, method, val, arguments.length ); 10451 }; 10452} ); 10453 10454// Support: Safari <=7 - 9.1, Chrome <=37 - 49 10455// Add the top/left cssHooks using jQuery.fn.position 10456// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 10457// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 10458// getComputedStyle returns percent when specified for top/left/bottom/right; 10459// rather than make the css module depend on the offset module, just check for it here 10460jQuery.each( [ "top", "left" ], function( _i, prop ) { 10461 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 10462 function( elem, computed ) { 10463 if ( computed ) { 10464 computed = curCSS( elem, prop ); 10465 10466 // If curCSS returns percentage, fallback to offset 10467 return rnumnonpx.test( computed ) ? 10468 jQuery( elem ).position()[ prop ] + "px" : 10469 computed; 10470 } 10471 } 10472 ); 10473} ); 10474 10475 10476// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 10477jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 10478 jQuery.each( { 10479 padding: "inner" + name, 10480 content: type, 10481 "": "outer" + name 10482 }, function( defaultExtra, funcName ) { 10483 10484 // Margin is only for outerHeight, outerWidth 10485 jQuery.fn[ funcName ] = function( margin, value ) { 10486 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 10487 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 10488 10489 return access( this, function( elem, type, value ) { 10490 var doc; 10491 10492 if ( isWindow( elem ) ) { 10493 10494 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 10495 return funcName.indexOf( "outer" ) === 0 ? 10496 elem[ "inner" + name ] : 10497 elem.document.documentElement[ "client" + name ]; 10498 } 10499 10500 // Get document width or height 10501 if ( elem.nodeType === 9 ) { 10502 doc = elem.documentElement; 10503 10504 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 10505 // whichever is greatest 10506 return Math.max( 10507 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 10508 elem.body[ "offset" + name ], doc[ "offset" + name ], 10509 doc[ "client" + name ] 10510 ); 10511 } 10512 10513 return value === undefined ? 10514 10515 // Get width or height on the element, requesting but not forcing parseFloat 10516 jQuery.css( elem, type, extra ) : 10517 10518 // Set width or height on the element 10519 jQuery.style( elem, type, value, extra ); 10520 }, type, chainable ? margin : undefined, chainable ); 10521 }; 10522 } ); 10523} ); 10524 10525 10526jQuery.each( [ 10527 "ajaxStart", 10528 "ajaxStop", 10529 "ajaxComplete", 10530 "ajaxError", 10531 "ajaxSuccess", 10532 "ajaxSend" 10533], function( _i, type ) { 10534 jQuery.fn[ type ] = function( fn ) { 10535 return this.on( type, fn ); 10536 }; 10537} ); 10538 10539 10540 10541 10542jQuery.fn.extend( { 10543 10544 bind: function( types, data, fn ) { 10545 return this.on( types, null, data, fn ); 10546 }, 10547 unbind: function( types, fn ) { 10548 return this.off( types, null, fn ); 10549 }, 10550 10551 delegate: function( selector, types, data, fn ) { 10552 return this.on( types, selector, data, fn ); 10553 }, 10554 undelegate: function( selector, types, fn ) { 10555 10556 // ( namespace ) or ( selector, types [, fn] ) 10557 return arguments.length === 1 ? 10558 this.off( selector, "**" ) : 10559 this.off( types, selector || "**", fn ); 10560 }, 10561 10562 hover: function( fnOver, fnOut ) { 10563 return this 10564 .on( "mouseenter", fnOver ) 10565 .on( "mouseleave", fnOut || fnOver ); 10566 } 10567} ); 10568 10569jQuery.each( 10570 ( "blur focus focusin focusout resize scroll click dblclick " + 10571 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 10572 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 10573 function( _i, name ) { 10574 10575 // Handle event binding 10576 jQuery.fn[ name ] = function( data, fn ) { 10577 return arguments.length > 0 ? 10578 this.on( name, null, data, fn ) : 10579 this.trigger( name ); 10580 }; 10581 } 10582); 10583 10584 10585 10586 10587// Support: Android <=4.0 only 10588// Make sure we trim BOM and NBSP 10589// Require that the "whitespace run" starts from a non-whitespace 10590// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position. 10591var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g; 10592 10593// Bind a function to a context, optionally partially applying any 10594// arguments. 10595// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 10596// However, it is not slated for removal any time soon 10597jQuery.proxy = function( fn, context ) { 10598 var tmp, args, proxy; 10599 10600 if ( typeof context === "string" ) { 10601 tmp = fn[ context ]; 10602 context = fn; 10603 fn = tmp; 10604 } 10605 10606 // Quick check to determine if target is callable, in the spec 10607 // this throws a TypeError, but we will just return undefined. 10608 if ( !isFunction( fn ) ) { 10609 return undefined; 10610 } 10611 10612 // Simulated bind 10613 args = slice.call( arguments, 2 ); 10614 proxy = function() { 10615 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 10616 }; 10617 10618 // Set the guid of unique handler to the same of original handler, so it can be removed 10619 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 10620 10621 return proxy; 10622}; 10623 10624jQuery.holdReady = function( hold ) { 10625 if ( hold ) { 10626 jQuery.readyWait++; 10627 } else { 10628 jQuery.ready( true ); 10629 } 10630}; 10631jQuery.isArray = Array.isArray; 10632jQuery.parseJSON = JSON.parse; 10633jQuery.nodeName = nodeName; 10634jQuery.isFunction = isFunction; 10635jQuery.isWindow = isWindow; 10636jQuery.camelCase = camelCase; 10637jQuery.type = toType; 10638 10639jQuery.now = Date.now; 10640 10641jQuery.isNumeric = function( obj ) { 10642 10643 // As of jQuery 3.0, isNumeric is limited to 10644 // strings and numbers (primitives or objects) 10645 // that can be coerced to finite numbers (gh-2662) 10646 var type = jQuery.type( obj ); 10647 return ( type === "number" || type === "string" ) && 10648 10649 // parseFloat NaNs numeric-cast false positives ("") 10650 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 10651 // subtraction forces infinities to NaN 10652 !isNaN( obj - parseFloat( obj ) ); 10653}; 10654 10655jQuery.trim = function( text ) { 10656 return text == null ? 10657 "" : 10658 ( text + "" ).replace( rtrim, "$1" ); 10659}; 10660 10661 10662 10663// Register as a named AMD module, since jQuery can be concatenated with other 10664// files that may use define, but not via a proper concatenation script that 10665// understands anonymous AMD modules. A named AMD is safest and most robust 10666// way to register. Lowercase jquery is used because AMD module names are 10667// derived from file names, and jQuery is normally delivered in a lowercase 10668// file name. Do this after creating the global so that if an AMD module wants 10669// to call noConflict to hide this version of jQuery, it will work. 10670 10671// Note that for maximum portability, libraries that are not jQuery should 10672// declare themselves as anonymous modules, and avoid setting a global if an 10673// AMD loader is present. jQuery is a special case. For more information, see 10674// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 10675 10676if ( t
10676ypeof define === "function" && define.amd ) { 10677 define( "jquery", [], function() { 10678 return jQuery; 10679 } ); 10680} 10681 10682 10683 10684 10685var 10686 10687 // Map over jQuery in case of overwrite 10688 _jQuery = window.jQuery, 10689 10690 // Map over the $ in case of overwrite 10691 _$ = window.$; 10692 10693jQuery.noConflict = function( deep ) { 10694 if ( window.$ === jQuery ) { 10695 window.$ = _$; 10696 } 10697 10698 if ( deep && window.jQuery === jQuery ) { 10699 window.jQuery = _jQuery; 10700 } 10701 10702 return jQuery; 10703}; 10704 10705// Expose jQuery and $ identifiers, even in AMD 10706// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557) 10707// and CommonJS for browser emulators (trac-13566) 10708if ( typeof noGlobal === "undefined" ) { 10709 window.jQuery = window.$ = jQuery; 10710} 10711 10712 10713 10714 10715return jQuery; 10716} ); 10717 10718;/*! jQuery v3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween | (c) OpenJS Foundation and other contributors | jquery.org/license */ 10719!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)}
vendor: 22,409 bytes, line 10719
10719,s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},m=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||m).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}ce.fn=ce.prototype={jquery:t,constructor:ce,length:0,toArray:function(){return ae.call(this)},get:function(e){return null==e?ae.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=ce.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return ce.each(this,e)},map:function(n){return this.pushStack(ce.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(ae.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ce.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(ce.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:oe.sort,splice:oe.splice},ce.extend=ce.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||v(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(ce.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||ce.isPlainObject(n)?n:{},i=!1,a[t]=ce.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},ce.extend({expando:"jQuery"+(t+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==i.call(e))&&(!(t=r(e))||"function"==typeof(n=ue.call(t,"constructor")&&t.constructor)&&o.call(n)===a)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(c(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},text:function(e){var t,n="",r=0,i=e.nodeType;if(!i)while(t=e[r++])n+=ce.text(t);return 1===i||11===i?e.textContent:9===i?e.documentElement.textContent:3===i||4===i?e.nodeValue:n},makeArray:function(e,t){var n=t||[];return null!=e&&(c(Object(e))?ce.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},isXMLDoc:function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!l.test(t||n&&n.nodeName||"HTML")},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(c(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:le}),"function"==typeof Symbol&&(ce.fn[Symbol.iterator]=oe[Symbol.iterator]),ce.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var de=oe.pop,pe=oe.sort,he=oe.splice,ge="[\\x20\\t\\r\\n\\f]",ve=new RegExp("^"+ge+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ge+"+$","g");ce.contains=function(e,t){var n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(e.contains?e.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))};var f=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;function d(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e}ce.escapeSelector=function(e){return(e+"").replace(f,d)};var ye=m,me=s;!function(){var e,x,w,o,a,C,r,T,p,i,E=me,k=ce.expando,S=0,n=0,s=W(),c=W(),u=W(),h=W(),l=function(e,t){return e===t&&(a=!0),0},f="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",t="(?:\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",d="\\["+ge+"*("+t+")(?:"+ge+"*([*^$|!~]?=)"+ge+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+t+"))|)"+ge+"*\\]",g=":("+t+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+d+")*)|.*)\\)|)",v=new RegExp(ge+"+","g"),y=new RegExp("^"+ge+"*,"+ge+"*"),m=new RegExp("^"+ge+"*([>+~]|"+ge+")"+ge+"*"),b=new RegExp(ge+"|>"),A=new RegExp(g),D=new RegExp("^"+t+"$"),N={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+d),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},L=/^(?:input|select|textarea|button)$/i,j=/^h\d$/i,O=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,P=/[+~]/,H=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),q=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},R=function(){V()},M=K(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{E.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){E={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(V(e),e=e||C,T)){if(11!==d&&(u=O.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return E.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return E.call(n,a),n}else{if(u[2])return E.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return E.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||p&&p.test(t))){if(c=t,f=e,1===d&&(b.test(t)||m.test(t))){(f=P.test(t)&&X(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=k)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+G(l[o]);c=l.join(",")}try{return E.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function B(e){return e[k]=!0,e}function F(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function $(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&M(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function U(a){return B(function(o){return o=+o,B(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function X(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=C&&9===n.nodeType&&n.documentElement&&(r=(C=n).documentElement,T=!ce.isXMLDoc(C),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=C&&(t=C.defaultView)&&t.top!==t&&t.addEventListener("unload",R),le.getById=F(function(e){return r.appendChild(e).id=ce.expando,!C.getElementsByName||!C.getElementsByName(ce.expando).length}),le.disconnectedMatch=F(function(e){return i.call(e,"*")}),le.scope=F(function(){return C.querySelectorAll(":scope")}),le.cssHas=F(function(){try{return C.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(x.filter.ID=function(e){var t=e.replace(H,q);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&T){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(H,q);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&T){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},x.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&T)return t.getElementsByClassName(e)},p=[],F(function(e){var t;r.appendChild(e).innerHTML="<a id='"+k+"' href='' disabled='disabled'></a><select id='"+k+"-\r\\' disabled='disabled'><option selected=''></option></select>",e.querySelectorAll("[selected]").length||p.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+k+"-]").length||p.push("~="),e.querySelectorAll("a#"+k+"+*").length||p.push(".#.+[+~]"),e.querySelectorAll(":checked").length||p.push(":checked"),(t=C.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&p.push(":enabled",":disabled"),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||p.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||p.push(":has"),p=p.length&&new RegExp(p.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===C||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),C}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),T&&!h[t+" "]&&(!p||!p.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0<I(t,C,null,[e]).length},I.contains=function(e,t){return(e.ownerDocument||e)!=C&&V(e),ce.contains(e,t)},I.attr=function(e,t){(e.ownerDocument||e)!=C&&V(e);var n=x.attrHandle[t.toLowerCase()],r=n&&ue.call(x.attrHandle,t.toLowerCase())?n(e,t,!T):void 0;return void 0!==r?r:e.getAttribute(t)},I.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},ce.uniqueSort=function(e){var t,n=[],r=0,i=0;if(a=!le.sortStable,o=!le.sortStable&&ae.call(e,0),pe.call(e,l),a){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)he.call(e,n[r],1)}return o=null,e},ce.fn.uniqueSort=function(){return this.pushStack(ce.uniqueSort(ae.apply(this)))},(x=ce.expr={cacheLength:50,createPseudo:B,match:N,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(H,q),e[3]=(e[3]||e[4]||e[5]||"").replace(H,q),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return N.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&A.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(H,q).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(v," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(p,e,t,h,g){var v="nth"!==p.slice(0,3),y="last"!==p.slice(-4),m="of-type"===e;return 1===h&&0===g?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u=v!==y?"nextSibling":"previousSibling",l=e.parentNode,c=m&&e.nodeName.toLowerCase(),f=!n&&!m,d=!1;if(l){if(v){while(u){o=e;while(o=o[u])if(m?fe(o,c):1===o.nodeType)return!1;s=u="only"===p&&!s&&"nextSibling"}return!0}if(s=[y?l.firstChild:l.lastChild],y&&f){d=(a=(r=(i=l[k]||(l[k]={}))[p]||[])[0]===S&&r[1])&&r[2],o=a&&l.childNodes[a];while(o=++a&&o&&o[u]||(d=a=0)||s.pop())if(1===o.nodeType&&++d&&o===e){i[p]=[S,a,d];break}}else if(f&&(d=a=(r=(i=e[k]||(e[k]={}))[p]||[])[0]===S&&r[1]),!1===d)while(o=++a&&o&&o[u]||(d=a=0)||s.pop())if((m?fe(o,c):1===o.nodeType)&&++d&&(f&&((i=o[k]||(o[k]={}))[p]=[S,d]),o===e))break;return(d-=g)===h||d%h==0&&0<=d/h}}},PSEUDO:function(e,o){var t,a=x.pseudos[e]||x.setFilters[e.toLowerCase()]||I.error("unsupported pseudo: "+e);return a[k]?a(o):1<a.length?(t=[e,e,"",o],x.setFilters.hasOwnProperty(e.toLowerCase())?B(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=se.call(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:B(function(e){var r=[],i=[],s=ne(e.replace(ve,"$1"));return s[k]?B(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:B(function(t){return function(e){return 0<I(t,e).length}}),contains:B(function(t){return t=t.replace(H,q),function(e){return-1<(e.textContent||ce.text(e)).indexOf(t)}}),lang:B(function(n){return D.test(n||"")||I.error("unsupported lang: "+n),n=n.replace(H,q).toLowerCase(),function(e){var t;do{if(t=T?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=ie.location&&ie.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===r},focus:function(e){return e===function(){try{return C.activeElement}catch(e){}}()&&C.hasFocus()&&!!(e.type||e.href||~e.tabIndex)},enabled:z(!1),disabled:z(!0),checked:function(e){return fe(e,"input")&&!!e.checked||fe(e,"option")&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!x.pseudos.empty(e)},header:function(e){return j.test(e.nodeName)},input:function(e){return L.test(e.nodeName)},button:function(e){return fe(e,"input")&&"button"===e.type||fe(e,"button")},text:function(e){var t;return fe(e,"input")&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:U(function(){return[0]}),last:U(function(e,t){return[t-1]}),eq:U(function(e,t,n){return[n<0?n+t:n]}),even:U(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:U(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:U(function(e,t,n){var r;for(r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:U(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=x.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})x.pseudos[e]=$(e);for(e in{submit:!0,reset:!0})x.pseudos[e]=_(e);function Q(){}function Y(e,t){var n,r,i,o,a,s,u,l=c[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=x.preFilter;while(a){for(o in n&&!(r=y.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=m.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(ve," ")}),a=a.slice(n.length)),x.filter)!(r=N[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?I.error(e):c(e,s).slice(0)}function G(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function K(a,e,t){var s=e.dir,u=e.next,l=u||s,c=t&&"parentNode"===l,f=n++;return e.first?function(e,t,n){while(e=e[s])if(1===e.nodeType||c)return a(e,t,n);return!1}:function(e,t,n){var r,i,o=[S,f];if(n){while(e=e[s])if((1===e.nodeType||c)&&a(e,t,n))return!0}else while(e=e[s])if(1===e.nodeType||c)if(i=e[k]||(e[k]={}),u&&fe(e,u))e=e[s]||e;else{if((r=i[l])&&r[0]===S&&r[1]===f)return o[2]=r[2];if((i[l]=o)[2]=a(e,t,n))return!0}return!1}}function J(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Z(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function ee(p,h,g,v,y,e){return v&&!v[k]&&(v=ee(v)),y&&!y[k]&&(y=ee(y,e)),B(function(e,t,n,r){var i,o,a,s,u=[],l=[],c=t.length,f=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)I(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),d=!p||!e&&h?f:Z(f,u,p,n,r);if(g?g(d,s=y||(e?p:c||v)?[]:t,n,r):s=d,v){i=Z(s,l),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(s[l[o]]=!(d[l[o]]=a))}if(e){if(y||p){if(y){i=[],o=s.length;while(o--)(a=s[o])&&i.push(d[o]=a);y(null,s=[],i,r)}o=s.length;while(o--)(a=s[o])&&-1<(i=y?se.call(e,a):u[o])&&(e[i]=!(t[i]=a))}}else s=Z(s===t?s.splice(c,s.length):s),y?y(null,t,s,r):E.apply(t,s)})}function te(e){for(var i,t,n,r=e.length,o=x.relative[e[0].type],a=o||x.relative[" "],s=o?1:0,u=K(function(e){return e===i},a,!0),l=K(function(e){return-1<se.call(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!=w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=x.relative[e[s].type])c=[K(J(c),t)];else{if((t=x.filter[e[s].type].apply(null,e[s].matches))[k]){for(n=++s;n<r;n++)if(x.relative[e[n].type])break;return ee(1<s&&J(c),1<s&&G(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(ve,"$1"),t,s<n&&te(e.slice(s,n)),n<r&&te(e=e.slice(n)),n<r&&G(e))}c.push(t)}return J(c)}function ne(e,t){var n,v,y,m,b,r,i=[],o=[],a=u[e+" "];if(!a){t||(t=Y(e)),n=t.length;while(n--)(a=te(t[n]))[k]?i.push(a):o.push(a);(a=u(e,(v=o,m=0<(y=i).length,b=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],d=w,p=e||b&&x.find.TAG("*",i),h=S+=null==d?1:Math.random()||.1,g=p.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=p[l]);l++){if(b&&o){a=0,t||o.ownerDocument==C||(V(o),n=!T);while(s=v[a++])if(s(o,t||C,n)){E.call(r,o);break}i&&(S=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=de.call(r));f=Z(f)}E.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&ce.uniqueSort(r)}return i&&(S=h,w=d),c},m?B(r):r))).selector=e}return a}function re(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&Y(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&T&&x.relative[o[1].type]){if(!(t=(x.find.ID(a.matches[0].replace(H,q),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=N.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],x.relative[s=a.type])break;if((u=x.find[s])&&(r=u(a.matches[0].replace(H,q),P.test(o[0].type)&&X(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&G(o)))return E.apply(n,r),n;break}}}return(l||ne(e,c))(r,t,!T,n,!t||P.test(e)&&X(t.parentNode)||t),n}Q.prototype=x.filters=x.pseudos,x.setFilters=new Q,le.sortStable=k.split("").sort(l).join("")===k,V(),le.sortDetached=F(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce.find=I,ce.expr[":"]=ce.expr.pseudos,ce.unique=ce.uniqueSort,I.compile=ne,I.select=re,I.setDocument=V,I.tokenize=Y,I.escape=ce.escapeSelector,I.getText=ce.text,I.isXML=ce.isXMLDoc,I.selectors=ce.expr,I.support=ce.support,I.uniqueSort=ce.uniqueSort}();var p=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&ce(e).is(n))break;r.push(e)}return r},h=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},w=ce.expr.match.needsContext,C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1<se.call(n,e)!==r}):ce.filter(n,e,r)}ce.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?ce.find.matchesSelector(r,e)?[r]:[]:ce.find.matches(e,ce.grep(t,function(e){return 1===e.nodeType}))},ce.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(ce(e).filter(function(){for(t=0;t<r;t++)if(ce.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)ce.find(e,i[t],n);return 1<r?ce.uniqueSort(n):n},filter:function(e){return this.pushStack(T(this,e||[],!1))},not:function(e){return this.pushStack(T(this,e||[],!0))},is:function(e){return!!T(this,"string"==typeof e&&w.test(e)?ce(e):e||[],!1).length}});var E,k=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||E,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:k.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:m,!0)),C
vendor: 11,777 bytes, line 10719
10719.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=m.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,E=ce(m);var S=/^(?:parents|prev(?:Until|All))/,A={children:!0,contents:!0,next:!0,prev:!0};function D(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(ce.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&ce(e);if(!w.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&ce.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?ce.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?se.call(ce(e),this[0]):se.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(ce.uniqueSort(ce.merge(this.get(),ce(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),ce.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return p(e,"parentNode")},parentsUntil:function(e,t,n){return p(e,"parentNode",n)},next:function(e){return D(e,"nextSibling")},prev:function(e){return D(e,"previousSibling")},nextAll:function(e){return p(e,"nextSibling")},prevAll:function(e){return p(e,"previousSibling")},nextUntil:function(e,t,n){return p(e,"nextSibling",n)},prevUntil:function(e,t,n){return p(e,"previousSibling",n)},siblings:function(e){return h((e.parentNode||{}).firstChild,e)},children:function(e){return h(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(fe(e,"template")&&(e=e.content||e),ce.merge([],e.childNodes))}},function(r,i){ce.fn[r]=function(e,t){var n=ce.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=ce.filter(t,n)),1<this.length&&(A[r]||ce.uniqueSort(n),S.test(r)&&n.reverse()),this.pushStack(n)}});var N=/[^\x20\t\r\n\f]+/g;function L(e){return e}function j(e){throw e}function O(e,t,n,r){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(n):e&&v(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}ce.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},ce.each(e.match(N)||[],function(e,t){n[t]=!0}),n):ce.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){ce.each(e,function(e,t){v(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==x(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return ce.each(arguments,function(e,t){var n;while(-1<(n=ce.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<ce.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},ce.extend({Deferred:function(e){var o=[["notify","progress",ce.Callbacks("memory"),ce.Callbacks("memory"),2],["resolve","done",ce.Callbacks("once memory"),ce.Callbacks("once memory"),0,"resolved"],["reject","fail",ce.Callbacks("once memory"),ce.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return ce.Deferred(function(r){ce.each(o,function(e,t){var n=v(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&v(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,v(t)?s?t.call(e,l(u,o,L,s),l(u,o,j,s)):(u++,t.call(e,l(u,o,L,s),l(u,o,j,s),l(u,o,L,o.notifyWith))):(a!==L&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){ce.Deferred.exceptionHook&&ce.Deferred.exceptionHook(e,t.error),u<=i+1&&(a!==j&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(ce.Deferred.getErrorHook?t.error=ce.Deferred.getErrorHook():ce.Deferred.getStackHook&&(t.error=ce.Deferred.getStackHook()),ie.setTimeout(t))}}return ce.Deferred(function(e){o[0][3].add(l(0,e,v(r)?r:L,e.notifyWith)),o[1][3].add(l(0,e,v(t)?t:L)),o[2][3].add(l(0,e,v(n)?n:j))}).promise()},promise:function(e){return null!=e?ce.extend(e,a):a}},s={};return ce.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=ae.call(arguments),o=ce.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?ae.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(O(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||v(i[t]&&i[t].then)))return o.then();while(t--)O(i[t],a(t),o.reject);return o.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;ce.Deferred.exceptionHook=function(e,t){ie.console&&ie.console.warn&&e&&P.test(e.name)&&ie.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},ce.readyException=function(e){ie.setTimeout(function(){throw e})};var H=ce.Deferred();function q(){m.removeEventListener("DOMContentLoaded",q),ie.removeEventListener("load",q),ce.ready()}ce.fn.ready=function(e){return H.then(e)["catch"](function(e){ce.readyException(e)}),this},ce.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--ce.readyWait:ce.isReady)||(ce.isReady=!0)!==e&&0<--ce.readyWait||H.resolveWith(m,[ce])}}),ce.ready.then=H.then,"complete"===m.readyState||"loading"!==m.readyState&&!m.documentElement.doScroll?ie.setTimeout(ce.ready):(m.addEventListener("DOMContentLoaded",q),ie.addEventListener("load",q));var R=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n))for(s in i=!0,n)R(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,v(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(ce(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},M=/^-ms-/,I=/-([a-z])/g;function W(e,t){return t.toUpperCase()}function B(e){return e.replace(M,"ms-").replace(I,W)}var F=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function $(){this.expando=ce.expando+$.uid++}$.uid=1,$.prototype={cache:function(e){var t=e[this.expando];return t||(t={},F(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[B(t)]=n;else for(r in t)i[B(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][B(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(B):(t=B(t))in r?[t]:t.match(N)||[]).length;while(n--)delete r[t[n]]}(void 0===t||ce.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!ce.isEmptyObject(t)}};var _=new $,z=new $,U=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,X=/[A-Z]/g;function V(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(X,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:U.test(i)?JSON.parse(i):i)}catch(e){}z.set(e,t,n)}else n=void 0;return n}ce.extend({hasData:function(e){return z.hasData(e)||_.hasData(e)},data:function(e,t,n){return z.access(e,t,n)},removeData:function(e,t){z.remove(e,t)},_data:function(e,t,n){return _.access(e,t,n)},_removeData:function(e,t){_.remove(e,t)}}),ce.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=z.get(o),1===o.nodeType&&!_.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=B(r.slice(5)),V(o,r,i[r]));_.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){z.set(this,n)}):R(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=z.get(o,n))?t:void 0!==(t=V(o,n))?t:void 0;this.each(function(){z.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){z.remove(this,e)})}}),ce.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=_.get(e,t),n&&(!r||Array.isArray(n)?r=_.access(e,t,ce.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=ce.queue(e,t),r=n.length,i=n.shift(),o=ce._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){ce.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return _.get(e,n)||_.access(e,n,{empty:ce.Callbacks("once memory").add(function(){_.remove(e,[t+"queue",n])})})}}),ce.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?ce.queue(this[0],t):void 0===n?this:this.each(function(){var e=ce.queue(this,t,n);ce._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&ce.dequeue(this,t)})},dequeue:function(e){return this.each(function(){ce.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=ce.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=_.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,Y=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),G=["Top","Right","Bottom","Left"],K=m.documentElement,J=function(e){return ce.contains(e.ownerDocument,e)},Z={composed:!0};K.getRootNode&&(J=function(e){return ce.contains(e.ownerDocument,e)||e.getRootNode(Z)===e.ownerDocument});var ee=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&J(e)&&"none"===ce.css(e,"display")};var te={};function ne(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=_.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ee(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=te[s])||(o=a.body.appendChild(a.createElement(s)),u=ce.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),te[s]=u)))):"none"!==n&&(l[c]="none",_.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}ce.fn.extend({show:function(){return ne(this,!0)},hide:function(){return ne(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ee(this)?ce(this).show():ce(this).hide()})}});var re,be,xe=/^(?:checkbox|radio)$/i,we=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,
vendor: 1,249 bytes, line 10719
10719Ce=/^$|^module$|\/(?:java|ecma)script/i;re=m.createDocumentFragment().appendChild(m.createElement("div")),(be=m.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),re.appendChild(be),le.checkClone=re.cloneNode(!0).cloneNode(!0).lastChild.checked,re.innerHTML="<textarea>x</textarea>",le.noCloneChecked=!!re.cloneNode(!0).lastChild.defaultValue,re.innerHTML="<option></option>",le.option=!!re.lastChild;var Te={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function Ee(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function ke(e,t){for(var n=0,r=e.length;n<r;n++)_.set(e[n],"globalEval",!t||_.get(t[n],"globalEval"))}Te.tbody=Te.tfoot=Te.colgroup=Te.caption=Te.thead,Te.th=Te.td,le.option||(Te.optgroup=Te.option=[1,"<select multiple='multiple'>","</select>"]);var Se=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p<h;
vendor: 13,976 bytes, line 10719
10719p++)if((o=e[p])||0===o)if("object"===x(o))ce.merge(d,o.nodeType?[o]:o);else if(Se.test(o)){a=a||f.appendChild(t.createElement("div")),s=(we.exec(o)||["",""])[1].toLowerCase(),u=Te[s]||Te._default,a.innerHTML=u[1]+ce.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;ce.merge(d,a.childNodes),(a=f.firstChild).textContent=""}else d.push(t.createTextNode(o));f.textContent="",p=0;while(o=d[p++])if(r&&-1<ce.inArray(o,r))i&&i.push(o);else if(l=J(o),a=Ee(f.appendChild(o),"script"),l&&ke(a),n){c=0;while(o=a[c++])Ce.test(o.type||"")&&n.push(o)}return f}var De=/^([^.]*)(?:\.(.+)|)/;function Ne(){return!0}function Le(){return!1}function je(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)je(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Le;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return ce().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=ce.guid++)),e.each(function(){ce.event.add(this,t,i,r,n)})}function Oe(e,r,t){t?(_.set(e,r,!1),ce.event.add(e,r,{namespace:!1,handler:function(e){var t,n=_.get(this,r);if(1&e.isTrigger&&this[r]){if(n)(ce.event.special[r]||{}).delegateType&&e.stopPropagation();else if(n=ae.call(arguments),_.set(this,r,n),this[r](),t=_.get(this,r),_.set(this,r,!1),n!==t)return e.stopImmediatePropagation(),e.preventDefault(),t}else n&&(_.set(this,r,ce.event.trigger(n[0],n.slice(1),this)),e.stopPropagation(),e.isImmediatePropagationStopped=Ne)}})):void 0===_.get(e,r)&&ce.event.add(e,r,Ne)}ce.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,v=_.get(t);if(F(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&ce.find.matchesSelector(K,i),n.guid||(n.guid=ce.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof ce&&ce.event.triggered!==e.type?ce.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(N)||[""]).length;while(l--)p=g=(s=De.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),p&&(f=ce.event.special[p]||{},p=(i?f.delegateType:f.bindType)||p,f=ce.event.special[p]||{},c=ce.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&ce.expr.match.needsContext.test(i),namespace:h.join(".")},o),(d=u[p])||((d=u[p]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(p,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,c):d.push(c),ce.event.global[p]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,v=_.hasData(e)&&_.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(N)||[""]).length;while(l--)if(p=g=(s=De.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),p){f=ce.event.special[p]||{},d=u[p=(r?f.delegateType:f.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=d.length;while(o--)c=d[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(e,c));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||ce.removeEvent(e,p,v.handle),delete u[p])}else for(p in u)ce.event.remove(e,p+t[l],n,r,!0);ce.isEmptyObject(u)&&_.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=ce.event.fix(e),l=(_.get(this,"events")||Object.create(null))[u.type]||[],c=ce.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=ce.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((ce.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<ce(i,this).index(l):ce.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(ce.Event.prototype,t,{enumerable:!0,configurable:!0,get:v(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[ce.expando]?e:new ce.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return xe.test(t.type)&&t.click&&fe(t,"input")&&Oe(t,"click",!0),!1},trigger:function(e){var t=this||e;return xe.test(t.type)&&t.click&&fe(t,"input")&&Oe(t,"click"),!0},_default:function(e){var t=e.target;return xe.test(t.type)&&t.click&&fe(t,"input")&&_.get(t,"click")||fe(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},ce.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},ce.Event=function(e,t){if(!(this instanceof ce.Event))return new ce.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ne:Le,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&ce.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[ce.expando]=!0},ce.Event.prototype={constructor:ce.Event,isDefaultPrevented:Le,isPropagationStopped:Le,isImmediatePropagationStopped:Le,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ne,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ne,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ne,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},ce.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},ce.event.addProp),ce.each({focus:"focusin",blur:"focusout"},function(r,i){function o(e){if(m.documentMode){var t=_.get(this,"handle"),n=ce.event.fix(e);n.type="focusin"===e.type?"focus":"blur",n.isSimulated=!0,t(e),n.target===n.currentTarget&&t(n)}else ce.event.simulate(i,e.target,ce.event.fix(e))}ce.event.special[r]={setup:function(){var e;if(Oe(this,r,!0),!m.documentMode)return!1;(e=_.get(this,i))||this.addEventListener(i,o),_.set(this,i,(e||0)+1)},trigger:function(){return Oe(this,r),!0},teardown:function(){var e;if(!m.documentMode)return!1;(e=_.get(this,i)-1)?_.set(this,i,e):(this.removeEventListener(i,o),_.remove(this,i))},_default:function(e){return _.get(e.target,r)},delegateType:i},ce.event.special[i]={setup:function(){var e=this.ownerDocument||this.document||this,t=m.documentMode?this:e,n=_.get(t,i);n||(m.documentMode?this.addEventListener(i,o):e.addEventListener(r,o,!0)),_.set(t,i,(n||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=m.documentMode?this:e,n=_.get(t,i)-1;n?_.set(t,i,n):(m.documentMode?this.removeEventListener(i,o):e.removeEventListener(r,o,!0),_.remove(t,i))}}}),ce.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){ce.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||ce.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),ce.fn.extend({on:function(e,t,n,r){return je(this,e,t,n,r)},one:function(e,t,n,r){return je(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,ce(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Le),this.each(function(){ce.event.remove(this,e,n,t)})}});var Pe=/<script|<style|<link/i,He=/checked\s*(?:[^=]|=\s*.checked.)/i,qe=/^\s*<!\[CDATA\[|\]\]>\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Me(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Ie(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function We(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)ce.event.add(t,i,s[i][n]);z.hasData(e)&&(o=z.access(e),a=ce.extend({},o),z.set(t,a))}}function Be(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,d=f-1,p=r[0],h=v(p);if(h||1<f&&"string"==typeof p&&!le.checkClone&&He.test(p))return n.each(function(e){var t=n.eq(e);h&&(r[0]=p.call(this,e,t.html())),Be(t,r,i,o)});if(f&&(t=(e=Ae(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=ce.map(Ee(e,"script"),Me)).length;c<f;c++)u=e,c!==d&&(u=ce.clone(u,!0,!0),s&&ce.merge(a,Ee(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,ce.map(a,Ie),c=0;c<s;c++)u=a[c],Ce.test(u.type||"")&&!_.access(u,"globalEval")&&ce.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?ce._evalUrl&&!u.noModule&&ce._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(qe,""),u,l))}return n}function Fe(e,t,n){for(var r,i=t?ce.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||ce.cleanData(Ee(r)),r.parentNode&&(n&&J(r)&&ke(Ee(r,"script")),r.parentNode.removeChild(r));return e}ce.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=J(e);if(!(le.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||ce.isXMLDoc(e)))for(a=Ee(c),r=0,i=(o=Ee(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&xe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||Ee(e),a=a||Ee(c),r=0,i=o.length;r<i;r++)We(o[r],a[r]);else We(e,c);return 0<(a=Ee(c,"script")).length&&ke(a,!f&&Ee(e,"script")),c},cleanData:function(e){for(var t,n,r,i=ce.event.special,o=0;void 0!==(n=e[o]);o++)if(F(n)){if(t=n[_.expando]){if(t.events)for(r in t.events)i[r]?ce.event.remove(n,r):ce.removeEvent(n,r,t.handle);n[_.expando]=void 0}n[z.expando]&&(n[z.expando]=void 0)}}}),ce.fn.extend({detach:function(e){return Fe(this,e,!0)},remove:function(e){return Fe(this,e)},text:function(e){return R(this,function(e){return void 0===e?ce.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Be(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Re(this,e).appendChild(e)})},prepend:function(){return Be(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Re(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Be(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Be(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(ce.cleanData(Ee(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return ce.clone(this,e,t)})},html:function(e){return R(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Pe.test(e)&&!Te[(we.exec(e)||["",""])[1].toLowerCase()]){e=ce.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(ce.cleanData(Ee(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Be(this,arguments,function(e){var t=this.parentNode;ce.inArray(this,n)<0&&(ce.cleanData(Ee(this)),t&&t.replaceChild(e,this))},n)}}),ce.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){ce.fn[e]=function(e){for(var t,n=[],r=ce(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),ce(r[o])[a](t),s.apply(n,t.get());return this.pushStack(n)}});var $e=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),_e=/^--/,ze=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=ie),t.getComputedStyle(e)},Ue=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Xe=new RegExp(G.join("|"),"i");function Ve(e,t,n){var r,i,o,a,s=_e.test(t),u=e.style;return(n=n||ze(e))&&(a=n.getPropertyValue(t)||n[t],s&&a&&(a=a.replace(ve,"$1")||void 0),""!==a||J(e)||(a=ce.style(e,t)),!le.pixelBoxStyles()&&$e.test(a)&&Xe.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=n.width,u.width=r,u.minWidth=i,u.maxWidth=o)),void 0!==a?a+"":a}function Qe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;
10719left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",K.appendChild(u).appendChild(l);var e=ie.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),K.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=m.createElement("div"),l=m.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",le.clearCloneStyle="content-box"===l.style.backgroundClip,ce.extend(le,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=m.createElement("table"),t=m.createElement("tr"),n=m.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="box-sizing:content-box;border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",K.appendChild(e).appendChild(t).appendChild(n),r=ie.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,K.removeChild(e)),a}}))}();var Ye=["Webkit","Moz","ms"],Ge=m.createElement("div").style,Ke={};function Je(e){var t=ce.cssProps[e]||Ke[e];return t||(e in Ge?e:Ke[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Ye.length;while(n--)if((e=Ye[n]+t)in Ge)return e}(e)||e)}var Ze,et,tt=/^(none|table(?!-c[ea]).+)/,nt={position:"absolute",visibility:"hidden",display:"block"},rt={letterSpacing:"0",fontWeight:"400"};function it(e,t,n){var r=Y.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function ot(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0,l=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(l+=ce.css(e,n+G[a],!0,i)),r?("content"===n&&(u-=ce.css(e,"padding"+G[a],!0,i)),"margin"!==n&&(u-=ce.css(e,"border"+G[a]+"Width",!0,i))):(u+=ce.css(e,"padding"+G[a],!0,i),"padding"!==n?u+=ce.css(e,"border"+G[a]+"Width",!0,i):s+=ce.css(e,"border"+G[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u+l}function at(e,t,n){var r=ze(e),i=(!le.boxSizingReliable()||n)&&"border-box"===ce.css(e,"boxSizing",!1,r),o=i,a=Ve(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if($e.test(a)){if(!n)return a;a="auto"}return(!le.boxSizingReliable()&&i||!le.reliableTrDimensions()&&fe(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===ce.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===ce.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+ot(e,t,n||(i?"border":"content"),o,r,a)+"px"}ce.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Ve(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=B(t),u=_e.test(t),l=e.style;if(u||(t=Je(s)),a=ce.cssHooks[t]||ce.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=Y.exec(n))&&i[1]&&(n=function(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return ce.css(e,t,"")},u=s(),l=n&&n[3]||(ce.cssNumber[t]?"":"px"),c=e.nodeType&&(ce.cssNumber[t]||"px"!==l&&+u)&&Y.exec(ce.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)ce.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,ce.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(ce.cssNumber[s]?"":"px")),le.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=B(t);return _e.test(t)||(t=Je(s)),(a=ce.cssHooks[t]||ce.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Ve(e,t,r)),"normal"===i&&t in rt&&(i=rt[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),ce.each(["height","width"],function(e,u){ce.cssHooks[u]={get:function(e,t,n){if(t)return!tt.test(ce.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?at(e,u,n):Ue(e,nt,function(){return at(e,u,n)})},set:function(e,t,n){var r,i=ze(e),o=!le.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===ce.css(e,"boxSizing",!1,i),s=n?ot(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-ot(e,u,"border",!1,i)-.5)),s&&(r=Y.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=ce.css(e,u)),it(0,t,s)}}}),ce.cssHooks.marginLeft=Qe(le.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Ve(e,"marginLeft"))||e.getBoundingClientRect().left-Ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),ce.each({margin:"",padding:"",border:"Width"},function(i,o){ce.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+G[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(ce.cssHooks[i+o].set=it)}),ce.fn.extend({css:function(e,t){return R(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=ze(e),i=t.length;a<i;a++)o[t[a]]=ce.css(e,t[a],!1,r);return o}return void 0!==n?ce.style(e,t,n):ce.css(e,t)},e,t,1<arguments.length)}}),ce.fn.delay=function(r,e){return r=ce.fx&&ce.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=ie.setTimeout(e,r);t.stop=function(){ie.clearTimeout(n)}})},Ze=m.createElement("input"),et=m.createElement("select").appendChild(m.createElement("option")),Ze.type="checkbox",le.checkOn=""!==Ze.value,le.optSelected=et.selected,(Ze=m.createElement("input")).value="t",Ze.type="radio",le.radioValue="t"===Ze.value;var st,ut=ce.expr.attrHandle;ce.fn.extend({attr:function(e,t){return R(this,ce.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){ce.removeAttr(this,e)})}}
vendor: 9,814 bytes, line 10719
10719),ce.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?ce.prop(e,t,n):(1===o&&ce.isXMLDoc(e)||(i=ce.attrHooks[t.toLowerCase()]||(ce.expr.match.bool.test(t)?st:void 0)),void 0!==n?null===n?void ce.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=ce.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!le.radioValue&&"radio"===t&&fe(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(N);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),st={set:function(e,t,n){return!1===t?ce.removeAttr(e,n):e.setAttribute(n,n),n}},ce.each(ce.expr.match.bool.source.match(/\w+/g),function(e,t){var a=ut[t]||ce.find.attr;ut[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=ut[o],ut[o]=r,r=null!=a(e,t,n)?o:null,ut[o]=i),r}});var lt=/^(?:input|select|textarea|button)$/i,ct=/^(?:a|area)$/i;function ft(e){return(e.match(N)||[]).join(" ")}function dt(e){return e.getAttribute&&e.getAttribute("class")||""}function pt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(N)||[]}ce.fn.extend({prop:function(e,t){return R(this,ce.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[ce.propFix[e]||e]})}}),ce.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&ce.isXMLDoc(e)||(t=ce.propFix[t]||t,i=ce.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=ce.find.attr(e,"tabindex");return t?parseInt(t,10):lt.test(e.nodeName)||ct.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),le.optSelected||(ce.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),ce.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){ce.propFix[this.toLowerCase()]=this}),ce.fn.extend({addClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){ce(this).addClass(t.call(this,e,dt(this)))}):(e=pt(t)).length?this.each(function(){if(r=dt(this),n=1===this.nodeType&&" "+ft(r)+" "){for(o=0;o<e.length;o++)i=e[o],n.indexOf(" "+i+" ")<0&&(n+=i+" ");a=ft(n),r!==a&&this.setAttribute("class",a)}}):this},removeClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){ce(this).removeClass(t.call(this,e,dt(this)))}):arguments.length?(e=pt(t)).length?this.each(function(){if(r=dt(this),n=1===this.nodeType&&" "+ft(r)+" "){for(o=0;o<e.length;o++){i=e[o];while(-1<n.indexOf(" "+i+" "))n=n.replace(" "+i+" "," ")}a=ft(n),r!==a&&this.setAttribute("class",a)}}):this:this.attr("class","")},toggleClass:function(t,n){var e,r,i,o,a=typeof t,s="string"===a||Array.isArray(t);return v(t)?this.each(function(e){ce(this).toggleClass(t.call(this,e,dt(this),n),n)}):"boolean"==typeof n&&s?n?this.addClass(t):this.removeClass(t):(e=pt(t),this.each(function(){if(s)for(o=ce(this),i=0;i<e.length;i++)r=e[i],o.hasClass(r)?o.removeClass(r):o.addClass(r);else void 0!==t&&"boolean"!==a||((r=dt(this))&&_.set(this,"__className__",r),this.setAttribute&&this.setAttribute("class",r||!1===t?"":_.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+ft(dt(n))+" ").indexOf(t))return!0;return!1}});var ht=/\r/g;ce.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=v(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,ce(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=ce.map(t,function(e){return null==e?"":e+""})),(r=ce.valHooks[this.type]||ce.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=ce.valHooks[t.type]||ce.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(ht,""):null==e?"":e:void 0}}),ce.extend({valHooks:{option:{get:function(e){var t=ce.find.attr(e,"value");return null!=t?t:ft(ce.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!fe(n.parentNode,"optgroup"))){if(t=ce(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=ce.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<ce.inArray(ce.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),ce.each(["radio","checkbox"],function(){ce.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<ce.inArray(ce(e).val(),t)}},le.checkOn||(ce.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),ce.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new ie.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||ce.error("Invalid XML: "+(n?ce.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var gt=/^(?:focusinfocus|focusoutblur)$/,vt=function(e){e.stopPropagation()};ce.extend(ce.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,d=[n||m],p=ue.call(e,"type")?e.type:e,h=ue.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||m,3!==n.nodeType&&8!==n.nodeType&&!gt.test(p+ce.event.triggered)&&(-1<p.indexOf(".")&&(p=(h=p.split(".")).shift(),h.sort()),u=p.indexOf(":")<0&&"on"+p,(e=e[ce.expando]?e:new ce.Event(p,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:ce.makeArray(t,[e]),c=ce.event.special[p]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!y(n)){for(s=c.delegateType||p,gt.test(s+p)||(o=o.parentNode);o;o=o.parentNode)d.push(o),a=o;a===(n.ownerDocument||m)&&d.push(a.defaultView||a.parentWindow||ie)}i=0;while((o=d[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||p,(l=(_.get(o,"events")||Object.create(null))[e.type]&&_.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&F(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=p,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(d.pop(),t)||!F(n)||u&&v(n[p])&&!y(n)&&((a=n[u])&&(n[u]=null),ce.event.triggered=p,e.isPropagationStopped()&&f.addEventListener(p,vt),n[p](),e.isPropagationStopped()&&f.removeEventListener(p,vt),ce.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=ce.extend(new ce.Event,n,{type:e,isSimulated:!0});ce.event.trigger(r,null,t)}}),ce.fn.extend({trigger:function(e,t){return this.each(function(){ce.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return ce.event.trigger(e,t,n,!0)}});var yt,mt=/\[\]$/,bt=/\r?\n/g,xt=/^(?:submit|button|image|reset|file)$/i,wt=/^(?:input|select|textarea|keygen)/i;function Ct(n,e,r,i){var t;if(Array.isArray(e))ce.each(e,function(e,t){r||mt.test(n)?i(n,t):Ct(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==x(e))i(n,e);else for(t in e)Ct(n+"["+t+"]",e[t],r,i)}ce.param=function(e,t){var n,r=[],i=function(e,t){var n=v(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!ce.isPlainObject(e))ce.each(e,function(){i(this.name,this.value)});else for(n in e)Ct(n,e[n],t,i);return r.join("&")},ce.fn.extend({serialize:function(){return ce.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=ce.prop(this,"elements");return e?ce.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!ce(this).is(":disabled")&&wt.test(this.nodeName)&&!xt.test(e)&&(this.checked||!xe.test(e))}).map(function(e,t){var n=ce(this).val();return null==n?null:Array.isArray(n)?ce.map(n,function(e){return{name:t.name,value:e.replace(bt,"\r\n")}}):{name:t.name,value:n.replace(bt,"\r\n")}}).get()}}),ce.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=ce(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return v(n)?this.each(function(e){ce(this).wrapInner(n.call(this,e))}):this.each(function(){var e=ce(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=v(t);return this.each(function(e){ce(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){ce(this).replaceWith(this.childNodes)}),this}}),ce.expr.pseudos.hidden=function(e){return!ce.expr.pseudos.visible(e)},ce.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},le.createHTMLDocument=((yt=m.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===yt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=m.implementation.createHTMLDocument("")).createElement("base")).href=m.location.href,t.head.appendChild(r)):t=m),o=!n&&[],(i=C.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"to
10719p"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||K})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return R(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Qe(le.pixelPosition,function(e,t){if(t)return t=Ve(e,n),$e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return R(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Tt=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;ce.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),v(e))return r=ae.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(ae.call(arguments)))}).guid=e.guid=e.guid||ce.guid++,i},ce.holdReady=function(e){e?ce.readyWait++:ce.ready(!0)},ce.isArray=Array.isArray,ce.parseJSON=JSON.parse,ce.nodeName=fe,ce.isFunction=v,ce.isWindow=y,ce.camelCase=B,ce.type=x,ce.now=Date.now,ce.isNumeric=function(e){var t=ce.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},ce.trim=function(e){return null==e?"":(e+"").replace(Tt,"$1")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return ce});var Et=ie.jQuery,kt=ie.$;return ce.noConflict=function(e){return ie.$===ce&&(ie.$=kt),e&&ie.jQuery===ce&&(ie.jQuery=Et),ce},"undefined"==typeof e&&(ie.jQuery=ie.$=ce),ce}); 10720 10721;/**! 10722 * @fileOverview Kickass library to create and place poppers near their reference elements. 10723 * @version 1.14.3 10724 * @license 10725 * Copyright (c) 2016 Federico Zivolo and contributors 10726 * 10727 * Permission is hereby granted, free of charge, to any person obtaining a copy 10728 * of this software and associated documentation files (the "Software"), to deal 10729 * in the Software without restriction, including without limitation the rights 10730 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10731 * copies of the Software, and to permit persons to whom the Software is 10732 * furnished to do so, subject to the following conditions: 10733 * 10734 * The above copyright notice and this permission notice shall be included in all 10735 * copies or substantial portions of the Software. 10736 * 10737 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10738 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 10739 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10740 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 10741 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 10742 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 10743 * SOFTWARE. 10744 */ 10745(function (global, factory) { 10746 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 10747 typeof define === 'function' && define.amd ? define(factory) : 10748 (global.Popper = factory()); 10749}(this, (function () { 'use strict'; 10750 10751var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'; 10752 10753var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; 10754var timeoutDuration = 0; 10755for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { 10756 if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { 10757 timeoutDuration = 1; 10758 break; 10759 } 10760} 10761 10762function microtaskDebounce(fn) { 10763 var called = false;
vendor: 4,080 bytes, lines 10764-10927
10764 return function () { 10765 if (called) { 10766 return; 10767 } 10768 called = true; 10769 window.Promise.resolve().then(function () { 10770 called = false; 10771 fn(); 10772 }); 10773 }; 10774} 10775 10776function taskDebounce(fn) { 10777 var scheduled = false; 10778 return function () { 10779 if (!scheduled) { 10780 scheduled = true; 10781 setTimeout(function () { 10782 scheduled = false; 10783 fn(); 10784 }, timeoutDuration); 10785 } 10786 }; 10787} 10788 10789var supportsMicroTasks = isBrowser && window.Promise; 10790 10791/** 10792* Create a debounced version of a method, that's asynchronously deferred 10793* but called in the minimum time possible. 10794* 10795* @method 10796* @memberof Popper.Utils 10797* @argument {Function} fn 10798* @returns {Function} 10799*/ 10800var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; 10801 10802/** 10803 * Check if the given variable is a function 10804 * @method 10805 * @memberof Popper.Utils 10806 * @argument {Any} functionToCheck - variable to check 10807 * @returns {Boolean} answer to: is a function? 10808 */ 10809function isFunction(functionToCheck) { 10810 var getType = {}; 10811 return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; 10812} 10813 10814/** 10815 * Get CSS computed property of the given element 10816 * @method 10817 * @memberof Popper.Utils 10818 * @argument {Eement} element 10819 * @argument {String} property 10820 */ 10821function getStyleComputedProperty(element, property) { 10822 if (element.nodeType !== 1) { 10823 return []; 10824 } 10825 // NOTE: 1 DOM access here 10826 var css = getComputedStyle(element, null); 10827 return property ? css[property] : css; 10828} 10829 10830/** 10831 * Returns the parentNode or the host of the element 10832 * @method 10833 * @memberof Popper.Utils 10834 * @argument {Element} element 10835 * @returns {Element} parent 10836 */ 10837function getParentNode(element) { 10838 if (element.nodeName === 'HTML') { 10839 return element; 10840 } 10841 return element.parentNode || element.host; 10842} 10843 10844/** 10845 * Returns the scrolling parent of the given element 10846 * @method 10847 * @memberof Popper.Utils 10848 * @argument {Element} element 10849 * @returns {Element} scroll parent 10850 */ 10851function getScrollParent(element) { 10852 // Return body, `getScroll` will take care to get the correct `scrollTop` from it 10853 if (!element) { 10854 return document.body; 10855 } 10856 10857 switch (element.nodeName) { 10858 case 'HTML': 10859 case 'BODY': 10860 return element.ownerDocument.body; 10861 case '#document': 10862 return element.body; 10863 } 10864 10865 // Firefox want us to check `-x` and `-y` variations as well 10866 10867 var _getStyleComputedProp = getStyleComputedProperty(element), 10868 overflow = _getStyleComputedProp.overflow, 10869 overflowX = _getStyleComputedProp.overflowX, 10870 overflowY = _getStyleComputedProp.overflowY; 10871 10872 if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { 10873 return element; 10874 } 10875 10876 return getScrollParent(getParentNode(element)); 10877} 10878 10879var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); 10880var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); 10881 10882/** 10883 * Determines if the browser is Internet Explorer 10884 * @method 10885 * @memberof Popper.Utils 10886 * @param {Number} version to check 10887 * @returns {Boolean} isIE 10888 */ 10889function isIE(version) { 10890 if (version === 11) { 10891 return isIE11; 10892 } 10893 if (version === 10) { 10894 return isIE10; 10895 } 10896 return isIE11 || isIE10; 10897} 10898 10899/** 10900 * Returns the offset parent of the given element 10901 * @method 10902 * @memberof Popper.Utils 10903 * @argument {Element} element 10904 * @returns {Element} offset parent 10905 */ 10906function getOffsetParent(element) { 10907 if (!element) { 10908 return document.documentElement; 10909 } 10910 10911 var noOffsetParent = isIE(10) ? document.body : null; 10912 10913 // NOTE: 1 DOM access here 10914 var offsetParent = element.offsetParent; 10915 // Skip hidden elements which don't have an offsetParent 10916 while (offsetParent === noOffsetParent && element.nextElementSibling) { 10917 offsetParent = (element = element.nextElementSibling).offsetParent; 10918 } 10919 10920 var nodeName = offsetParent && offsetParent.nodeName; 10921 10922 if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { 10923 return element ? element.ownerDocument.documentElement : document.documentElement; 10924 } 10925 10926 // .offsetParent will return the closest TD or TABLE in case 10927 // no offsetParent is present, I hate this job...
vendor: 1,646 bytes, lines 10928-10983
10928 if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { 10929 return getOffsetParent(offsetParent); 10930 } 10931 10932 return offsetParent; 10933} 10934 10935function isOffsetContainer(element) { 10936 var nodeName = element.nodeName; 10937 10938 if (nodeName === 'BODY') { 10939 return false; 10940 } 10941 return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; 10942} 10943 10944/** 10945 * Finds the root node (document, shadowDOM root) of the given element 10946 * @method 10947 * @memberof Popper.Utils 10948 * @argument {Element} node 10949 * @returns {Element} root node 10950 */ 10951function getRoot(node) { 10952 if (node.parentNode !== null) { 10953 return getRoot(node.parentNode); 10954 } 10955 10956 return node; 10957} 10958 10959/** 10960 * Finds the offset parent common to the two provided nodes 10961 * @method 10962 * @memberof Popper.Utils 10963 * @argument {Element} element1 10964 * @argument {Element} element2 10965 * @returns {Element} common offset parent 10966 */ 10967function findCommonOffsetParent(element1, element2) { 10968 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 10969 if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { 10970 return document.documentElement; 10971 } 10972 10973 // Here we make sure to give as "start" the element that comes first in the DOM 10974 var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; 10975 var start = order ? element1 : element2; 10976 var end = order ? element2 : element1; 10977 10978 // Get common ancestor container 10979 var range = document.createRange(); 10980 range.setStart(start, 0); 10981 range.setEnd(end, 0); 10982 var commonAncestorContainer = range.commonAncestorContainer; 10983
vendor: 9,991 bytes, lines 10984-11291
10984 // Both nodes are inside #document 10985 10986 if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { 10987 if (isOffsetContainer(commonAncestorContainer)) { 10988 return commonAncestorContainer; 10989 } 10990 10991 return getOffsetParent(commonAncestorContainer); 10992 } 10993 10994 // one of the nodes is inside shadowDOM, find which one 10995 var element1root = getRoot(element1); 10996 if (element1root.host) { 10997 return findCommonOffsetParent(element1root.host, element2); 10998 } else { 10999 return findCommonOffsetParent(element1, getRoot(element2).host); 11000 } 11001} 11002 11003/** 11004 * Gets the scroll value of the given element in the given side (top and left) 11005 * @method 11006 * @memberof Popper.Utils 11007 * @argument {Element} element 11008 * @argument {String} side `top` or `left` 11009 * @returns {number} amount of scrolled pixels 11010 */ 11011function getScroll(element) { 11012 var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; 11013 11014 var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; 11015 var nodeName = element.nodeName; 11016 11017 if (nodeName === 'BODY' || nodeName === 'HTML') { 11018 var html = element.ownerDocument.documentElement; 11019 var scrollingElement = element.ownerDocument.scrollingElement || html; 11020 return scrollingElement[upperSide]; 11021 } 11022 11023 return element[upperSide]; 11024} 11025 11026/* 11027 * Sum or subtract the element scroll values (left and top) from a given rect object 11028 * @method 11029 * @memberof Popper.Utils 11030 * @param {Object} rect - Rect object you want to change 11031 * @param {HTMLElement} element - The element from the function reads the scroll values 11032 * @param {Boolean} subtract - set to true if you want to subtract the scroll values 11033 * @return {Object} rect - The modifier rect object 11034 */ 11035function includeScroll(rect, element) { 11036 var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 11037 11038 var scrollTop = getScroll(element, 'top'); 11039 var scrollLeft = getScroll(element, 'left'); 11040 var modifier = subtract ? -1 : 1; 11041 rect.top += scrollTop * modifier; 11042 rect.bottom += scrollTop * modifier; 11043 rect.left += scrollLeft * modifier; 11044 rect.right += scrollLeft * modifier; 11045 return rect; 11046} 11047 11048/* 11049 * Helper to detect borders of a given element 11050 * @method 11051 * @memberof Popper.Utils 11052 * @param {CSSStyleDeclaration} styles 11053 * Result of `getStyleComputedProperty` on the given element 11054 * @param {String} axis - `x` or `y` 11055 * @return {number} borders - The borders size of the given axis 11056 */ 11057 11058function getBordersSize(styles, axis) { 11059 var sideA = axis === 'x' ? 'Left' : 'Top'; 11060 var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; 11061 11062 return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10); 11063} 11064 11065function getSize(axis, body, html, computedStyle) { 11066 return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? html['offset' + axis] + computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0); 11067} 11068 11069function getWindowSizes() { 11070 var body = document.body; 11071 var html = document.documentElement; 11072 var computedStyle = isIE(10) && getComputedStyle(html); 11073 11074 return { 11075 height: getSize('Height', body, html, computedStyle), 11076 width: getSize('Width', body, html, computedStyle) 11077 }; 11078} 11079 11080var classCallCheck = function (instance, Constructor) { 11081 if (!(instance instanceof Constructor)) { 11082 throw new TypeError("Cannot call a class as a function"); 11083 } 11084}; 11085 11086var createClass = function () { 11087 function defineProperties(target, props) { 11088 for (var i = 0; i < props.length; i++) { 11089 var descriptor = props[i]; 11090 descriptor.enumerable = descriptor.enumerable || false; 11091 descriptor.configurable = true; 11092 if ("value" in descriptor) descriptor.writable = true; 11093 Object.defineProperty(target, descriptor.key, descriptor); 11094 } 11095 } 11096 11097 return function (Constructor, protoProps, staticProps) { 11098 if (protoProps) defineProperties(Constructor.prototype, protoProps); 11099 if (staticProps) defineProperties(Constructor, staticProps); 11100 return Constructor; 11101 }; 11102}(); 11103 11104 11105 11106 11107 11108var defineProperty = function (obj, key, value) { 11109 if (key in obj) { 11110 Object.defineProperty(obj, key, { 11111 value: value, 11112 enumerable: true, 11113 configurable: true, 11114 writable: true 11115 }); 11116 } else { 11117 obj[key] = value; 11118 } 11119 11120 return obj; 11121}; 11122 11123var _extends = Object.assign || function (target) { 11124 for (var i = 1; i < arguments.length; i++) { 11125 var source = arguments[i]; 11126 11127 for (var key in source) { 11128 if (Object.prototype.hasOwnProperty.call(source, key)) { 11129 target[key] = source[key]; 11130 } 11131 } 11132 } 11133 11134 return target; 11135}; 11136 11137/** 11138 * Given element offsets, generate an output similar to getBoundingClientRect 11139 * @method 11140 * @memberof Popper.Utils 11141 * @argument {Object} offsets 11142 * @returns {Object} ClientRect like output 11143 */ 11144function getClientRect(offsets) { 11145 return _extends({}, offsets, { 11146 right: offsets.left + offsets.width, 11147 bottom: offsets.top + offsets.height 11148 }); 11149} 11150 11151/** 11152 * Get bounding client rect of given element 11153 * @method 11154 * @memberof Popper.Utils 11155 * @param {HTMLElement} element 11156 * @return {Object} client rect 11157 */ 11158function getBoundingClientRect(element) { 11159 var rect = {}; 11160 11161 // IE10 10 FIX: Please, don't ask, the element isn't 11162 // considered in DOM in some circumstances... 11163 // This isn't reproducible in IE10 compatibility mode of IE11 11164 try { 11165 if (isIE(10)) { 11166 rect = element.getBoundingClientRect(); 11167 var scrollTop = getScroll(element, 'top'); 11168 var scrollLeft = getScroll(element, 'left'); 11169 rect.top += scrollTop; 11170 rect.left += scrollLeft; 11171 rect.bottom += scrollTop; 11172 rect.right += scrollLeft; 11173 } else { 11174 rect = element.getBoundingClientRect(); 11175 } 11176 } catch (e) {} 11177 11178 var result = { 11179 left: rect.left, 11180 top: rect.top, 11181 width: rect.right - rect.left, 11182 height: rect.bottom - rect.top 11183 }; 11184 11185 // subtract scrollbar size from sizes 11186 var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {}; 11187 var width = sizes.width || element.clientWidth || result.right - result.left; 11188 var height = sizes.height || element.clientHeight || result.bottom - result.top; 11189 11190 var horizScrollbar = element.offsetWidth - width; 11191 var vertScrollbar = element.offsetHeight - height; 11192 11193 // if an hypothetical scrollbar is detected, we must be sure it's not a `border` 11194 // we make this check conditional for performance reasons 11195 if (horizScrollbar || vertScrollbar) { 11196 var styles = getStyleComputedProperty(element); 11197 horizScrollbar -= getBordersSize(styles, 'x'); 11198 vertScrollbar -= getBordersSize(styles, 'y'); 11199 11200 result.width -= horizScrollbar; 11201 result.height -= vertScrollbar; 11202 } 11203 11204 return getClientRect(result); 11205} 11206 11207function getOffsetRectRelativeToArbitraryNode(children, parent) { 11208 var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 11209 11210 var isIE10 = isIE(10); 11211 var isHTML = parent.nodeName === 'HTML'; 11212 var childrenRect = getBoundingClientRect(children); 11213 var parentRect = getBoundingClientRect(parent); 11214 var scrollParent = getScrollParent(children); 11215 11216 var styles = getStyleComputedProperty(parent); 11217 var borderTopWidth = parseFloat(styles.borderTopWidth, 10); 11218 var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10); 11219 11220 // In cases where the parent is fixed, we must ignore negative scroll in offset calc 11221 if (fixedPosition && parent.nodeName === 'HTML') { 11222 parentRect.top = Math.max(parentRect.top, 0); 11223 parentRect.left = Math.max(parentRect.left, 0); 11224 } 11225 var offsets = getClientRect({ 11226 top: childrenRect.top - parentRect.top - borderTopWidth, 11227 left: childrenRect.left - parentRect.left - borderLeftWidth, 11228 width: childrenRect.width, 11229 height: childrenRect.height 11230 }); 11231 offsets.marginTop = 0; 11232 offsets.marginLeft = 0; 11233 11234 // Subtract margins of documentElement in case it's being used as parent 11235 // we do this only on HTML because it's the only element that behaves 11236 // differently when margins are applied to it. The margins are included in 11237 // the box of the documentElement, in the other cases not. 11238 if (!isIE10 && isHTML) { 11239 var marginTop = parseFloat(styles.marginTop, 10); 11240 var marginLeft = parseFloat(styles.marginLeft, 10); 11241 11242 offsets.top -= borderTopWidth - marginTop; 11243 offsets.bottom -= borderTopWidth - marginTop; 11244 offsets.left -= borderLeftWidth - marginLeft; 11245 offsets.right -= borderLeftWidth - marginLeft; 11246 11247 // Attach marginTop and marginLeft because in some circumstances we may need them 11248 offsets.marginTop = marginTop; 11249 offsets.marginLeft = marginLeft; 11250 } 11251 11252 if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { 11253 offsets = includeScroll(offsets, parent); 11254 } 11255 11256 return offsets; 11257} 11258 11259function getViewportOffsetRectRelativeToArtbitraryNode(element) { 11260 var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 11261 11262 var html = element.ownerDocument.documentElement; 11263 var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); 11264 var width = Math.max(html.clientWidth, window.innerWidth || 0); 11265 var height = Math.max(html.clientHeight, window.innerHeight || 0); 11266 11267 var scrollTop = !excludeScroll ? getScroll(html) : 0; 11268 var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; 11269 11270 var offset = { 11271 top: scrollTop - relativeOffset.top + relativeOffset.marginTop, 11272 left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, 11273 width: width, 11274 height: height 11275 }; 11276 11277 return getClientRect(offset); 11278} 11279 11280/** 11281 * Check if the given element is fixed or is inside a fixed parent 11282 * @method 11283 * @memberof Popper.Utils 11284 * @argument {Element} element 11285 * @argument {Element} customContainer 11286 * @returns {Boolean} answer to "isFixed?" 11287 */ 11288function isFixed(element) { 11289 var nodeName = element.nodeName; 11290 if (nodeName === 'BODY' || nodeName === 'HTML') { 11291 return false;
vendor: 5,191 bytes, lines 11292-11457
11292 } 11293 if (getStyleComputedProperty(element, 'position') === 'fixed') { 11294 return true; 11295 } 11296 return isFixed(getParentNode(element)); 11297} 11298 11299/** 11300 * Finds the first parent of an element that has a transformed property defined 11301 * @method 11302 * @memberof Popper.Utils 11303 * @argument {Element} element 11304 * @returns {Element} first transformed parent or documentElement 11305 */ 11306 11307function getFixedPositionOffsetParent(element) { 11308 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 11309 if (!element || !element.parentElement || isIE()) { 11310 return document.documentElement; 11311 } 11312 var el = element.parentElement; 11313 while (el && getStyleComputedProperty(el, 'transform') === 'none') { 11314 el = el.parentElement; 11315 } 11316 return el || document.documentElement; 11317} 11318 11319/** 11320 * Computed the boundaries limits and return them 11321 * @method 11322 * @memberof Popper.Utils 11323 * @param {HTMLElement} popper 11324 * @param {HTMLElement} reference 11325 * @param {number} padding 11326 * @param {HTMLElement} boundariesElement - Element used to define the boundaries 11327 * @param {Boolean} fixedPosition - Is in fixed position mode 11328 * @returns {Object} Coordinates of the boundaries 11329 */ 11330function getBoundaries(popper, reference, padding, boundariesElement) { 11331 var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; 11332 11333 // NOTE: 1 DOM access here 11334 11335 var boundaries = { top: 0, left: 0 }; 11336 var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 11337 11338 // Handle viewport case 11339 if (boundariesElement === 'viewport') { 11340 boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); 11341 } else { 11342 // Handle other cases based on DOM element used as boundaries 11343 var boundariesNode = void 0; 11344 if (boundariesElement === 'scrollParent') { 11345 boundariesNode = getScrollParent(getParentNode(reference)); 11346 if (boundariesNode.nodeName === 'BODY') { 11347 boundariesNode = popper.ownerDocument.documentElement; 11348 } 11349 } else if (boundariesElement === 'window') { 11350 boundariesNode = popper.ownerDocument.documentElement; 11351 } else { 11352 boundariesNode = boundariesElement; 11353 } 11354 11355 var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); 11356 11357 // In case of HTML, we need a different computation 11358 if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { 11359 var _getWindowSizes = getWindowSizes(), 11360 height = _getWindowSizes.height, 11361 width = _getWindowSizes.width; 11362 11363 boundaries.top += offsets.top - offsets.marginTop; 11364 boundaries.bottom = height + offsets.top; 11365 boundaries.left += offsets.left - offsets.marginLeft; 11366 boundaries.right = width + offsets.left; 11367 } else { 11368 // for all the other DOM elements, this one is good 11369 boundaries = offsets; 11370 } 11371 } 11372 11373 // Add paddings 11374 boundaries.left += padding; 11375 boundaries.top += padding; 11376 boundaries.right -= padding; 11377 boundaries.bottom -= padding; 11378 11379 return boundaries; 11380} 11381 11382function getArea(_ref) { 11383 var width = _ref.width, 11384 height = _ref.height; 11385 11386 return width * height; 11387} 11388 11389/** 11390 * Utility used to transform the `auto` placement to the placement with more 11391 * available space. 11392 * @method 11393 * @memberof Popper.Utils 11394 * @argument {Object} data - The data object generated by update method 11395 * @argument {Object} options - Modifiers configuration and options 11396 * @returns {Object} The data object, properly modified 11397 */ 11398function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { 11399 var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; 11400 11401 if (placement.indexOf('auto') === -1) { 11402 return placement; 11403 } 11404 11405 var boundaries = getBoundaries(popper, reference, padding, boundariesElement); 11406 11407 var rects = { 11408 top: { 11409 width: boundaries.width, 11410 height: refRect.top - boundaries.top 11411 }, 11412 right: { 11413 width: boundaries.right - refRect.right, 11414 height: boundaries.height 11415 }, 11416 bottom: { 11417 width: boundaries.width, 11418 height: boundaries.bottom - refRect.bottom 11419 }, 11420 left: { 11421 width: refRect.left - boundaries.left, 11422 height: boundaries.height 11423 } 11424 }; 11425 11426 var sortedAreas = Object.keys(rects).map(function (key) { 11427 return _extends({ 11428 key: key 11429 }, rects[key], { 11430 area: getArea(rects[key]) 11431 }); 11432 }).sort(function (a, b) { 11433 return b.area - a.area; 11434 }); 11435 11436 var filteredAreas = sortedAreas.filter(function (_ref2) { 11437 var width = _ref2.width, 11438 height = _ref2.height; 11439 return width >= popper.clientWidth && height >= popper.clientHeight; 11440 }); 11441 11442 var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; 11443 11444 var variation = placement.split('-')[1]; 11445 11446 return computedPlacement + (variation ? '-' + variation : ''); 11447} 11448 11449/** 11450 * Get offsets to the reference element 11451 * @method 11452 * @memberof Popper.Utils 11453 * @param {Object} state 11454 * @param {Element} popper - the popper element 11455 * @param {Element} reference - the reference element (the popper will be relative to this) 11456 * @param {Element} fixedPosition - is in fixed position mode 11457 * @returns {Object}
vendor: 4,317 bytes, lines 11457-11592
11457 An object containing the offsets which will be applied to the popper 11458 */ 11459function getReferenceOffsets(state, popper, reference) { 11460 var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 11461 11462 var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 11463 return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); 11464} 11465 11466/** 11467 * Get the outer sizes of the given element (offset size + margins) 11468 * @method 11469 * @memberof Popper.Utils 11470 * @argument {Element} element 11471 * @returns {Object} object containing width and height properties 11472 */ 11473function getOuterSizes(element) { 11474 var styles = getComputedStyle(element); 11475 var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom); 11476 var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight); 11477 var result = { 11478 width: element.offsetWidth + y, 11479 height: element.offsetHeight + x 11480 }; 11481 return result; 11482} 11483 11484/** 11485 * Get the opposite placement of the given one 11486 * @method 11487 * @memberof Popper.Utils 11488 * @argument {String} placement 11489 * @returns {String} flipped placement 11490 */ 11491function getOppositePlacement(placement) { 11492 var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; 11493 return placement.replace(/left|right|bottom|top/g, function (matched) { 11494 return hash[matched]; 11495 }); 11496} 11497 11498/** 11499 * Get offsets to the popper 11500 * @method 11501 * @memberof Popper.Utils 11502 * @param {Object} position - CSS position the Popper will get applied 11503 * @param {HTMLElement} popper - the popper element 11504 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) 11505 * @param {String} placement - one of the valid placement options 11506 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper 11507 */ 11508function getPopperOffsets(popper, referenceOffsets, placement) { 11509 placement = placement.split('-')[0]; 11510 11511 // Get popper node sizes 11512 var popperRect = getOuterSizes(popper); 11513 11514 // Add position, width and height to our offsets object 11515 var popperOffsets = { 11516 width: popperRect.width, 11517 height: popperRect.height 11518 }; 11519 11520 // depending by the popper placement we have to compute its offsets slightly differently 11521 var isHoriz = ['right', 'left'].indexOf(placement) !== -1; 11522 var mainSide = isHoriz ? 'top' : 'left'; 11523 var secondarySide = isHoriz ? 'left' : 'top'; 11524 var measurement = isHoriz ? 'height' : 'width'; 11525 var secondaryMeasurement = !isHoriz ? 'height' : 'width'; 11526 11527 popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; 11528 if (placement === secondarySide) { 11529 popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; 11530 } else { 11531 popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; 11532 } 11533 11534 return popperOffsets; 11535} 11536 11537/** 11538 * Mimics the `find` method of Array 11539 * @method 11540 * @memberof Popper.Utils 11541 * @argument {Array} arr 11542 * @argument prop 11543 * @argument value 11544 * @returns index or -1 11545 */ 11546function find(arr, check) { 11547 // use native find if supported 11548 if (Array.prototype.find) { 11549 return arr.find(check); 11550 } 11551 11552 // use `filter` to obtain the same behavior of `find` 11553 return arr.filter(check)[0]; 11554} 11555 11556/** 11557 * Return the index of the matching object 11558 * @method 11559 * @memberof Popper.Utils 11560 * @argument {Array} arr 11561 * @argument prop 11562 * @argument value 11563 * @returns index or -1 11564 */ 11565function findIndex(arr, prop, value) { 11566 // use native findIndex if supported 11567 if (Array.prototype.findIndex) { 11568 return arr.findIndex(function (cur) { 11569 return cur[prop] === value; 11570 }); 11571 } 11572 11573 // use `find` + `indexOf` if `findIndex` isn't supported 11574 var match = find(arr, function (obj) { 11575 return obj[prop] === value; 11576 }); 11577 return arr.indexOf(match); 11578} 11579 11580/** 11581 * Loop trough the list of modifiers and run them in order, 11582 * each of them will then edit the data object. 11583 * @method 11584 * @memberof Popper.Utils 11585 * @param {dataObject} data 11586 * @param {Array} modifiers 11587 * @param {String} ends - Optional modifier name used as stopper 11588 * @returns {dataObject} 11589 */ 11590function runModifiers(modifiers, data, ends) { 11591 var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); 11592
vendor: 14,876 bytes, lines 11593-12038
11593 modifiersToRun.forEach(function (modifier) { 11594 if (modifier['function']) { 11595 // eslint-disable-line dot-notation 11596 console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); 11597 } 11598 var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation 11599 if (modifier.enabled && isFunction(fn)) { 11600 // Add properties to offsets to make them a complete clientRect object 11601 // we do this before each modifier to make sure the previous one doesn't 11602 // mess with these values 11603 data.offsets.popper = getClientRect(data.offsets.popper); 11604 data.offsets.reference = getClientRect(data.offsets.reference); 11605 11606 data = fn(data, modifier); 11607 } 11608 }); 11609 11610 return data; 11611} 11612 11613/** 11614 * Updates the position of the popper, computing the new offsets and applying 11615 * the new style.<br /> 11616 * Prefer `scheduleUpdate` over `update` because of performance reasons. 11617 * @method 11618 * @memberof Popper 11619 */ 11620function update() { 11621 // if popper is destroyed, don't perform any further update 11622 if (this.state.isDestroyed) { 11623 return; 11624 } 11625 11626 var data = { 11627 instance: this, 11628 styles: {}, 11629 arrowStyles: {}, 11630 attributes: {}, 11631 flipped: false, 11632 offsets: {} 11633 }; 11634 11635 // compute reference element offsets 11636 data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); 11637 11638 // compute auto placement, store placement inside the data object, 11639 // modifiers will be able to edit `placement` if needed 11640 // and refer to originalPlacement to know the original value 11641 data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); 11642 11643 // store the computed placement inside `originalPlacement` 11644 data.originalPlacement = data.placement; 11645 11646 data.positionFixed = this.options.positionFixed; 11647 11648 // compute the popper offsets 11649 data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); 11650 11651 data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; 11652 11653 // run the modifiers 11654 data = runModifiers(this.modifiers, data); 11655 11656 // the first `update` will call `onCreate` callback 11657 // the other ones will call `onUpdate` callback 11658 if (!this.state.isCreated) { 11659 this.state.isCreated = true; 11660 this.options.onCreate(data); 11661 } else { 11662 this.options.onUpdate(data); 11663 } 11664} 11665 11666/** 11667 * Helper used to know if the given modifier is enabled. 11668 * @method 11669 * @memberof Popper.Utils 11670 * @returns {Boolean} 11671 */ 11672function isModifierEnabled(modifiers, modifierName) { 11673 return modifiers.some(function (_ref) { 11674 var name = _ref.name, 11675 enabled = _ref.enabled; 11676 return enabled && name === modifierName; 11677 }); 11678} 11679 11680/** 11681 * Get the prefixed supported property name 11682 * @method 11683 * @memberof Popper.Utils 11684 * @argument {String} property (camelCase) 11685 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) 11686 */ 11687function getSupportedPropertyName(property) { 11688 var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; 11689 var upperProp = property.charAt(0).toUpperCase() + property.slice(1); 11690 11691 for (var i = 0; i < prefixes.length; i++) { 11692 var prefix = prefixes[i]; 11693 var toCheck = prefix ? '' + prefix + upperProp : property; 11694 if (typeof document.body.style[toCheck] !== 'undefined') { 11695 return toCheck; 11696 } 11697 } 11698 return null; 11699} 11700 11701/** 11702 * Destroy the popper 11703 * @method 11704 * @memberof Popper 11705 */ 11706function destroy() { 11707 this.state.isDestroyed = true; 11708 11709 // touch DOM only if `applyStyle` modifier is enabled 11710 if (isModifierEnabled(this.modifiers, 'applyStyle')) { 11711 this.popper.removeAttribute('x-placement'); 11712 this.popper.style.position = ''; 11713 this.popper.style.top = ''; 11714 this.popper.style.left = ''; 11715 this.popper.style.right = ''; 11716 this.popper.style.bottom = ''; 11717 this.popper.style.willChange = ''; 11718 this.popper.style[getSupportedPropertyName('transform')] = ''; 11719 } 11720 11721 this.disableEventListeners(); 11722 11723 // remove the popper if user explicity asked for the deletion on destroy 11724 // do not use `remove` because IE11 doesn't support it 11725 if (this.options.removeOnDestroy) { 11726 this.popper.parentNode.removeChild(this.popper); 11727 } 11728 return this; 11729} 11730 11731/** 11732 * Get the window associated with the element 11733 * @argument {Element} element 11734 * @returns {Window} 11735 */ 11736function getWindow(element) { 11737 var ownerDocument = element.ownerDocument; 11738 return ownerDocument ? ownerDocument.defaultView : window; 11739} 11740 11741function attachToScrollParents(scrollParent, event, callback, scrollParents) { 11742 var isBody = scrollParent.nodeName === 'BODY'; 11743 var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; 11744 target.addEventListener(event, callback, { passive: true }); 11745 11746 if (!isBody) { 11747 attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); 11748 } 11749 scrollParents.push(target); 11750} 11751 11752/** 11753 * Setup needed event listeners used to update the popper position 11754 * @method 11755 * @memberof Popper.Utils 11756 * @private 11757 */ 11758function setupEventListeners(reference, options, state, updateBound) { 11759 // Resize event listener on window 11760 state.updateBound = updateBound; 11761 getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); 11762 11763 // Scroll event listener on scroll parents 11764 var scrollElement = getScrollParent(reference); 11765 attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); 11766 state.scrollElement = scrollElement; 11767 state.eventsEnabled = true; 11768 11769 return state; 11770} 11771 11772/** 11773 * It will add resize/scroll events and start recalculating 11774 * position of the popper element when they are triggered. 11775 * @method 11776 * @memberof Popper 11777 */ 11778function enableEventListeners() { 11779 if (!this.state.eventsEnabled) { 11780 this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); 11781 } 11782} 11783 11784/** 11785 * Remove event listeners used to update the popper position 11786 * @method 11787 * @memberof Popper.Utils 11788 * @private 11789 */ 11790function removeEventListeners(reference, state) { 11791 // Remove resize event listener on window 11792 getWindow(reference).removeEventListener('resize', state.updateBound); 11793 11794 // Remove scroll event listener on scroll parents 11795 state.scrollParents.forEach(function (target) { 11796 target.removeEventListener('scroll', state.updateBound); 11797 }); 11798 11799 // Reset state 11800 state.updateBound = null; 11801 state.scrollParents = []; 11802 state.scrollElement = null; 11803 state.eventsEnabled = false; 11804 return state; 11805} 11806 11807/** 11808 * It will remove resize/scroll events and won't recalculate popper position 11809 * when they are triggered. It also won't trigger onUpdate callback anymore, 11810 * unless you call `update` method manually. 11811 * @method 11812 * @memberof Popper 11813 */ 11814function disableEventListeners() { 11815 if (this.state.eventsEnabled) { 11816 cancelAnimationFrame(this.scheduleUpdate); 11817 this.state = removeEventListeners(this.reference, this.state); 11818 } 11819} 11820 11821/** 11822 * Tells if a given input is a number 11823 * @method 11824 * @memberof Popper.Utils 11825 * @param {*} input to check 11826 * @return {Boolean} 11827 */ 11828function isNumeric(n) { 11829 return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); 11830} 11831 11832/** 11833 * Set the style to the given popper 11834 * @method 11835 * @memberof Popper.Utils 11836 * @argument {Element} element - Element to apply the style to 11837 * @argument {Object} styles 11838 * Object with a list of properties and values which will be applied to the element 11839 */ 11840function setStyles(element, styles) { 11841 Object.keys(styles).forEach(function (prop) { 11842 var unit = ''; 11843 // add unit if the value is numeric and is one of the following 11844 if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { 11845 unit = 'px'; 11846 } 11847 element.style[prop] = styles[prop] + unit; 11848 }); 11849} 11850 11851/** 11852 * Set the attributes to the given popper 11853 * @method 11854 * @memberof Popper.Utils 11855 * @argument {Element} element - Element to apply the attributes to 11856 * @argument {Object} styles 11857 * Object with a list of properties and values which will be applied to the element 11858 */ 11859function setAttributes(element, attributes) { 11860 Object.keys(attributes).forEach(function (prop) { 11861 var value = attributes[prop]; 11862 if (value !== false) { 11863 element.setAttribute(prop, attributes[prop]); 11864 } else { 11865 element.removeAttribute(prop); 11866 } 11867 }); 11868} 11869 11870/** 11871 * @function 11872 * @memberof Modifiers 11873 * @argument {Object} data - The data object generated by `update` method 11874 * @argument {Object} data.styles - List of style properties - values to apply to popper element 11875 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element 11876 * @argument {Object} options - Modifiers configuration and options 11877 * @returns {Object} The same data object 11878 */ 11879function applyStyle(data) { 11880 // any property present in `data.styles` will be applied to the popper, 11881 // in this way we can make the 3rd party modifiers add custom styles to it 11882 // Be aware, modifiers could override the properties defined in the previous 11883 // lines of this modifier! 11884 setStyles(data.instance.popper, data.styles); 11885 11886 // any property present in `data.attributes` will be applied to the popper, 11887 // they will be set as HTML attributes of the element 11888 setAttributes(data.instance.popper, data.attributes); 11889 11890 // if arrowElement is defined and arrowStyles has some properties 11891 if (data.arrowElement && Object.keys(data.arrowStyles).length) { 11892 setStyles(data.arrowElement, data.arrowStyles); 11893 } 11894 11895 return data; 11896} 11897 11898/** 11899 * Set the x-placement attribute before everything else because it could be used 11900 * to add margins to the popper margins needs to be calculated to get the 11901 * correct popper offsets. 11902 * @method 11903 * @memberof Popper.modifiers 11904 * @param {HTMLElement} reference - The reference element used to position the popper 11905 * @param {HTMLElement} popper - The HTML element used as popper 11906 * @param {Object} options - Popper.js options 11907 */ 11908function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { 11909 // compute reference element offsets 11910 var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); 11911 11912 // compute auto placement, store placement inside the data object, 11913 // modifiers will be able to edit `placement` if needed 11914 // and refer to originalPlacement to know the original value 11915 var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); 11916 11917 popper.setAttribute('x-placement', placement); 11918 11919 // Apply `position` to popper before anything else because 11920 // without the position applied we can't guarantee correct computations 11921 setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); 11922 11923 return options; 11924} 11925 11926/** 11927 * @function 11928 * @memberof Modifiers 11929 * @argument {Object} data - The data object generated by `update` method 11930 * @argument {Object} options - Modifiers configuration and options 11931 * @returns {Object} The data object, properly modified 11932 */ 11933function computeStyle(data, options) { 11934 var x = options.x, 11935 y = options.y; 11936 var popper = data.offsets.popper; 11937 11938 // Remove this legacy support in Popper.js v2 11939 11940 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { 11941 return modifier.name === 'applyStyle'; 11942 }).gpuAcceleration; 11943 if (legacyGpuAccelerationOption !== undefined) { 11944 console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); 11945 } 11946 var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; 11947 11948 var offsetParent = getOffsetParent(data.instance.popper); 11949 var offsetParentRect = getBoundingClientRect(offsetParent); 11950 11951 // Styles 11952 var styles = { 11953 position: popper.position 11954 }; 11955 11956 // Avoid blurry text by using full pixel integers. 11957 // For pixel-perfect positioning, top/bottom prefers rounded 11958 // values, while left/right prefers floored values. 11959 var offsets = { 11960 left: Math.floor(popper.left), 11961 top: Math.round(popper.top), 11962 bottom: Math.round(popper.bottom), 11963 right: Math.floor(popper.right) 11964 }; 11965 11966 var sideA = x === 'bottom' ? 'top' : 'bottom'; 11967 var sideB = y === 'right' ? 'left' : 'right'; 11968 11969 // if gpuAcceleration is set to `true` and transform is supported, 11970 // we use `translate3d` to apply the position to the popper we 11971 // automatically use the supported prefixed version if needed 11972 var prefixedProperty = getSupportedPropertyName('transform'); 11973 11974 // now, let's make a step back and look at this code closely (wtf?) 11975 // If the content of the popper grows once it's been positioned, it 11976 // may happen that the popper gets misplaced because of the new content 11977 // overflowing its reference element 11978 // To avoid this problem, we provide two options (x and y), which allow 11979 // the consumer to define the offset origin. 11980 // If we position a popper on top of a reference element, we can set 11981 // `x` to `top` to make the popper grow towards its top instead of 11982 // its bottom. 11983 var left = void 0, 11984 top = void 0; 11985 if (sideA === 'bottom') { 11986 top = -offsetParentRect.height + offsets.bottom; 11987 } else { 11988 top = offsets.top; 11989 } 11990 if (sideB === 'right') { 11991 left = -offsetParentRect.width + offsets.right; 11992 } else { 11993 left = offsets.left; 11994 } 11995 if (gpuAcceleration && prefixedProperty) { 11996 styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; 11997 styles[sideA] = 0; 11998 styles[sideB] = 0; 11999 styles.willChange = 'transform'; 12000 } else { 12001 // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties 12002 var invertTop = sideA === 'bottom' ? -1 : 1; 12003 var invertLeft = sideB === 'right' ? -1 : 1; 12004 styles[sideA] = top * invertTop; 12005 styles[sideB] = left * invertLeft; 12006 styles.willChange = sideA + ', ' + sideB; 12007 } 12008 12009 // Attributes 12010 var attributes = { 12011 'x-placement': data.placement 12012 }; 12013 12014 // Update `data` attributes, styles and arrowStyles 12015 data.attributes = _extends({}, attributes, data.attributes); 12016 data.styles = _extends({}, styles, data.styles); 12017 data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); 12018 12019 return data; 12020} 12021 12022/** 12023 * Helper used to know if the given modifier depends from another one.<br /> 12024 * It checks if the needed modifier is listed and enabled. 12025 * @method 12026 * @memberof Popper.Utils 12027 * @param {Array} modifiers - list of modifiers 12028 * @param {String} requestingName - name of requesting modifier 12029 * @param {String} requestedName - name of requested modifier 12030 * @returns {Boolean} 12031 */ 12032function isModifierRequired(modifiers, requestingName, requestedName) { 12033 var requesting = find(modifiers, function (_ref) { 12034 var name = _ref.name; 12035 return name === requestingName; 12036 }); 12037 12038 var isRequired = !!requesting && modifiers.some(function (modifier) {
vendor: 4,120 bytes, lines 12039-12158
12039 return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; 12040 }); 12041 12042 if (!isRequired) { 12043 var _requesting = '`' + requestingName + '`'; 12044 var requested = '`' + requestedName + '`'; 12045 console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); 12046 } 12047 return isRequired; 12048} 12049 12050/** 12051 * @function 12052 * @memberof Modifiers 12053 * @argument {Object} data - The data object generated by update method 12054 * @argument {Object} options - Modifiers configuration and options 12055 * @returns {Object} The data object, properly modified 12056 */ 12057function arrow(data, options) { 12058 var _data$offsets$arrow; 12059 12060 // arrow depends on keepTogether in order to work 12061 if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { 12062 return data; 12063 } 12064 12065 var arrowElement = options.element; 12066 12067 // if arrowElement is a string, suppose it's a CSS selector 12068 if (typeof arrowElement === 'string') { 12069 arrowElement = data.instance.popper.querySelector(arrowElement); 12070 12071 // if arrowElement is not found, don't run the modifier 12072 if (!arrowElement) { 12073 return data; 12074 } 12075 } else { 12076 // if the arrowElement isn't a query selector we must check that the 12077 // provided DOM node is child of its popper node 12078 if (!data.instance.popper.contains(arrowElement)) { 12079 console.warn('WARNING: `arrow.element` must be child of its popper element!'); 12080 return data; 12081 } 12082 } 12083 12084 var placement = data.placement.split('-')[0]; 12085 var _data$offsets = data.offsets, 12086 popper = _data$offsets.popper, 12087 reference = _data$offsets.reference; 12088 12089 var isVertical = ['left', 'right'].indexOf(placement) !== -1; 12090 12091 var len = isVertical ? 'height' : 'width'; 12092 var sideCapitalized = isVertical ? 'Top' : 'Left'; 12093 var side = sideCapitalized.toLowerCase(); 12094 var altSide = isVertical ? 'left' : 'top'; 12095 var opSide = isVertical ? 'bottom' : 'right'; 12096 var arrowElementSize = getOuterSizes(arrowElement)[len]; 12097 12098 // 12099 // extends keepTogether behavior making sure the popper and its 12100 // reference have enough pixels in conjuction 12101 // 12102 12103 // top/left side 12104 if (reference[opSide] - arrowElementSize < popper[side]) { 12105 data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); 12106 } 12107 // bottom/right side 12108 if (reference[side] + arrowElementSize > popper[opSide]) { 12109 data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; 12110 } 12111 data.offsets.popper = getClientRect(data.offsets.popper); 12112 12113 // compute center of the popper 12114 var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; 12115 12116 // Compute the sideValue using the updated popper offsets 12117 // take popper margin in account because we don't have this info available 12118 var css = getStyleComputedProperty(data.instance.popper); 12119 var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); 12120 var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); 12121 var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; 12122 12123 // prevent arrowElement from being placed not contiguously to its popper 12124 sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); 12125 12126 data.arrowElement = arrowElement; 12127 data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); 12128 12129 return data; 12130} 12131 12132/** 12133 * Get the opposite placement variation of the given one 12134 * @method 12135 * @memberof Popper.Utils 12136 * @argument {String} placement variation 12137 * @returns {String} flipped placement variation 12138 */ 12139function getOppositeVariation(variation) { 12140 if (variation === 'end') { 12141 return 'start'; 12142 } else if (variation === 'start') { 12143 return 'end'; 12144 } 12145 return variation; 12146} 12147 12148/** 12149 * List of accepted placements to use as values of the `placement` option.<br /> 12150 * Valid placements are: 12151 * - `auto` 12152 * - `top` 12153 * - `right` 12154 * - `bottom` 12155 * - `left` 12156 * 12157 * Each placement can have a variation from this list: 12158 * - `-start`
12159 * - `-end` 12160 * 12161 * Variations are interpreted easily if you think of them as the left to right 12162 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` 12163 * is right.<br /> 12164 * Vertically (`left` and `right`), `start` is top and `end` is bottom. 12165 * 12166 * Some valid examples are: 12167 * - `top-end` (on top of reference, right aligned) 12168 * - `right-start` (on right of reference, top aligned) 12169 * - `bottom` (on bottom, centered) 12170 * - `auto-right` (on the side with more space available, alignment depends by placement) 12171 * 12172 * @static 12173 * @type {Array} 12174 * @enum {String} 12175 * @readonly 12176 * @method placements 12177 * @memberof Popper 12178 */ 12179var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; 12180 12181// Get rid of `auto` `auto-start` and `auto-end` 12182var validPlacements = placements.slice(3); 12183 12184/** 12185 * Given an initial placement, returns all the subsequent placements 12186 * clockwise (or counter-clockwise). 12187 * 12188 * @method 12189 * @memberof Popper.Utils 12190 * @argument {String} placement - A valid placement (it accepts variations) 12191 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise 12192 * @returns {Array} placements including their variations 12193 */ 12194function clockwise(placement) { 12195 var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 12196 12197 var index = validPlacements.indexOf(placement); 12198 var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); 12199 return counter ? arr.reverse() : arr; 12200} 12201 12202var BEHAVIORS = { 12203 FLIP: 'flip', 12204 CLOCKWISE: 'clockwise', 12205 COUNTERCLOCKWISE: 'counterclockwise' 12206}; 12207 12208/** 12209 * @function 12210 * @memberof Modifiers 12211 * @argument {Object} data - The data object generated by update method 12212 * @argument {Object} options - Modifiers configuration and options 12213 * @returns {Object} The data object, properly modified 12214 */ 12215function flip(data, options) { 12216 // if `inner` modifier is enabled, we can't use the `flip` modifier 12217 if (isModifierEnabled(data.instance.modifiers, 'inner')) { 12218 return data; 12219 } 12220 12221 if (data.flipped && data.placement === data.originalPlacement) { 12222 // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides 12223 return data; 12224 } 12225 12226 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); 12227 12228 var placement = data.placement.split('-')[0]; 12229 var placementOpposite = getOppositePlacement(placement); 12230 var variation = data.placement.split('-')[1] || ''; 12231 12232 var flipOrder = []; 12233 12234 switch (options.behavior) { 12235 case BEHAVIORS.FLIP: 12236 flipOrder = [placement, placementOpposite]; 12237 break; 12238 case BEHAVIORS.CLOCKWISE: 12239 flipOrder = clockwise(placement); 12240 break; 12241 case BEHAVIORS.COUNTERCLOCKWISE: 12242 flipOrder = clockwise(placement, true); 12243 break; 12244 default: 12245 flipOrder = options.behavior; 12246 } 12247 12248 flipOrder.forEach(function (step, index) { 12249 if (placement !== step || flipOrder.length === index + 1) { 12250 return data; 12251 } 12252 12253 placement = data.placement.split('-')[0]; 12254 placementOpposite = getOppositePlacement(placement); 12255 12256 var popperOffsets = data.offsets.popper; 12257 var refOffsets = data.offsets.reference; 12258 12259 // using floor because the reference offsets may contain decimals we are not going to consider here 12260 var floor = Math.floor; 12261 var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); 12262 12263 var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); 12264 var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); 12265 var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); 12266 var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); 12267 12268 var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; 12269 12270 // flip the variation if required 12271 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 12272 var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom)
vendor: 14,631 bytes, lines 12272-12712
12272; 12273 12274 if (overlapsRef || overflowsBoundaries || flippedVariation) { 12275 // this boolean to detect any flip loop 12276 data.flipped = true; 12277 12278 if (overlapsRef || overflowsBoundaries) { 12279 placement = flipOrder[index + 1]; 12280 } 12281 12282 if (flippedVariation) { 12283 variation = getOppositeVariation(variation); 12284 } 12285 12286 data.placement = placement + (variation ? '-' + variation : ''); 12287 12288 // this object contains `position`, we want to preserve it along with 12289 // any additional property we may add in the future 12290 data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); 12291 12292 data = runModifiers(data.instance.modifiers, data, 'flip'); 12293 } 12294 }); 12295 return data; 12296} 12297 12298/** 12299 * @function 12300 * @memberof Modifiers 12301 * @argument {Object} data - The data object generated by update method 12302 * @argument {Object} options - Modifiers configuration and options 12303 * @returns {Object} The data object, properly modified 12304 */ 12305function keepTogether(data) { 12306 var _data$offsets = data.offsets, 12307 popper = _data$offsets.popper, 12308 reference = _data$offsets.reference; 12309 12310 var placement = data.placement.split('-')[0]; 12311 var floor = Math.floor; 12312 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 12313 var side = isVertical ? 'right' : 'bottom'; 12314 var opSide = isVertical ? 'left' : 'top'; 12315 var measurement = isVertical ? 'width' : 'height'; 12316 12317 if (popper[side] < floor(reference[opSide])) { 12318 data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; 12319 } 12320 if (popper[opSide] > floor(reference[side])) { 12321 data.offsets.popper[opSide] = floor(reference[side]); 12322 } 12323 12324 return data; 12325} 12326 12327/** 12328 * Converts a string containing value + unit into a px value number 12329 * @function 12330 * @memberof {modifiers~offset} 12331 * @private 12332 * @argument {String} str - Value + unit string 12333 * @argument {String} measurement - `height` or `width` 12334 * @argument {Object} popperOffsets 12335 * @argument {Object} referenceOffsets 12336 * @returns {Number|String} 12337 * Value in pixels, or original string if no values were extracted 12338 */ 12339function toValue(str, measurement, popperOffsets, referenceOffsets) { 12340 // separate value from unit 12341 var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); 12342 var value = +split[1]; 12343 var unit = split[2]; 12344 12345 // If it's not a number it's an operator, I guess 12346 if (!value) { 12347 return str; 12348 } 12349 12350 if (unit.indexOf('%') === 0) { 12351 var element = void 0; 12352 switch (unit) { 12353 case '%p': 12354 element = popperOffsets; 12355 break; 12356 case '%': 12357 case '%r': 12358 default: 12359 element = referenceOffsets; 12360 } 12361 12362 var rect = getClientRect(element); 12363 return rect[measurement] / 100 * value; 12364 } else if (unit === 'vh' || unit === 'vw') { 12365 // if is a vh or vw, we calculate the size based on the viewport 12366 var size = void 0; 12367 if (unit === 'vh') { 12368 size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); 12369 } else { 12370 size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 12371 } 12372 return size / 100 * value; 12373 } else { 12374 // if is an explicit pixel unit, we get rid of the unit and keep the value 12375 // if is an implicit unit, it's px, and we return just the value 12376 return value; 12377 } 12378} 12379 12380/** 12381 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. 12382 * @function 12383 * @memberof {modifiers~offset} 12384 * @private 12385 * @argument {String} offset 12386 * @argument {Object} popperOffsets 12387 * @argument {Object} referenceOffsets 12388 * @argument {String} basePlacement 12389 * @returns {Array} a two cells array with x and y offsets in numbers 12390 */ 12391function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { 12392 var offsets = [0, 0]; 12393 12394 // Use height if placement is left or right and index is 0 otherwise use width 12395 // in this way the first offset will use an axis and the second one 12396 // will use the other one 12397 var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; 12398 12399 // Split the offset string to obtain a list of values and operands 12400 // The regex addresses values with the plus or minus sign in front (+10, -20, etc) 12401 var fragments = offset.split(/(\+|\-)/).map(function (frag) { 12402 return frag.trim(); 12403 }); 12404 12405 // Detect if the offset string contains a pair of values or a single one 12406 // they could be separated by comma or space 12407 var divider = fragments.indexOf(find(fragments, function (frag) { 12408 return frag.search(/,|\s/) !== -1; 12409 })); 12410 12411 if (fragments[divider] && fragments[divider].indexOf(',') === -1) { 12412 console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); 12413 } 12414 12415 // If divider is found, we divide the list of values and operands to divide 12416 // them by ofset X and Y. 12417 var splitRegex = /\s*,\s*|\s+/; 12418 var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; 12419 12420 // Convert the values with units to absolute pixels to allow our computations 12421 ops = ops.map(function (op, index) { 12422 // Most of the units rely on the orientation of the popper 12423 var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; 12424 var mergeWithPrevious = false; 12425 return op 12426 // This aggregates any `+` or `-` sign that aren't considered operators 12427 // e.g.: 10 + +5 => [10, +, +5] 12428 .reduce(function (a, b) { 12429 if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { 12430 a[a.length - 1] = b; 12431 mergeWithPrevious = true; 12432 return a; 12433 } else if (mergeWithPrevious) { 12434 a[a.length - 1] += b; 12435 mergeWithPrevious = false; 12436 return a; 12437 } else { 12438 return a.concat(b); 12439 } 12440 }, []) 12441 // Here we convert the string values into number values (in px) 12442 .map(function (str) { 12443 return toValue(str, measurement, popperOffsets, referenceOffsets); 12444 }); 12445 }); 12446 12447 // Loop trough the offsets arrays and execute the operations 12448 ops.forEach(function (op, index) { 12449 op.forEach(function (frag, index2) { 12450 if (isNumeric(frag)) { 12451 offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); 12452 } 12453 }); 12454 }); 12455 return offsets; 12456} 12457 12458/** 12459 * @function 12460 * @memberof Modifiers 12461 * @argument {Object} data - The data object generated by update method 12462 * @argument {Object} options - Modifiers configuration and options 12463 * @argument {Number|String} options.offset=0 12464 * The offset value as described in the modifier description 12465 * @returns {Object} The data object, properly modified 12466 */ 12467function offset(data, _ref) { 12468 var offset = _ref.offset; 12469 var placement = data.placement, 12470 _data$offsets = data.offsets, 12471 popper = _data$offsets.popper, 12472 reference = _data$offsets.reference; 12473 12474 var basePlacement = placement.split('-')[0]; 12475 12476 var offsets = void 0; 12477 if (isNumeric(+offset)) { 12478 offsets = [+offset, 0]; 12479 } else { 12480 offsets = parseOffset(offset, popper, reference, basePlacement); 12481 } 12482 12483 if (basePlacement === 'left') { 12484 popper.top += offsets[0]; 12485 popper.left -= offsets[1]; 12486 } else if (basePlacement === 'right') { 12487 popper.top += offsets[0]; 12488 popper.left += offsets[1]; 12489 } else if (basePlacement === 'top') { 12490 popper.left += offsets[0]; 12491 popper.top -= offsets[1]; 12492 } else if (basePlacement === 'bottom') { 12493 popper.left += offsets[0]; 12494 popper.top += offsets[1]; 12495 } 12496 12497 data.popper = popper; 12498 return data; 12499} 12500 12501/** 12502 * @function 12503 * @memberof Modifiers 12504 * @argument {Object} data - The data object generated by `update` method 12505 * @argument {Object} options - Modifiers configuration and options 12506 * @returns {Object} The data object, properly modified 12507 */ 12508function preventOverflow(data, options) { 12509 var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); 12510 12511 // If offsetParent is the reference element, we really want to 12512 // go one step up and use the next offsetParent as reference to 12513 // avoid to make this modifier completely useless and look like broken 12514 if (data.instance.reference === boundariesElement) { 12515 boundariesElement = getOffsetParent(boundariesElement); 12516 } 12517 12518 // NOTE: DOM access here 12519 // resets the popper's position so that the document size can be calculated excluding 12520 // the size of the popper element itself 12521 var transformProp = getSupportedPropertyName('transform'); 12522 var popperStyles = data.instance.popper.style; // assignment to help minification 12523 var top = popperStyles.top, 12524 left = popperStyles.left, 12525 transform = popperStyles[transformProp]; 12526 12527 popperStyles.top = ''; 12528 popperStyles.left = ''; 12529 popperStyles[transformProp] = ''; 12530 12531 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); 12532 12533 // NOTE: DOM access here 12534 // restores the original style properties after the offsets have been computed 12535 popperStyles.top = top; 12536 popperStyles.left = left; 12537 popperStyles[transformProp] = transform; 12538 12539 options.boundaries = boundaries; 12540 12541 var order = options.priority; 12542 var popper = data.offsets.popper; 12543 12544 var check = { 12545 primary: function primary(placement) { 12546 var value = popper[placement]; 12547 if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { 12548 value = Math.max(popper[placement], boundaries[placement]); 12549 } 12550 return defineProperty({}, placement, value); 12551 }, 12552 secondary: function secondary(placement) { 12553 var mainSide = placement === 'right' ? 'left' : 'top'; 12554 var value = popper[mainSide]; 12555 if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { 12556 value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); 12557 } 12558 return defineProperty({}, mainSide, value); 12559 } 12560 }; 12561 12562 order.forEach(function (placement) { 12563 var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; 12564 popper = _extends({}, popper, check[side](placement)); 12565 }); 12566 12567 data.offsets.popper = popper; 12568 12569 return data; 12570} 12571 12572/** 12573 * @function 12574 * @memberof Modifiers 12575 * @argument {Object} data - The data object generated by `update` method 12576 * @argument {Object} options - Modifiers configuration and options 12577 * @returns {Object} The data object, properly modified 12578 */ 12579function shift(data) { 12580 var placement = data.placement; 12581 var basePlacement = placement.split('-')[0]; 12582 var shiftvariation = placement.split('-')[1]; 12583 12584 // if shift shiftvariation is specified, run the modifier 12585 if (shiftvariation) { 12586 var _data$offsets = data.offsets, 12587 reference = _data$offsets.reference, 12588 popper = _data$offsets.popper; 12589 12590 var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; 12591 var side = isVertical ? 'left' : 'top'; 12592 var measurement = isVertical ? 'width' : 'height'; 12593 12594 var shiftOffsets = { 12595 start: defineProperty({}, side, reference[side]), 12596 end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) 12597 }; 12598 12599 data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); 12600 } 12601 12602 return data; 12603} 12604 12605/** 12606 * @function 12607 * @memberof Modifiers 12608 * @argument {Object} data - The data object generated by update method 12609 * @argument {Object} options - Modifiers configuration and options 12610 * @returns {Object} The data object, properly modified 12611 */ 12612function hide(data) { 12613 if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { 12614 return data; 12615 } 12616 12617 var refRect = data.offsets.reference; 12618 var bound = find(data.instance.modifiers, function (modifier) { 12619 return modifier.name === 'preventOverflow'; 12620 }).boundaries; 12621 12622 if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { 12623 // Avoid unnecessary DOM access if visibility hasn't changed 12624 if (data.hide === true) { 12625 return data; 12626 } 12627 12628 data.hide = true; 12629 data.attributes['x-out-of-boundaries'] = ''; 12630 } else { 12631 // Avoid unnecessary DOM access if visibility hasn't changed 12632 if (data.hide === false) { 12633 return data; 12634 } 12635 12636 data.hide = false; 12637 data.attributes['x-out-of-boundaries'] = false; 12638 } 12639 12640 return data; 12641} 12642 12643/** 12644 * @function 12645 * @memberof Modifiers 12646 * @argument {Object} data - The data object generated by `update` method 12647 * @argument {Object} options - Modifiers configuration and options 12648 * @returns {Object} The data object, properly modified 12649 */ 12650function inner(data) { 12651 var placement = data.placement; 12652 var basePlacement = placement.split('-')[0]; 12653 var _data$offsets = data.offsets, 12654 popper = _data$offsets.popper, 12655 reference = _data$offsets.reference; 12656 12657 var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; 12658 12659 var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; 12660 12661 popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); 12662 12663 data.placement = getOppositePlacement(placement); 12664 data.offsets.popper = getClientRect(popper); 12665 12666 return data; 12667} 12668 12669/** 12670 * Modifier function, each modifier can have a function of this type assigned 12671 * to its `fn` property.<br /> 12672 * These functions will be called on each update, this means that you must 12673 * make sure they are performant enough to avoid performance bottlenecks. 12674 * 12675 * @function ModifierFn 12676 * @argument {dataObject} data - The data object generated by `update` method 12677 * @argument {Object} options - Modifiers configuration and options 12678 * @returns {dataObject} The data object, properly modified 12679 */ 12680 12681/** 12682 * Modifiers are plugins used to alter the behavior of your poppers.<br /> 12683 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities 12684 * needed by the library. 12685 * 12686 * Usually you don't want to override the `order`, `fn` and `onLoad` props. 12687 * All the other properties are configurations that could be tweaked. 12688 * @namespace modifiers 12689 */ 12690var modifiers = { 12691 /** 12692 * Modifier used to shift the popper on the start or end of its reference 12693 * element.<br /> 12694 * It will read the variation of the `placement` property.<br /> 12695 * It can be one either `-end` or `-start`. 12696 * @memberof modifiers 12697 * @inner 12698 */ 12699 shift: { 12700 /** @prop {number} order=100 - Index used to define the order of execution */ 12701 order: 100, 12702 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12703 enabled: true, 12704 /** @prop {ModifierFn} */ 12705 fn: shift 12706 }, 12707 12708 /** 12709 * The `offset` modifier can shift your popper on both its axis. 12710 * 12711 * It accepts the following units: 12712 * - `px` or unit
12712less, interpreted as pixels 12713 * - `%` or `%r`, percentage relative to the length of the reference element 12714 * - `%p`, percentage relative to the length of the popper element 12715 * - `vw`, CSS viewport width unit 12716 * - `vh`, CSS viewport height unit 12717 * 12718 * For length is intended the main axis relative to the placement of the popper.<br /> 12719 * This means that if the placement is `top` or `bottom`, the length will be the 12720 * `width`. In case of `left` or `right`, it will be the height. 12721 * 12722 * You can provide a single value (as `Number` or `String`), or a pair of values 12723 * as `String` divided by a comma or one (or more) white spaces.<br /> 12724 * The latter is a deprecated method because it leads to confusion and will be 12725 * removed in v2.<br /> 12726 * Additionally, it accepts additions and subtractions between different units. 12727 * Note that multiplications and divisions aren't supported. 12728 * 12729 * Valid examples are: 12730 * ``` 12731 * 10 12732 * '10%' 12733 * '10, 10' 12734 * '10%, 10' 12735 * '10 + 10%' 12736 * '10 - 5vh + 3%' 12737 * '-10px + 5vh, 5px - 6%' 12738 * ``` 12739 * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap 12740 * > with their reference element, unfortunately, you will have to disable the `flip` modifier. 12741 * > More on this [reading this issue](https://github.com/FezVrasta/popper.js/issues/373) 12742 * 12743 * @memberof modifiers 12744 * @inner 12745 */ 12746 offset: { 12747 /** @prop {number} order=200 - Index used to define the order of execution */ 12748 order: 200, 12749 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12750 enabled: true, 12751 /** @prop {ModifierFn} */ 12752 fn: offset, 12753 /** @prop {Number|String} offset=0 12754 * The offset value as described in the modifier description 12755 */ 12756 offset: 0 12757 }, 12758 12759 /** 12760 * Modifier used to prevent the popper from being positioned outside the boundary. 12761 * 12762 * An scenario exists where the reference itself is not within the boundaries.<br /> 12763 * We can say it has "escaped the boundaries" — or just "escaped".<br /> 12764 * In this case we need to decide whether the popper should either: 12765 * 12766 * - detach from the reference and remain "trapped" in the boundaries, or 12767 * - if it should ignore the boundary and "escape with its reference" 12768 * 12769 * When `escapeWithReference` is set to`true` and reference is completely 12770 * outside its boundaries, the popper will overflow (or completely leave) 12771 * the boundaries in order to remain attached to the edge of the reference. 12772 * 12773 * @memberof modifiers 12774 * @inner 12775 */ 12776 preventOverflow: { 12777 /** @prop {number} order=300 - Index used to define the order of execution */ 12778 order: 300, 12779 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12780 enabled: true, 12781 /** @prop {ModifierFn} */ 12782 fn: preventOverflow, 12783 /** 12784 * @prop {Array} [priority=['left','right','top','bottom']] 12785 * Popper will try to prevent overflow following these priorities by default, 12786 * then, it could overflow on the left and on top of the `boundariesElement` 12787 */ 12788 priority: ['left', 'right', 'top', 'bottom'], 12789 /** 12790 * @prop {number} padding=5 12791 * Amount of pixel used to define a minimum distance between the boundaries 12792 * and the popper this makes sure the popper has always a little padding 12793 * between the edges of its container 12794 */ 12795 padding: 5, 12796 /** 12797 * @prop {String|HTMLElement} boundariesElement='scrollParent' 12798 * Boundaries used by the modifier, can be `scrollParent`, `window`, 12799 * `viewport` or any DOM element. 12800 */ 12801 boundariesElement: 'scrollParent' 12802 }, 12803 12804 /** 12805 * Modifier used to make sure the reference and its popper stay near eachothers 12806 * without leaving any gap between the two. Expecially useful when the arrow is 12807 * enabled and you want to assure it to point to its reference element. 12808 * It cares only about the first axis, you can still have poppers with margin 12809 * between the popper and its reference element. 12810 * @memberof modifiers 12811 * @inner 12812 */ 12813 keepTogether: { 12814 /** @prop {number} order=400 - Index used to define the order of execution */ 12815 order: 400, 12816 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12817 enabled: true, 12818 /** @prop {ModifierFn} */ 12819 fn: keepTogether 12820 }, 12821 12822 /** 12823 * This modifier is used to move the `arrowElement` of the popper to make 12824 * sure it is positioned between the reference element and its popper element. 12825 * It will read the outer size of the `arrowElement` node to detect how many 12826 * pixels of conjuction are needed. 12827 * 12828 * It has no effect if no `arrowElement` is provided. 12829 * @memberof modifiers 12830 * @inner 12831 */ 12832 arrow: { 12833 /** @prop {number} order=500 - Index used to define the order of execution */ 12834 order: 500, 12835 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12836 enabled: true, 12837 /** @prop {ModifierFn} */ 12838 fn: arrow, 12839 /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ 12840 element: '[x-arrow]' 12841 }, 12842 12843 /** 12844 * Modifier used to flip the popper's placement when it starts to overlap its 12845 * reference element. 12846 * 12847 * Requires the `preventOverflow` modifier before it in order to work. 12848 * 12849 * **NOTE:** this modifier will interrupt the current update cycle and will 12850 * restart it if it detects the need to flip the placement. 12851 * @memberof modifiers 12852 * @inner 12853 */ 12854 flip: { 12855 /** @prop {number} order=600 - Index used to define the order of execution */ 12856 order: 600, 12857 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12858 enabled: true, 12859 /** @prop {ModifierFn} */ 12860 fn: flip, 12861 /** 12862 * @prop {String|Array} behavior='flip' 12863 * The behavior used to change the popper's placement. It can be one of 12864 * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid 12865 * placements (with optional variations). 12866 */ 12867 behavior: 'flip', 12868 /** 12869 * @prop {number} padding=5 12870 * The popper will flip if it hits the edges of the `boundariesElement` 12871 */ 12872 padding: 5, 12873 /** 12874 * @prop {String|HTMLElement} boundariesElement='viewport' 12875 * The element which will define the boundaries of the popper position, 12876 * the popper will never be placed outside of the defined boundaries 12877 * (except if keepTogether is enabled) 12878 */ 12879 boundariesElement: 'viewport' 12880 }, 12881 12882 /** 12883 * Modifier used to make the popper flow toward the inner of the reference element. 12884 * By default, when this modifier is disabled, the popper will be placed outside 12885 * the reference element. 12886 * @memberof modifiers 12887 * @inner 12888 */ 12889 inner: { 12890 /** @prop {number} order=700 - Index used to define the order of execution */ 12891 order: 700, 12892 /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ 12893 enabled: false, 12894 /** @prop {ModifierFn} */ 12895 fn: inner 12896 }, 12897 12898 /** 12899 * Modifier used to hide the popper when its reference element is outside of the 12900 * popper boundaries. It will set a `x-out-of-boundaries` attribute which can 12901 * be used to hide with a CSS selector the popper when its reference is 12902 * out of boundaries. 12903 * 12904 * Requires the `preventOverflow` modifier before it in order to work. 12905 * @memberof modifiers 12906 * @inner 12907 */ 12908 hide: { 12909 /** @prop {number} order=800 - Index used to define the order of execution */ 12910 order: 800, 12911 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12912 enabled: true, 12913 /** @prop {ModifierFn} */ 12914 fn: hide 12915 }, 12916 12917 /** 12918 * Computes the style that will be applied to the popper element to gets 12919 * properly positioned. 12920 * 12921 * Note that this modifier will not touch the DOM, it just prepares the styles 12922 * so that `applyStyle` modifier can apply it. This separation is useful 12923 * in case you need to replace `applyStyle` with a custom implementation. 12924 * 12925 * This modifier has `850` as `order` value to maintain backward compatibility 12926 * with previous versions of Popper.js. Expect the modifiers ordering method 12927 * to change in future major versions of the library. 12928 * 12929 * @memberof modifiers 12930 * @inner 12931 */ 12932 computeStyle: { 12933 /** @prop {number} order=850 - Index used to define the order of execution */ 12934 order: 850, 12935 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12936 enabled: true, 12937 /** @prop {ModifierFn} */ 12938 fn: computeStyle, 12939 /** 12940 * @prop {Boolean} gpuAcceleration=true 12941 * If true, it uses the CSS 3d transformation to position the popper. 12942 * Otherwise, it will use the `top` and `left` properties. 12943 */ 12944 gpuAcceleration: true, 12945 /** 12946 * @prop {string} [x='bottom'] 12947 * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. 12948 * Change this if your popper should grow in a direction different from `bottom` 12949 */ 12950 x: 'bottom', 12951 /** 12952 * @prop {string} [x='left'] 12953 * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. 12954 * Change this if your popper should grow in a direction different from `right` 12955 */ 12956 y: 'right' 12957 }, 12958 12959 /** 12960 * Applies the computed styles to the popper element. 12961 * 12962 * All the DOM manipulations are limited to this modifier. This is useful in case 12963 * you want to integrate Popper.js inside a framework or view library and you 12964 * want to delegate all the DOM manipulations to it. 12965 * 12966 * Note that if you disable this modifier, you must make sure the popper element 12967 * has its position set to `absolute` before Popper.js can do its work! 12968 * 12969 * Just disable this modifier and define you own to achieve the desired effect. 12970 * 12971 * @memberof modifiers 12972 * @inner 12973 */ 12974 applyStyle: { 12975 /** @prop {number} order=900 - Index used to define the order of execution */ 12976 order: 900, 12977 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 12978 enabled: true, 12979 /** @prop {ModifierFn} */
vendor: 4,801 bytes, lines 12980-13118
12980 fn: applyStyle, 12981 /** @prop {Function} */ 12982 onLoad: applyStyleOnLoad, 12983 /** 12984 * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier 12985 * @prop {Boolean} gpuAcceleration=true 12986 * If true, it uses the CSS 3d transformation to position the popper. 12987 * Otherwise, it will use the `top` and `left` properties. 12988 */ 12989 gpuAcceleration: undefined 12990 } 12991}; 12992 12993/** 12994 * The `dataObject` is an object containing all the informations used by Popper.js 12995 * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks. 12996 * @name dataObject 12997 * @property {Object} data.instance The Popper.js instance 12998 * @property {String} data.placement Placement applied to popper 12999 * @property {String} data.originalPlacement Placement originally defined on init 13000 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier 13001 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper. 13002 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier 13003 * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`) 13004 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow, it expects the JavaScript nomenclature (eg. `marginBottom`) 13005 * @property {Object} data.boundaries Offsets of the popper boundaries 13006 * @property {Object} data.offsets The measurements of popper, reference and arrow elements. 13007 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values 13008 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values 13009 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 13010 */ 13011 13012/** 13013 * Default options provided to Popper.js constructor.<br /> 13014 * These can be overriden using the `options` argument of Popper.js.<br /> 13015 * To override an option, simply pass as 3rd argument an object with the same 13016 * structure of this object, example: 13017 * ``` 13018 * new Popper(ref, pop, { 13019 * modifiers: { 13020 * preventOverflow: { enabled: false } 13021 * } 13022 * }) 13023 * ``` 13024 * @type {Object} 13025 * @static 13026 * @memberof Popper 13027 */ 13028var Defaults = { 13029 /** 13030 * Popper's placement 13031 * @prop {Popper.placements} placement='bottom' 13032 */ 13033 placement: 'bottom', 13034 13035 /** 13036 * Set this to true if you want popper to position it self in 'fixed' mode 13037 * @prop {Boolean} positionFixed=false 13038 */ 13039 positionFixed: false, 13040 13041 /** 13042 * Whether events (resize, scroll) are initially enabled 13043 * @prop {Boolean} eventsEnabled=true 13044 */ 13045 eventsEnabled: true, 13046 13047 /** 13048 * Set to true if you want to automatically remove the popper when 13049 * you call the `destroy` method. 13050 * @prop {Boolean} removeOnDestroy=false 13051 */ 13052 removeOnDestroy: false, 13053 13054 /** 13055 * Callback called when the popper is created.<br /> 13056 * By default, is set to no-op.<br /> 13057 * Access Popper.js instance with `data.instance`. 13058 * @prop {onCreate} 13059 */ 13060 onCreate: function onCreate() {}, 13061 13062 /** 13063 * Callback called when the popper is updated, this callback is not called 13064 * on the initialization/creation of the popper, but only on subsequent 13065 * updates.<br /> 13066 * By default, is set to no-op.<br /> 13067 * Access Popper.js instance with `data.instance`. 13068 * @prop {onUpdate} 13069 */ 13070 onUpdate: function onUpdate() {}, 13071 13072 /** 13073 * List of modifiers used to modify the offsets before they are applied to the popper. 13074 * They provide most of the functionalities of Popper.js 13075 * @prop {modifiers} 13076 */ 13077 modifiers: modifiers 13078}; 13079 13080/** 13081 * @callback onCreate 13082 * @param {dataObject} data 13083 */ 13084 13085/** 13086 * @callback onUpdate 13087 * @param {dataObject} data 13088 */ 13089 13090// Utils 13091// Methods 13092var Popper = function () { 13093 /** 13094 * Create a new Popper.js instance 13095 * @class Popper 13096 * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper 13097 * @param {HTMLElement} popper - The HTML element used as popper. 13098 * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) 13099 * @return {Object} instance - The generated Popper.js instance 13100 */ 13101 function Popper(reference, popper) { 13102 var _this = this; 13103 13104 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 13105 classCallCheck(this, Popper); 13106 13107 this.scheduleUpdate = function () { 13108 return requestAnimationFrame(_this.update); 13109 }; 13110 13111 // make update() debounced, so that it only runs at most once-per-tick 13112 this.update = debounce(this.update.bind(this)); 13113 13114 // with {} we create a new object with the options inside it 13115 this.options = _extends({}, Popper.Defaults, options); 13116 13117 // init state 13118 this.state = {
vendor: 4,355 bytes, lines 13119-13250
13119 isDestroyed: false, 13120 isCreated: false, 13121 scrollParents: [] 13122 }; 13123 13124 // get reference and popper elements (allow jQuery wrappers) 13125 this.reference = reference && reference.jquery ? reference[0] : reference; 13126 this.popper = popper && popper.jquery ? popper[0] : popper; 13127 13128 // Deep merge modifiers options 13129 this.options.modifiers = {}; 13130 Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { 13131 _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); 13132 }); 13133 13134 // Refactoring modifiers' list (Object => Array) 13135 this.modifiers = Object.keys(this.options.modifiers).map(function (name) { 13136 return _extends({ 13137 name: name 13138 }, _this.options.modifiers[name]); 13139 }) 13140 // sort the modifiers by order 13141 .sort(function (a, b) { 13142 return a.order - b.order; 13143 }); 13144 13145 // modifiers have the ability to execute arbitrary code when Popper.js get inited 13146 // such code is executed in the same order of its modifier 13147 // they could add new properties to their options configuration 13148 // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! 13149 this.modifiers.forEach(function (modifierOptions) { 13150 if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { 13151 modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); 13152 } 13153 }); 13154 13155 // fire the first update to position the popper in the right place 13156 this.update(); 13157 13158 var eventsEnabled = this.options.eventsEnabled; 13159 if (eventsEnabled) { 13160 // setup event listeners, they will take care of update the position in specific situations 13161 this.enableEventListeners(); 13162 } 13163 13164 this.state.eventsEnabled = eventsEnabled; 13165 } 13166 13167 // We can't use class properties because they don't get listed in the 13168 // class prototype and break stuff like Sinon stubs 13169 13170 13171 createClass(Popper, [{ 13172 key: 'update', 13173 value: function update$$1() { 13174 return update.call(this); 13175 } 13176 }, { 13177 key: 'destroy', 13178 value: function destroy$$1() { 13179 return destroy.call(this); 13180 } 13181 }, { 13182 key: 'enableEventListeners', 13183 value: function enableEventListeners$$1() { 13184 return enableEventListeners.call(this); 13185 } 13186 }, { 13187 key: 'disableEventListeners', 13188 value: function disableEventListeners$$1() { 13189 return disableEventListeners.call(this); 13190 } 13191 13192 /** 13193 * Schedule an update, it will run on the next UI update available 13194 * @method scheduleUpdate 13195 * @memberof Popper 13196 */ 13197 13198 13199 /** 13200 * Collection of utilities useful when writing custom modifiers. 13201 * Starting from version 1.7, this method is available only if you 13202 * include `popper-utils.js` before `popper.js`. 13203 * 13204 * **DEPRECATION**: This way to access PopperUtils is deprecated 13205 * and will be removed in v2! Use the PopperUtils module directly instead. 13206 * Due to the high instability of the methods contained in Utils, we can't 13207 * guarantee them to follow semver. Use them at your own risk! 13208 * @static 13209 * @private 13210 * @type {Object} 13211 * @deprecated since version 1.8 13212 * @member Utils 13213 * @memberof Popper 13214 */ 13215 13216 }]); 13217 return Popper; 13218}(); 13219 13220/** 13221 * The `referenceObject` is an object that provides an interface compatible with Popper.js 13222 * and lets you use it as replacement of a real DOM node.<br /> 13223 * You can use this method to position a popper relatively to a set of coordinates 13224 * in case you don't have a DOM node to use as reference. 13225 * 13226 * ``` 13227 * new Popper(referenceObject, popperNode); 13228 * ``` 13229 * 13230 * NB: This feature isn't supported in Internet Explorer 10 13231 * @name referenceObject 13232 * @property {Function} data.getBoundingClientRect 13233 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. 13234 * @property {number} data.clientWidth 13235 * An ES6 getter that will return the width of the virtual reference element. 13236 * @property {number} data.clientHeight 13237 * An ES6 getter that will return the height of the virtual reference element. 13238 */ 13239 13240 13241Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; 13242Popper.placements = placements; 13243Popper.Defaults = Defaults; 13244 13245return Popper; 13246 13247}))); 13248//# sourceMappingURL=popper.js.map 13249 13250;
vendor: 122,971 bytes, lines 13250-16417
13250/* Javascript plotting library for jQuery, version 0.8.3. 13251 13252Copyright (c) 2007-2014 IOLA and Ole Laursen. 13253Licensed under the MIT license. 13254 13255*/ 13256 13257// first an inline dependency, jquery.colorhelpers.js, we inline it here 13258// for convenience 13259 13260/* Plugin for jQuery for working with colors. 13261 * 13262 * Version 1.1. 13263 * 13264 * Inspiration from jQuery color animation plugin by John Resig. 13265 * 13266 * Released under the MIT license by Ole Laursen, October 2009. 13267 * 13268 * Examples: 13269 * 13270 * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() 13271 * var c = $.color.extract($("#mydiv"), 'background-color'); 13272 * console.log(c.r, c.g, c.b, c.a); 13273 * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" 13274 * 13275 * Note that .scale() and .add() return the same modified object 13276 * instead of making a new one. 13277 * 13278 * V. 1.1: Fix error handling so e.g. parsing an empty string does 13279 * produce a color rather than just crashing. 13280 */ 13281(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); 13282 13283// the actual Flot code 13284(function($) { 13285 13286 // Cache the prototype hasOwnProperty for faster access 13287 13288 var hasOwnProperty = Object.prototype.hasOwnProperty; 13289 13290 // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM 13291 // operation produces the same effect as detach, i.e. removing the element 13292 // without touching its jQuery data. 13293 13294 // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+. 13295 13296 if (!$.fn.detach) { 13297 $.fn.detach = function() { 13298 return this.each(function() { 13299 if (this.parentNode) { 13300 this.parentNode.removeChild( this ); 13301 } 13302 }); 13303 }; 13304 } 13305 13306 /////////////////////////////////////////////////////////////////////////// 13307 // The Canvas object is a wrapper around an HTML5 <canvas> tag. 13308 // 13309 // @constructor 13310 // @param {string} cls List of classes to apply to the canvas. 13311 // @param {element} container Element onto which to append the canvas. 13312 // 13313 // Requiring a container is a little iffy, but unfortunately canvas 13314 // operations don't work unless the canvas is attached to the DOM. 13315 13316 function Canvas(cls, container) { 13317 13318 var element = container.children("." + cls)[0]; 13319 13320 if (element == null) { 13321 13322 element = document.createElement("canvas"); 13323 element.className = cls; 13324 13325 $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 }) 13326 .appendTo(container); 13327 13328 // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas 13329 13330 if (!element.getContext) { 13331 if (window.G_vmlCanvasManager) { 13332 element = window.G_vmlCanvasManager.initElement(element); 13333 } else { 13334 throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode."); 13335 } 13336 } 13337 } 13338 13339 this.element = element; 13340 13341 var context = this.context = element.getContext("2d"); 13342 13343 // Determine the screen's ratio of physical to device-independent 13344 // pixels. This is the ratio between the canvas width that the browser 13345 // advertises and the number of pixels actually present in that space. 13346 13347 // The iPhone 4, for example, has a device-independent width of 320px, 13348 // but its screen is actually 640px wide. It therefore has a pixel 13349 // ratio of 2, while most normal devices have a ratio of 1. 13350 13351 var devicePixelRatio = window.devicePixelRatio || 1, 13352 backingStoreRatio = 13353 context.webkitBackingStorePixelRatio || 13354 context.mozBackingStorePixelRatio || 13355 context.msBackingStorePixelRatio || 13356 context.oBackingStorePixelRatio || 13357 context.backingStorePixelRatio || 1; 13358 13359 this.pixelRatio = devicePixelRatio / backingStoreRatio; 13360 13361 // Size the canvas to match the internal dimensions of its container 13362 13363 this.resize(container.width(), container.height()); 13364 13365 // Collection of HTML div layers for text overlaid onto the canvas 13366 13367 this.textContainer = null; 13368 this.text = {}; 13369 13370 // Cache of text fragments and metrics, so we can avoid expensively 13371 // re-calculating them when the plot is re-rendered in a loop. 13372 13373 this._textCache = {}; 13374 } 13375 13376 // Resizes the canvas to the given dimensions. 13377 // 13378 // @param {number} width New width of the canvas, in pixels. 13379 // @param {number} width New height of the canvas, in pixels. 13380 13381 Canvas.prototype.resize = function(width, height) { 13382 13383 if (width <= 0 || height <= 0) { 13384 throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height); 13385 } 13386 13387 var element = this.element, 13388 context = this.context, 13389 pixelRatio = this.pixelRatio; 13390 13391 // Resize the canvas, increasing its density based on the display's 13392 // pixel ratio; basically giving it more pixels without increasing the 13393 // size of its element, to take advantage of the fact that retina 13394 // displays have that many more pixels in the same advertised space. 13395 13396 // Resizing should reset the state (excanvas seems to be buggy though) 13397 13398 if (this.width != width) { 13399 element.width = width * pixelRatio; 13400 element.style.width = width + "px"; 13401 this.width = width; 13402 } 13403 13404 if (this.height != height) { 13405 element.height = height * pixelRatio; 13406 element.style.height = height + "px"; 13407 this.height = height; 13408 } 13409 13410 // Save the context, so we can reset in case we get replotted. The 13411 // restore ensure that we're really back at the initial state, and 13412 // should be safe even if we haven't saved the initial state yet. 13413 13414 context.restore(); 13415 context.save(); 13416 13417 // Scale the coordinate space to match the display density; so even though we 13418 // may have twice as many pixels, we still want lines and other drawing to 13419 // appear at the same size; the extra pixels will just make them crisper. 13420 13421 context.scale(pixelRatio, pixelRatio); 13422 }; 13423 13424 // Clears the entire canvas area, not including any overlaid HTML text 13425 13426 Canvas.prototype.clear = function() { 13427 this.context.clearRect(0, 0, this.width, this.height); 13428 }; 13429 13430 // Finishes rendering the canvas, including managing the text overlay. 13431 13432 Canvas.prototype.render = function() { 13433 13434 var cache = this._textCache; 13435 13436 // For each text layer, add elements marked as active that haven't 13437 // already been rendered, and remove those that are no longer active. 13438 13439 for (var layerKey in cache) { 13440 if (hasOwnProperty.call(cache, layerKey)) { 13441 13442 var layer = this.getTextLayer(layerKey), 13443 layerCache = cache[layerKey]; 13444 13445 layer.hide(); 13446 13447 for (var styleKey in layerCache) { 13448 if (hasOwnProperty.call(layerCache, styleKey)) { 13449 var styleCache = layerCache[styleKey]; 13450 for (var key in styleCache) { 13451 if (hasOwnProperty.call(styleCache, key)) { 13452 13453 var positions = styleCache[key].positions; 13454 13455 for (var i = 0, position; position = positions[i]; i++) { 13456 if (position.active) { 13457 if (!position.rendered) { 13458 layer.append(position.element); 13459 position.rendered = true; 13460 } 13461 } else { 13462 positions.splice(i--, 1); 13463 if (position.rendered) { 13464 position.element.detach(); 13465 } 13466 } 13467 } 13468 13469 if (positions.length == 0) { 13470 delete styleCache[key]; 13471 } 13472 } 13473 } 13474 } 13475 } 13476 13477 layer.show(); 13478 } 13479 } 13480 }; 13481 13482 // Creates (if necessary) and returns the text overlay container. 13483 // 13484 // @param {string} classes String of space-separated CSS classes used to 13485 // uniquely identify the text layer. 13486 // @return {object} The jQuery-wrapped text-layer div. 13487 13488 Canvas.prototype.getTextLayer = function(classes) { 13489 13490 var layer = this.text[classes]; 13491 13492 // Create the text layer if it doesn't exist 13493 13494 if (layer == null) { 13495 13496 // Create the text layer container, if it doesn't exist 13497 13498 if (this.textContainer == null) { 13499 this.textContainer = $("<div class='flot-text'></div>") 13500 .css({ 13501 position: "absolute", 13502 top: 0, 13503 left: 0, 13504 bottom: 0, 13505 right: 0, 13506 'font-size': "smaller", 13507 color: "#545454" 13508 }) 13509 .insertAfter(this.element); 13510 } 13511 13512 layer = this.text[classes] = $("<div></div>") 13513 .addClass(classes) 13514 .css({ 13515 position: "absolute", 13516 top: 0, 13517 left: 0, 13518 bottom: 0, 13519 right: 0 13520 }) 13521 .appendTo(this.textContainer); 13522 } 13523 13524 return layer; 13525 }; 13526 13527 // Creates (if necessary) and returns a text info object. 13528 // 13529 // The object looks like this: 13530 // 13531 // { 13532 // width: Width of the text's wrapper div. 13533 // height: Height of the text's wrapper div. 13534 // element: The jQuery-wrapped HTML div containing the text. 13535 // positions: Array of positions at which this text is drawn. 13536 // } 13537 // 13538 // The positions array contains objects that look like this: 13539 // 13540 // { 13541 // active: Flag indicating whether the text should be visible. 13542 // rendered: Flag indicating whether the text is currently visible. 13543 // element: The jQuery-wrapped HTML div containing the text. 13544 // x: X coordinate at which to draw the text. 13545 // y: Y coordinate at which to draw the text. 13546 // } 13547 // 13548 // Each position after the first receives a clone of the original element. 13549 // 13550 // The idea is that that the width, height, and general 'identity' of the 13551 // text is constant no matter where it is placed; the placements are a 13552 // secondary property. 13553 // 13554 // Canvas maintains a cache of recently-used text info objects; getTextInfo 13555 // either returns the cached element or creates a new entry. 13556 // 13557 // @param {string} layer A string of space-separated CSS classes uniquely 13558 // identifying the layer containing this text. 13559 // @param {string} text Text string to retrieve info for. 13560 // @param {(string|object)=} font Either a string of space-separated CSS 13561 // classes or a font-spec object, defining the text's font and style. 13562 // @param {number=} angle Angle at which to rotate the text, in degrees. 13563 // Angle is currently unused, it will be implemented in the future. 13564 // @param {number=} width Maximum width of the text before it wraps. 13565 // @return {object} a text info object. 13566 13567 Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { 13568 13569 var textStyle, layerCache, styleCache, info; 13570 13571 // Cast the value to a string, in case we were given a number or such 13572 13573 text = "" + text; 13574 13575 // If the font is a font-spec object, generate a CSS font definition 13576 13577 if (typeof font === "object") { 13578 textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family; 13579 } else { 13580 textStyle = font; 13581 } 13582 13583 // Retrieve (or create) the cache for the text's layer and styles 13584 13585 layerCache = this._textCache[layer]; 13586 13587 if (layerCache == null) { 13588 layerCache = this._textCache[layer] = {}; 13589 } 13590 13591 styleCache = layerCache[textStyle]; 13592 13593 if (styleCache == null) { 13594 styleCache = layerCache[textStyle] = {}; 13595 } 13596 13597 info = styleCache[text]; 13598 13599 // If we can't find a matching element in our cache, create a new one 13600 13601 if (info == null) { 13602 13603 var element = $("<div></div>").html(text) 13604 .css({ 13605 position: "absolute", 13606 'max-width': width, 13607 top: -9999 13608 }) 13609 .appendTo(this.getTextLayer(layer)); 13610 13611 if (typeof font === "object") { 13612 element.css({ 13613 font: textStyle, 13614 color: font.color 13615 }); 13616 } else if (typeof font === "string") { 13617 element.addClass(font); 13618 } 13619 13620 info = styleCache[text] = { 13621 width: element.outerWidth(true), 13622 height: element.outerHeight(true), 13623 element: element, 13624 positions: [] 13625 }; 13626 13627 element.detach(); 13628 } 13629 13630 return info; 13631 }; 13632 13633 // Adds a text string to the canvas text overlay. 13634 // 13635 // The text isn't drawn immediately; it is marked as rendering, which will 13636 // result in its addition to the canvas on the next render pass. 13637 // 13638 // @param {string} layer A string of space-separated CSS classes uniquely 13639 // identifying the layer containing this text. 13640 // @param {number} x X coordinate at which to draw the text. 13641 // @param {number} y Y coordinate at which to draw the text. 13642 // @param {string} text Text string to draw. 13643 // @param {(string|object)=} font Either a string of space-separated CSS 13644 // classes or a font-spec object, defining the text's font and style. 13645 // @param {number=} angle Angle at which to rotate the text, in degrees. 13646 // Angle is currently unused, it will be implemented in the future. 13647 // @param {number=} width Maximum width of the text before it wraps. 13648 // @param {string=} halign Horizontal alignment of the text; either "left", 13649 // "center" or "right". 13650 // @param {string=} valign Vertical alignment of the text; either "top", 13651 // "middle" or "bottom". 13652 13653 Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { 13654 13655 var info = this.getTextInfo(layer, text, font, angle, width), 13656 positions = info.positions; 13657 13658 // Tweak the div's position to match the text's alignment 13659 13660 if (halign == "center") { 13661 x -= info.width / 2; 13662 } else if (halign == "right") { 13663 x -= info.width; 13664 } 13665 13666 if (valign == "middle") { 13667 y -= info.height / 2; 13668 } else if (valign == "bottom") { 13669 y -= info.height; 13670 } 13671 13672 // Determine whether this text already exists at this position. 13673 // If so, mark it for inclusion in the next render pass. 13674 13675 for (var i = 0, position; position = positions[i]; i++) { 13676 if (position.x == x && position.y == y) { 13677 position.active = true; 13678 return; 13679 } 13680 } 13681 13682 // If the text doesn't exist at this position, create a new entry 13683 13684 // For the very first position we'll re-use the original element, 13685 // while for subsequent ones we'll clone it. 13686 13687 position = { 13688 active: true, 13689 rendered: false, 13690 element: positions.length ? info.element.clone() : info.element, 13691 x: x, 13692 y: y 13693 }; 13694 13695 positions.push(position); 13696 13697 // Move the element to its final position within the container 13698 13699 position.element.css({ 13700 top: Math.round(y), 13701 left: Math.round(x), 13702 'text-align': halign // In case the text wraps 13703 }); 13704 }; 13705 13706 // Removes one or more text strings from the canvas text overlay. 13707 // 13708 // If no parameters are given, all text within the layer is removed. 13709 // 13710 // Note that the text is not immediately removed; it is simply marked as 13711 // inactive, which will result in its removal on the next render pass. 13712 // This avoids the performance penalty for 'clear and redraw' behavior, 13713 // where we potentially get rid of all text on a layer, but will likely 13714 // add back most or all of it later, as when redrawing axes, for example. 13715 // 13716 // @param {string} layer A string of space-separated CSS classes uniquely 13717 // identifying the layer containing this text. 13718 // @param {number=} x X coordinate of the text. 13719 // @param {number=} y Y coordinate of the text. 13720 // @param {string=} text Text string to remove. 13721 // @param {(string|object)=} font Either a string of space-separated CSS 13722 // classes or a font-spec object, defining the text's font and style. 13723 // @param {number=} angle Angle at which the text is rotated, in degrees. 13724 // Angle is currently unused, it will be implemented in the future. 13725 13726 Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { 13727 if (text == null) { 13728 var layerCache = this._textCache[layer]; 13729 if (layerCache != null) { 13730 for (var styleKey in layerCache) { 13731 if (hasOwnProperty.call(layerCache, styleKey)) { 13732 var styleCache = layerCache[styleKey]; 13733 for (var key in styleCache) { 13734 if (hasOwnProperty.call(styleCache, key)) { 13735 var positions = styleCache[key].positions; 13736 for (var i = 0, position; position = positions[i]; i++) { 13737 position.active = false; 13738 } 13739 } 13740 } 13741 } 13742 } 13743 } 13744 } else { 13745 var positions = this.getTextInfo(layer, text, font, angle).positions; 13746 for (var i = 0, position; position = positions[i]; i++) { 13747 if (position.x == x && position.y == y) { 13748 position.active = false; 13749 } 13750 } 13751 } 13752 }; 13753 13754 /////////////////////////////////////////////////////////////////////////// 13755 // The top-level container for the entire plot. 13756 13757 function Plot(placeholder, data_, options_, plugins) { 13758 // data is on the form: 13759 // [ series1, series2 ... ] 13760 // where series is either just the data as [ [x1, y1], [x2, y2], ... ] 13761 // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } 13762 13763 var series = [], 13764 options = { 13765 // the color theme used for graphs 13766 colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], 13767 legend: { 13768 show: true, 13769 noColumns: 1, // number of colums in legend table 13770 labelFormatter: null, // fn: string -> string 13771 labelBoxBorderColor: "#ccc", // border color for the little label boxes 13772 container: null, // container (as jQuery object) to put legend in, null means default on top of graph 13773 position: "ne", // position of default legend container within plot 13774 margin: 5, // distance from grid edge to default legend container within plot 13775 backgroundColor: null, // null means auto-detect 13776 backgroundOpacity: 0.85, // set to 0 to avoid background 13777 sorted: null // default to no legend sorting 13778 }, 13779 xaxis: { 13780 show: null, // null = auto-detect, true = always, false = never 13781 position: "bottom", // or "top" 13782 mode: null, // null or "time" 13783 font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" } 13784 color: null, // base color, labels, ticks 13785 tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" 13786 transform: null, // null or f: number -> number to transform axis 13787 inverseTransform: null, // if transform is set, this should be the inverse function 13788 min: null, // min. value to show, null means set automatically 13789 max: null, // max. value to show, null means set automatically 13790 autoscaleMargin: null, // margin in % to add if auto-setting min/max 13791 ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks 13792 tickFormatter: null, // fn: number -> string 13793 labelWidth: null, // size of tick labels in pixels 13794 labelHeight: null, 13795 reserveSpace: null, // whether to reserve space even if axis isn't shown 13796 tickLength: null, // size in pixels of ticks, or "full" for whole line 13797 alignTicksWithAxis: null, // axis number or null for no sync 13798 tickDecimals: null, // no. of decimals, null means auto 13799 tickSize: null, // number or [number, "unit"] 13800 minTickSize: null // number or [number, "unit"] 13801 }, 13802 yaxis: { 13803 autoscaleMargin: 0.02, 13804 position: "left" // or "right" 13805 }, 13806 xaxes: [], 13807 yaxes: [], 13808 series: { 13809 points: { 13810 show: false, 13811 radius: 3, 13812 lineWidth: 2, // in pixels 13813 fill: true, 13814 fillColor: "#ffffff", 13815 symbol: "circle" // or callback 13816 }, 13817 lines: { 13818 // we don't put in show: false so we can see 13819 // whether lines were actively disabled 13820 lineWidth: 2, // in pixels 13821 fill: false, 13822 fillColor: null, 13823 steps: false 13824 // Omit 'zero', so we can later default its value to 13825 // match that of the 'fill' option. 13826 }, 13827 bars: { 13828 show: false, 13829 lineWidth: 2, // in pixels 13830 barWidth: 1, // in units of the x axis 13831 fill: true, 13832 fillColor: null, 13833 align: "left", // "left", "right", or "center" 13834 horizontal: false, 13835 zero: true 13836 }, 13837 shadowSize: 3, 13838 highlightColor: null 13839 }, 13840 grid: { 13841 show: true, 13842 aboveData: false, 13843 color: "#545454", // primary color used for outline and labels 13844 backgroundColor: null, // null for transparent, else color 13845 borderColor: null, // set if different from the grid color 13846 tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" 13847 margin: 0, // distance from the canvas edge to the grid 13848 labelMargin: 5, // in pixels 13849 axisMargin: 8, // in pixels 13850 borderWidth: 2, // in pixels 13851 minBorderMargin: null, // in pixels, null means taken from points radius 13852 markings: null, // array of ranges or fn: axes -> array of ranges 13853 markingsColor: "#f4f4f4", 13854 markingsLineWidth: 2, 13855 // interactive stuff 13856 clickable: false, 13857 hoverable: false, 13858 autoHighlight: true, // highlight in case mouse is near 13859 mouseActiveRadius: 10 // how far the mouse can be away to activate an item 13860 }, 13861 interaction: { 13862 redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow 13863 }, 13864 hooks: {} 13865 }, 13866 surface = null, // the canvas for the plot itself 13867 overlay = null, // canvas for interactive stuff on top of plot 13868 eventHolder = null, // jQuery object that events should be bound to 13869 ctx = null, octx = null, 13870 xaxes = [], yaxes = [], 13871 plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, 13872 plotWidth = 0, plotHeight = 0, 13873 hooks = { 13874 processOptions: [], 13875 processRawData: [], 13876 processDatapoints: [], 13877 processOffset: [], 13878 drawBackground: [], 13879 drawSeries: [], 13880 draw: [], 13881 bindEvents: [], 13882 drawOverlay: [], 13883 shutdown: [] 13884 }, 13885 plot = this; 13886 13887 // public functions 13888 plot.setData = setData; 13889 plot.setupGrid = setupGrid; 13890 plot.draw = draw; 13891 plot.getPlaceholder = function() { return placeholder; }; 13892 plot.getCanvas = function() { return surface.element; }; 13893 plot.getPlotOffset = function() { return plotOffset; }; 13894 plot.width = function () { return plotWidth; }; 13895 plot.height = function () { return plotHeight; }; 13896 plot.offset = function () { 13897 var o = eventHolder.offset(); 13898 o.left += plotOffset.left; 13899 o.top += plotOffset.top; 13900 return o; 13901 }; 13902 plot.getData = function () { return series; }; 13903 plot.getAxes = function () { 13904 var res = {}, i; 13905 $.each(xaxes.concat(yaxes), function (_, axis) { 13906 if (axis) 13907 res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; 13908 }); 13909 return res; 13910 }; 13911 plot.getXAxes = function () { return xaxes; }; 13912 plot.getYAxes = function () { return yaxes; }; 13913 plot.c2p = canvasToAxisCoords; 13914 plot.p2c = axisToCanvasCoords; 13915 plot.getOptions = function () { return options; }; 13916 plot.highlight = highlight; 13917 plot.unhighlight = unhighlight; 13918 plot.triggerRedrawOverlay = triggerRedrawOverlay; 13919 plot.pointOffset = function(point) { 13920 return { 13921 left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10), 13922 top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10) 13923 }; 13924 }; 13925 plot.shutdown = shutdown; 13926 plot.destroy = function () { 13927 shutdown(); 13928 placeholder.removeData("plot").empty(); 13929 13930 series = []; 13931 options = null; 13932 surface = null; 13933 overlay = null; 13934 eventHolder = null; 13935 ctx = null; 13936 octx = null; 13937 xaxes = []; 13938 yaxes = []; 13939 hooks = null; 13940 highlights = []; 13941 plot = null; 13942 }; 13943 plot.resize = function () { 13944 var width = placeholder.width(), 13945 height = placeholder.height(); 13946 surface.resize(width, height); 13947 overlay.resize(width, height); 13948 }; 13949 13950 // public attributes 13951 plot.hooks = hooks; 13952 13953 // initialize 13954 initPlugins(plot); 13955 parseOptions(options_); 13956 setupCanvases(); 13957 setData(data_); 13958 setupGrid(); 13959 draw(); 13960 bindEvents(); 13961 13962 13963 function executeHooks(hook, args) { 13964 args = [plot].concat(args); 13965 for (var i = 0; i < hook.length; ++i) 13966 hook[i].apply(this, args); 13967 } 13968 13969 function initPlugins() { 13970 13971 // References to key classes, allowing plugins to modify them 13972 13973 var classes = { 13974 Canvas: Canvas 13975 }; 13976 13977 for (var i = 0; i < plugins.length; ++i) { 13978 var p = plugins[i]; 13979 p.init(plot, classes); 13980 if (p.options) 13981 $.extend(true, options, p.options); 13982 } 13983 } 13984 13985 function parseOptions(opts) { 13986 13987 $.extend(true, options, opts); 13988 13989 // $.extend merges arrays, rather than replacing them. When less 13990 // colors are provided than the size of the default palette, we 13991 // end up with those colors plus the remaining defaults, which is 13992 // not expected behavior; avoid it by replacing them here. 13993 13994 if (opts && opts.colors) { 13995 options.colors = opts.colors; 13996 } 13997 13998 if (options.xaxis.color == null) 13999 options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); 14000 if (options.yaxis.color == null) 14001 options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); 14002 14003 if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility 14004 options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; 14005 if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility 14006 options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; 14007 14008 if (options.grid.borderColor == null) 14009 options.grid.borderColor = options.grid.color; 14010 if (options.grid.tickColor == null) 14011 options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); 14012 14013 // Fill in defaults for axis options, including any unspecified 14014 // font-spec fields, if a font-spec was provided. 14015 14016 // If no x/y axis options were provided, create one of each anyway, 14017 // since the rest of the code assumes that they exist. 14018 14019 var i, axisOptions, axisCount, 14020 fontSize = placeholder.css("font-size"), 14021 fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13, 14022 fontDefaults = { 14023 style: placeholder.css("font-style"), 14024 size: Math.round(0.8 * fontSizeDefault), 14025 variant: placeholder.css("font-variant"), 14026 weight: placeholder.css("font-weight"), 14027 family: placeholder.css("font-family") 14028 }; 14029 14030 axisCount = options.xaxes.length || 1; 14031 for (i = 0; i < axisCount; ++i) { 14032 14033 axisOptions = options.xaxes[i]; 14034 if (axisOptions && !axisOptions.tickColor) { 14035 axisOptions.tickColor = axisOptions.color; 14036 } 14037 14038 axisOptions = $.extend(true, {}, options.xaxis, axisOptions); 14039 options.xaxes[i] = axisOptions; 14040 14041 if (axisOptions.font) { 14042 axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); 14043 if (!axisOptions.font.color) { 14044 axisOptions.font.color = axisOptions.color; 14045 } 14046 if (!axisOptions.font.lineHeight) { 14047 axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); 14048 } 14049 } 14050 } 14051 14052 axisCount = options.yaxes.length || 1; 14053 for (i = 0; i < axisCount; ++i) { 14054 14055 axisOptions = options.yaxes[i]; 14056 if (axisOptions && !axisOptions.tickColor) { 14057 axisOptions.tickColor = axisOptions.color; 14058 } 14059 14060 axisOptions = $.extend(true, {}, options.yaxis, axisOptions); 14061 options.yaxes[i] = axisOptions; 14062 14063 if (axisOptions.font) { 14064 axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); 14065 if (!axisOptions.font.color) { 14066 axisOptions.font.color = axisOptions.color; 14067 } 14068 if (!axisOptions.font.lineHeight) { 14069 axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); 14070 } 14071 } 14072 } 14073 14074 // backwards compatibility, to be removed in future 14075 if (options.xaxis.noTicks && options.xaxis.ticks == null) 14076 options.xaxis.ticks = options.xaxis.noTicks; 14077 if (options.yaxis.noTicks && options.yaxis.ticks == null) 14078 options.yaxis.ticks = options.yaxis.noTicks; 14079 if (options.x2axis) { 14080 options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); 14081 options.xaxes[1].position = "top"; 14082 // Override the inherit to allow the axis to auto-scale 14083 if (options.x2axis.min == null) { 14084 options.xaxes[1].min = null; 14085 } 14086 if (options.x2axis.max == null) { 14087 options.xaxes[1].max = null; 14088 } 14089 } 14090 if (options.y2axis) { 14091 options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); 14092 options.yaxes[1].position = "right"; 14093 // Override the inherit to allow the axis to auto-scale 14094 if (options.y2axis.min == null) { 14095 options.yaxes[1].min = null; 14096 } 14097 if (options.y2axis.max == null) { 14098 options.yaxes[1].max = null; 14099 } 14100 } 14101 if (options.grid.coloredAreas) 14102 options.grid.markings = options.grid.coloredAreas; 14103 if (options.grid.coloredAreasColor) 14104 options.grid.markingsColor = options.grid.coloredAreasColor; 14105 if (options.lines) 14106 $.extend(true, options.series.lines, options.lines); 14107 if (options.points) 14108 $.extend(true, options.series.points, options.points); 14109 if (options.bars) 14110 $.extend(true, options.series.bars, options.bars); 14111 if (options.shadowSize != null) 14112 options.series.shadowSize = options.shadowSize; 14113 if (options.highlightColor != null) 14114 options.series.highlightColor = options.highlightColor; 14115 14116 // save options on axes for future reference 14117 for (i = 0; i < options.xaxes.length; ++i) 14118 getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; 14119 for (i = 0; i < options.yaxes.length; ++i) 14120 getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; 14121 14122 // add hooks from options 14123 for (var n in hooks) 14124 if (options.hooks[n] && options.hooks[n].length) 14125 hooks[n] = hooks[n].concat(options.hooks[n]); 14126 14127 executeHooks(hooks.processOptions, [options]); 14128 } 14129 14130 function setData(d) { 14131 series = parseData(d); 14132 fillInSeriesOptions(); 14133 processData(); 14134 } 14135 14136 function parseData(d) { 14137 var res = []; 14138 for (var i = 0; i < d.length; ++i) { 14139 var s = $.extend(true, {}, options.series); 14140 14141 if (d[i].data != null) { 14142 s.data = d[i].data; // move the data instead of deep-copy 14143 delete d[i].data; 14144 14145 $.extend(true, s, d[i]); 14146 14147 d[i].data = s.data; 14148 } 14149 else 14150 s.data = d[i]; 14151 res.push(s); 14152 } 14153 14154 return res; 14155 } 14156 14157 function axisNumber(obj, coord) { 14158 var a = obj[coord + "axis"]; 14159 if (typeof a == "object") // if we got a real axis, extract number 14160 a = a.n; 14161 if (typeof a != "number") 14162 a = 1; // default to first axis 14163 return a; 14164 } 14165 14166 function allAxes() { 14167 // return flat array without annoying null entries 14168 return $.grep(xaxes.concat(yaxes), function (a) { return a; }); 14169 } 14170 14171 function canvasToAxisCoords(pos) { 14172 // return an object with x/y corresponding to all used axes 14173 var res = {}, i, axis; 14174 for (i = 0; i < xaxes.length; ++i) { 14175 axis = xaxes[i]; 14176 if (axis && axis.used) 14177 res["x" + axis.n] = axis.c2p(pos.left); 14178 } 14179 14180 for (i = 0; i < yaxes.length; ++i) { 14181 axis = yaxes[i]; 14182 if (axis && axis.used) 14183 res["y" + axis.n] = axis.c2p(pos.top); 14184 } 14185 14186 if (res.x1 !== undefined) 14187 res.x = res.x1; 14188 if (res.y1 !== undefined) 14189 res.y = res.y1; 14190 14191 return res; 14192 } 14193 14194 function axisToCanvasCoords(pos) { 14195 // get canvas coords from the first pair of x/y found in pos 14196 var res = {}, i, axis, key; 14197 14198 for (i = 0; i < xaxes.length; ++i) { 14199 axis = xaxes[i]; 14200 if (axis && axis.used) { 14201 key = "x" + axis.n; 14202 if (pos[key] == null && axis.n == 1) 14203 key = "x"; 14204 14205 if (pos[key] != null) { 14206 res.left = axis.p2c(pos[key]); 14207 break; 14208 } 14209 } 14210 } 14211 14212 for (i = 0; i < yaxes.length; ++i) { 14213 axis = yaxes[i]; 14214 if (axis && axis.used) { 14215 key = "y" + axis.n; 14216 if (pos[key] == null && axis.n == 1) 14217 key = "y"; 14218 14219 if (pos[key] != null) { 14220 res.top = axis.p2c(pos[key]); 14221 break; 14222 } 14223 } 14224 } 14225 14226 return res; 14227 } 14228 14229 function getOrCreateAxis(axes, number) { 14230 if (!axes[number - 1]) 14231 axes[number - 1] = { 14232 n: number, // save the number for future reference 14233 direction: axes == xaxes ? "x" : "y", 14234 options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) 14235 }; 14236 14237 return axes[number - 1]; 14238 } 14239 14240 function fillInSeriesOptions() { 14241 14242 var neededColors = series.length, maxIndex = -1, i; 14243 14244 // Subtract the number of series that already have fixed colors or 14245 // color indexes from the number that we still need to generate. 14246 14247 for (i = 0; i < series.length; ++i) { 14248 var sc = series[i].color; 14249 if (sc != null) { 14250 neededColors--; 14251 if (typeof sc == "number" && sc > maxIndex) { 14252 maxIndex = sc; 14253 } 14254 } 14255 } 14256 14257 // If any of the series have fixed color indexes, then we need to 14258 // generate at least as many colors as the highest index. 14259 14260 if (neededColors <= maxIndex) { 14261 neededColors = maxIndex + 1; 14262 } 14263 14264 // Generate all the colors, using first the option colors and then 14265 // variations on those colors once they're exhausted. 14266 14267 var c, colors = [], colorPool = options.colors, 14268 colorPoolSize = colorPool.length, variation = 0; 14269 14270 for (i = 0; i < neededColors; i++) { 14271 14272 c = $.color.parse(colorPool[i % colorPoolSize] || "#666"); 14273 14274 // Each time we exhaust the colors in the pool we adjust 14275 // a scaling factor used to produce more variations on 14276 // those colors. The factor alternates negative/positive 14277 // to produce lighter/darker colors. 14278 14279 // Reset the variation after every few cycles, or else 14280 // it will end up producing only white or black colors. 14281 14282 if (i % colorPoolSize == 0 && i) { 14283 if (variation >= 0) { 14284 if (variation < 0.5) { 14285 variation = -variation - 0.2; 14286 } else variation = 0; 14287 } else variation = -variation; 14288 } 14289 14290 colors[i] = c.scale('rgb', 1 + variation); 14291 } 14292 14293 // Finalize the series options, filling in their colors 14294 14295 var colori = 0, s; 14296 for (i = 0; i < series.length; ++i) { 14297 s = series[i]; 14298 14299 // assign colors 14300 if (s.color == null) { 14301 s.color = colors[colori].toString(); 14302 ++colori; 14303 } 14304 else if (typeof s.color == "number") 14305 s.color = colors[s.color].toString(); 14306 14307 // turn on lines automatically in case nothing is set 14308 if (s.lines.show == null) { 14309 var v, show = true; 14310 for (v in s) 14311 if (s[v] && s[v].show) { 14312 show = false; 14313 break; 14314 } 14315 if (show) 14316 s.lines.show = true; 14317 } 14318 14319 // If nothing was provided for lines.zero, default it to match 14320 // lines.fill, since areas by default should extend to zero. 14321 14322 if (s.lines.zero == null) { 14323 s.lines.zero = !!s.lines.fill; 14324 } 14325 14326 // setup axes 14327 s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); 14328 s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); 14329 } 14330 } 14331 14332 function processData() { 14333 var topSentry = Number.POSITIVE_INFINITY, 14334 bottomSentry = Number.NEGATIVE_INFINITY, 14335 fakeInfinity = Number.MAX_VALUE, 14336 i, j, k, m, length, 14337 s, points, ps, x, y, axis, val, f, p, 14338 data, format; 14339 14340 function updateAxis(axis, min, max) { 14341 if (min < axis.datamin && min != -fakeInfinity) 14342 axis.datamin = min; 14343 if (max > axis.datamax && max != fakeInfinity) 14344 axis.datamax = max; 14345 } 14346 14347 $.each(allAxes(), function (_, axis) { 14348 // init axis 14349 axis.datamin = topSentry; 14350 axis.datamax = bottomSentry; 14351 axis.used = false; 14352 }); 14353 14354 for (i = 0; i < series.length; ++i) { 14355 s = series[i]; 14356 s.datapoints = { points: [] }; 14357 14358 executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); 14359 } 14360 14361 // first pass: clean and copy data 14362 for (i = 0; i < series.length; ++i) { 14363 s = series[i]; 14364 14365 data = s.data; 14366 format = s.datapoints.format; 14367 14368 if (!format) { 14369 format = []; 14370 // find out how to copy 14371 format.push({ x: true, number: true, required: true }); 14372 format.push({ y: true, number: true, required: true }); 14373 14374 if (s.bars.show || (s.lines.show && s.lines.fill)) { 14375 var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); 14376 format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); 14377 if (s.bars.horizontal) { 14378 delete format[format.length - 1].y; 14379 format[format.length - 1].x = true; 14380 } 14381 } 14382 14383 s.datapoints.format = format; 14384 } 14385 14386 if (s.datapoints.pointsize != null) 14387 continue; // already filled in 14388 14389 s.datapoints.pointsize = format.length; 14390 14391 ps = s.datapoints.pointsize; 14392 points = s.datapoints.points; 14393 14394 var insertSteps = s.lines.show && s.lines.steps; 14395 s.xaxis.used = s.yaxis.used = true; 14396 14397 for (j = k = 0; j < data.length; ++j, k += ps) { 14398 p = data[j]; 14399 14400 var nullify = p == null; 14401 if (!nullify) { 14402 for (m = 0; m < ps; ++m) { 14403 val = p[m]; 14404 f = format[m]; 14405 14406 if (f) { 14407 if (f.number && val != null) { 14408 val = +val; // convert to number 14409 if (isNaN(val)) 14410 val = null; 14411 else if (val == Infinity) 14412 val = fakeInfinity; 14413 else if (val == -Infinity) 14414 val = -fakeInfinity; 14415 } 14416 14417 if (val == null) { 14418 if (f.required) 14419 nullify = true; 14420 14421 if (f.defaultValue != null) 14422 val = f.defaultValue; 14423 } 14424 } 14425 14426 points[k + m] = val; 14427 } 14428 } 14429 14430 if (nullify) { 14431 for (m = 0; m < ps; ++m) { 14432 val = points[k + m]; 14433 if (val != null) { 14434 f = format[m]; 14435 // extract min/max info 14436 if (f.autoscale !== false) { 14437 if (f.x) { 14438 updateAxis(s.xaxis, val, val); 14439 } 14440 if (f.y) { 14441 updateAxis(s.yaxis, val, val); 14442 } 14443 } 14444 } 14445 points[k + m] = null; 14446 } 14447 } 14448 else { 14449 // a little bit of line specific stuff that 14450 // perhaps shouldn't be here, but lacking 14451 // better means... 14452 if (insertSteps && k > 0 14453 && points[k - ps] != null 14454 && points[k - ps] != points[k] 14455 && points[k - ps + 1] != points[k + 1]) { 14456 // copy the point to make room for a middle point 14457 for (m = 0; m < ps; ++m) 14458 points[k + ps + m] = points[k + m]; 14459 14460 // middle point has same y 14461 points[k + 1] = points[k - ps + 1]; 14462 14463 // we've added a point, better reflect that 14464 k += ps; 14465 } 14466 } 14467 } 14468 } 14469 14470 // give the hooks a chance to run 14471 for (i = 0; i < series.length; ++i) { 14472 s = series[i]; 14473 14474 executeHooks(hooks.processDatapoints, [ s, s.datapoints]); 14475 } 14476 14477 // second pass: find datamax/datamin for auto-scaling 14478 for (i = 0; i < series.length; ++i) { 14479 s = series[i]; 14480 points = s.datapoints.points; 14481 ps = s.datapoints.pointsize; 14482 format = s.datapoints.format; 14483 14484 var xmin = topSentry, ymin = topSentry, 14485 xmax = bottomSentry, ymax = bottomSentry; 14486 14487 for (j = 0; j < points.length; j += ps) { 14488 if (points[j] == null) 14489 continue; 14490 14491 for (m = 0; m < ps; ++m) { 14492 val = points[j + m]; 14493 f = format[m]; 14494 if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) 14495 continue; 14496 14497 if (f.x) { 14498 if (val < xmin) 14499 xmin = val; 14500 if (val > xmax) 14501 xmax = val; 14502 } 14503 if (f.y) { 14504 if (val < ymin) 14505 ymin = val; 14506 if (val > ymax) 14507 ymax = val; 14508 } 14509 } 14510 } 14511 14512 if (s.bars.show) { 14513 // make sure we got room for the bar on the dancing floor 14514 var delta; 14515 14516 switch (s.bars.align) { 14517 case "left": 14518 delta = 0; 14519 break; 14520 case "right": 14521 delta = -s.bars.barWidth; 14522 break; 14523 default: 14524 delta = -s.bars.barWidth / 2; 14525 } 14526 14527 if (s.bars.horizontal) { 14528 ymin += delta; 14529 ymax += delta + s.bars.barWidth; 14530 } 14531 else { 14532 xmin += delta; 14533 xmax += delta + s.bars.barWidth; 14534 } 14535 } 14536 14537 updateAxis(s.xaxis, xmin, xmax); 14538 updateAxis(s.yaxis, ymin, ymax); 14539 } 14540 14541 $.each(allAxes(), function (_, axis) { 14542 if (axis.datamin == topSentry) 14543 axis.datamin = null; 14544 if (axis.datamax == bottomSentry) 14545 axis.datamax = null; 14546 }); 14547 } 14548 14549 function setupCanvases() { 14550 14551 // Make sure the placeholder is clear of everything except canvases 14552 // from a previous plot in this container that we'll try to re-use. 14553 14554 placeholder.css("padding", 0) // padding messes up the positioning 14555 .children().filter(function(){ 14556 return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base'); 14557 }).remove(); 14558 14559 if (placeholder.css("position") == 'static') 14560 placeholder.css("position", "relative"); // for positioning labels and overlay 14561 14562 surface = new Canvas("flot-base", placeholder); 14563 overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features 14564 14565 ctx = surface.context; 14566 octx = overlay.context; 14567 14568 // define which element we're listening for events on 14569 eventHolder = $(overlay.element).unbind(); 14570 14571 // If we're re-using a plot object, shut down the old one 14572 14573 var existing = placeholder.data("plot"); 14574 14575 if (existing) { 14576 existing.shutdown(); 14577 overlay.clear(); 14578 } 14579 14580 // save in case we get replotted 14581 placeholder.data("plot", plot); 14582 } 14583 14584 function bindEvents() { 14585 // bind events 14586 if (options.grid.hoverable) { 14587 eventHolder.mousemove(onMouseMove); 14588 14589 // Use bind, rather than .mouseleave, because we officially 14590 // still support jQuery 1.2.6, which doesn't define a shortcut 14591 // for mouseenter or mouseleave. This was a bug/oversight that 14592 // was fixed somewhere around 1.3.x. We can return to using 14593 // .mouseleave when we drop support for 1.2.6. 14594 14595 eventHolder.bind("mouseleave", onMouseLeave); 14596 } 14597 14598 if (options.grid.clickable) 14599 eventHolder.click(onClick); 14600 14601 executeHooks(hooks.bindEvents, [eventHolder]); 14602 } 14603 14604 function shutdown() { 14605 if (redrawTimeout) 14606 clearTimeout(redrawTimeout); 14607 14608 eventHolder.unbind("mousemove", onMouseMove); 14609 eventHolder.unbind("mouseleave", onMouseLeave); 14610 eventHolder.unbind("click", onClick); 14611 14612 executeHooks(hooks.shutdown, [eventHolder]); 14613 } 14614 14615 function setTransformationHelpers(axis) { 14616 // set helper functions on the axis, assumes plot area 14617 // has been computed already 14618 14619 function identity(x) { return x; } 14620 14621 var s, m, t = axis.options.transform || identity, 14622 it = axis.options.inverseTransform; 14623 14624 // precompute how much the axis is scaling a point 14625 // in canvas space 14626 if (axis.direction == "x") { 14627 s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); 14628 m = Math.min(t(axis.max), t(axis.min)); 14629 } 14630 else { 14631 s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); 14632 s = -s; 14633 m = Math.max(t(axis.max), t(axis.min)); 14634 } 14635 14636 // data point to canvas coordinate 14637 if (t == identity) // slight optimization 14638 axis.p2c = function (p) { return (p - m) * s; }; 14639 else 14640 axis.p2c = function (p) { return (t(p) - m) * s; }; 14641 // canvas coordinate to data point 14642 if (!it) 14643 axis.c2p = function (c) { return m + c / s; }; 14644 else 14645 axis.c2p = function (c) { return it(m + c / s); }; 14646 } 14647 14648 function measureTickLabels(axis) { 14649 14650 var opts = axis.options, 14651 ticks = axis.ticks || [], 14652 labelWidth = opts.labelWidth || 0, 14653 labelHeight = opts.labelHeight || 0, 14654 maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null), 14655 legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", 14656 layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, 14657 font = opts.font || "flot-tick-label tickLabel"; 14658 14659 for (var i = 0; i < ticks.length; ++i) { 14660 14661 var t = ticks[i]; 14662 14663 if (!t.label) 14664 continue; 14665 14666 var info = surface.getTextInfo(layer, t.label, font, null, maxWidth); 14667 14668 labelWidth = Math.max(labelWidth, info.width); 14669 labelHeight = Math.max(labelHeight, info.height); 14670 } 14671 14672 axis.labelWidth = opts.labelWidth || labelWidth; 14673 axis.labelHeight = opts.labelHeight || labelHeight; 14674 } 14675 14676 function allocateAxisBoxFirstPhase(axis) { 14677 // find the bounding box of the axis by looking at label 14678 // widths/heights and ticks, make room by diminishing the 14679 // plotOffset; this first phase only looks at one 14680 // dimension per axis, the other dimension depends on the 14681 // other axes so will have to wait 14682 14683 var lw = axis.labelWidth, 14684 lh = axis.labelHeight, 14685 pos = axis.options.position, 14686 isXAxis = axis.direction === "x", 14687 tickLength = axis.options.tickLength, 14688 axisMargin = options.grid.axisMargin, 14689 padding = options.grid.labelMargin, 14690 innermost = true, 14691 outermost = true, 14692 first = true, 14693 found = false; 14694 14695 // Determine the axis's position in its direction and on its side 14696 14697 $.each(isXAxis ? xaxes : yaxes, function(i, a) { 14698 if (a && (a.show || a.reserveSpace)) { 14699 if (a === axis) { 14700 found = true; 14701 } else if (a.options.position === pos) { 14702 if (found) { 14703 outermost = false; 14704 } else { 14705 innermost = false; 14706 } 14707 } 14708 if (!found) { 14709 first = false; 14710 } 14711 } 14712 }); 14713 14714 // The outermost axis on each side has no margin 14715 14716 if (outermost) { 14717 axisMargin = 0; 14718 } 14719 14720 // The ticks for the first axis in each direction stretch across 14721 14722 if (tickLength == null) { 14723 tickLength = first ? "full" : 5; 14724 } 14725 14726 if (!isNaN(+tickLength)) 14727 padding += +tickLength; 14728 14729 if (isXAxis) { 14730 lh += padding; 14731 14732 if (pos == "bottom") { 14733 plotOffset.bottom += lh + axisMargin; 14734 axis.box = { top: surface.height - plotOffset.bottom, height: lh }; 14735 } 14736 else { 14737 axis.box = { top: plotOffset.top + axisMargin, height: lh }; 14738 plotOffset.top += lh + axisMargin; 14739 } 14740 } 14741 else { 14742 lw += padding; 14743 14744 if (pos == "left") { 14745 axis.box = { left: plotOffset.left + axisMargin, width: lw }; 14746 plotOffset.left += lw + axisMargin; 14747 } 14748 else { 14749 plotOffset.right += lw + axisMargin; 14750 axis.box = { left: surface.width - plotOffset.right, width: lw }; 14751 } 14752 } 14753 14754 // save for future reference 14755 axis.position = pos; 14756 axis.tickLength = tickLength; 14757 axis.box.padding = padding; 14758 axis.innermost = innermost; 14759 } 14760 14761 function allocateAxisBoxSecondPhase(axis) { 14762 // now that all axis boxes have been placed in one 14763 // dimension, we can set the remaining dimension coordinates 14764 if (axis.direction == "x") { 14765 axis.box.left = plotOffset.left - axis.labelWidth / 2; 14766 axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; 14767 } 14768 else { 14769 axis.box.top = plotOffset.top - axis.labelHeight / 2; 14770 axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; 14771 } 14772 } 14773 14774 function adjustLayoutForThingsStickingOut() { 14775 // possibly adjust plot offset to ensure everything stays 14776 // inside the canvas and isn't clipped off 14777 14778 var minMargin = options.grid.minBorderMargin, 14779 axis, i; 14780 14781 // check stuff from the plot (FIXME: this should just read 14782 // a value from the series, otherwise it's impossible to 14783 // customize) 14784 if (minMargin == null) { 14785 minMargin = 0; 14786 for (i = 0; i < series.length; ++i) 14787 minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); 14788 } 14789 14790 var margins = { 14791 left: minMargin, 14792 right: minMargin, 14793 top: minMargin, 14794 bottom: minMargin 14795 }; 14796 14797 // check axis labels, note we don't check the actual 14798 // labels but instead use the overall width/height to not 14799 // jump as much around with replots 14800 $.each(allAxes(), function (_, axis) { 14801 if (axis.reserveSpace && axis.ticks && axis.ticks.length) { 14802 if (axis.direction === "x") { 14803 margins.left = Math.max(margins.left, axis.labelWidth / 2); 14804 margins.right = Math.max(margins.right, axis.labelWidth / 2); 14805 } else { 14806 margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2); 14807 margins.top = Math.max(margins.top, axis.labelHeight / 2); 14808 } 14809 } 14810 }); 14811 14812 plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left)); 14813 plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right)); 14814 plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top)); 14815 plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom)); 14816 } 14817 14818 function setupGrid() { 14819 var i, axes = allAxes(), showGrid = options.grid.show; 14820 14821 // Initialize the plot's offset from the edge of the canvas 14822 14823 for (var a in plotOffset) { 14824 var margin = options.grid.margin || 0; 14825 plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0; 14826 } 14827 14828 executeHooks(hooks.processOffset, [plotOffset]); 14829 14830 // If the grid is visible, add its border width to the offset 14831 14832 for (var a in plotOffset) { 14833 if(typeof(options.grid.borderWidth) == "object") { 14834 plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; 14835 } 14836 else { 14837 plotOffset[a] += showGrid ? options.grid.borderWidth : 0; 14838 } 14839 } 14840 14841 $.each(axes, function (_, axis) { 14842 var axisOpts = axis.options; 14843 axis.show = axisOpts.show == null ? axis.used : axisOpts.show; 14844 axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace; 14845 setRange(axis); 14846 }); 14847 14848 if (showGrid) { 14849 14850 var allocatedAxes = $.grep(axes, function (axis) { 14851 return axis.show || axis.reserveSpace; 14852 }); 14853 14854 $.each(allocatedAxes, function (_, axis) { 14855 // make the ticks 14856 setupTickGeneration(axis); 14857 setTicks(axis); 14858 snapRangeToTicks(axis, axis.ticks); 14859 // find labelWidth/Height for axis 14860 measureTickLabels(axis); 14861 }); 14862 14863 // with all dimensions calculated, we can compute the 14864 // axis bounding boxes, start from the outside 14865 // (reverse order) 14866 for (i = allocatedAxes.length - 1; i >= 0; --i) 14867 allocateAxisBoxFirstPhase(allocatedAxes[i]); 14868 14869 // make sure we've got enough space for things that 14870 // might stick out 14871 adjustLayoutForThingsStickingOut(); 14872 14873 $.each(allocatedAxes, function (_, axis) { 14874 allocateAxisBoxSecondPhase(axis); 14875 }); 14876 } 14877 14878 plotWidth = surface.width - plotOffset.left - plotOffset.right; 14879 plotHeight = surface.height - plotOffset.bottom - plotOffset.top; 14880 14881 // now we got the proper plot dimensions, we can compute the scaling 14882 $.each(axes, function (_, axis) { 14883 setTransformationHelpers(axis); 14884 }); 14885 14886 if (showGrid) { 14887 drawAxisLabels(); 14888 } 14889 14890 insertLegend(); 14891 } 14892 14893 function setRange(axis) { 14894 var opts = axis.options, 14895 min = +(opts.min != null ? opts.min : axis.datamin), 14896 max = +(opts.max != null ? opts.max : axis.datamax), 14897 delta = max - min; 14898 14899 if (delta == 0.0) { 14900 // degenerate case 14901 var widen = max == 0 ? 1 : 0.01; 14902 14903 if (opts.min == null) 14904 min -= widen; 14905 // always widen max if we couldn't widen min to ensure we 14906 // don't fall into min == max which doesn't work 14907 if (opts.max == null || opts.min != null) 14908 max += widen; 14909 } 14910 else { 14911 // consider autoscaling 14912 var margin = opts.autoscaleMargin; 14913 if (margin != null) { 14914 if (opts.min == null) { 14915 min -= delta * margin; 14916 // make sure we don't go below zero if all values 14917 // are positive 14918 if (min < 0 && axis.datamin != null && axis.datamin >= 0) 14919 min = 0; 14920 } 14921 if (opts.max == null) { 14922 max += delta * margin; 14923 if (max > 0 && axis.datamax != null && axis.datamax <= 0) 14924 max = 0; 14925 } 14926 } 14927 } 14928 axis.min = min; 14929 axis.max = max; 14930 } 14931 14932 function setupTickGeneration(axis) { 14933 var opts = axis.options; 14934 14935 // estimate number of ticks 14936 var noTicks; 14937 if (typeof opts.ticks == "number" && opts.ticks > 0) 14938 noTicks = opts.ticks; 14939 else 14940 // heuristic based on the model a*sqrt(x) fitted to 14941 // some data points that seemed reasonable 14942 noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height); 14943 14944 var delta = (axis.max - axis.min) / noTicks, 14945 dec = -Math.floor(Math.log(delta) / Math.LN10), 14946 maxDec = opts.tickDecimals; 14947 14948 if (maxDec != null && dec > maxDec) { 14949 dec = maxDec; 14950 } 14951 14952 var magn = Math.pow(10, -dec), 14953 norm = delta / magn, // norm is between 1.0 and 10.0 14954 size; 14955 14956 if (norm < 1.5) { 14957 size = 1; 14958 } else if (norm < 3) { 14959 size = 2; 14960 // special case for 2.5, requires an extra decimal 14961 if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { 14962 size = 2.5; 14963 ++dec; 14964 } 14965 } else if (norm < 7.5) { 14966 size = 5; 14967 } else { 14968 size = 10; 14969 } 14970 14971 size *= magn; 14972 14973 if (opts.minTickSize != null && size < opts.minTickSize) { 14974 size = opts.minTickSize; 14975 } 14976 14977 axis.delta = delta; 14978 axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); 14979 axis.tickSize = opts.tickSize || size; 14980 14981 // Time mode was moved to a plug-in in 0.8, and since so many people use it 14982 // we'll add an especially friendly reminder to make sure they included it. 14983 14984 if (opts.mode == "time" && !axis.tickGenerator) { 14985 throw new Error("Time mode requires the flot.time plugin."); 14986 } 14987 14988 // Flot supports base-10 axes; any other mode else is handled by a plug-in, 14989 // like flot.time.js. 14990 14991 if (!axis.tickGenerator) { 14992 14993 axis.tickGenerator = function (axis) { 14994 14995 var ticks = [], 14996 start = floorInBase(axis.min, axis.tickSize), 14997 i = 0, 14998 v = Number.NaN, 14999 prev; 15000 15001 do { 15002 prev = v; 15003 v = start + i * axis.tickSize; 15004 ticks.push(v); 15005 ++i; 15006 } while (v < axis.max && v != prev); 15007 return ticks; 15008 }; 15009 15010 axis.tickFormatter = function (value, axis) { 15011 15012 var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; 15013 var formatted = "" + Math.round(value * factor) / factor; 15014 15015 // If tickDecimals was specified, ensure that we have exactly that 15016 // much precision; otherwise default to the value's own precision. 15017 15018 if (axis.tickDecimals != null) { 15019 var decimal = formatted.indexOf("."); 15020 var precision = decimal == -1 ? 0 : formatted.length - decimal - 1; 15021 if (precision < axis.tickDecimals) { 15022 return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); 15023 } 15024 } 15025 15026 return formatted; 15027 }; 15028 } 15029 15030 if ($.isFunction(opts.tickFormatter)) 15031 axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); }; 15032 15033 if (opts.alignTicksWithAxis != null) { 15034 var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; 15035 if (otherAxis && otherAxis.used && otherAxis != axis) { 15036 // consider snapping min/max to outermost nice ticks 15037 var niceTicks = axis.tickGenerator(axis); 15038 if (niceTicks.length > 0) { 15039 if (opts.min == null) 15040 axis.min = Math.min(axis.min, niceTicks[0]); 15041 if (opts.max == null && niceTicks.length > 1) 15042 axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); 15043 } 15044 15045 axis.tickGenerator = function (axis) { 15046 // copy ticks, scaled to this axis 15047 var ticks = [], v, i; 15048 for (i = 0; i < otherAxis.ticks.length; ++i) { 15049 v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); 15050 v = axis.min + v * (axis.max - axis.min); 15051 ticks.push(v); 15052 } 15053 return ticks; 15054 }; 15055 15056 // we might need an extra decimal since forced 15057 // ticks don't necessarily fit naturally 15058 if (!axis.mode && opts.tickDecimals == null) { 15059 var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), 15060 ts = axis.tickGenerator(axis); 15061 15062 // only proceed if the tick interval rounded 15063 // with an extra decimal doesn't give us a 15064 // zero at end 15065 if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) 15066 axis.tickDecimals = extraDec; 15067 } 15068 } 15069 } 15070 } 15071 15072 function setTicks(axis) { 15073 var oticks = axis.options.ticks, ticks = []; 15074 if (oticks == null || (typeof oticks == "number" && oticks > 0)) 15075 ticks = axis.tickGenerator(axis); 15076 else if (oticks) { 15077 if ($.isFunction(oticks)) 15078 // generate the ticks 15079 ticks = oticks(axis); 15080 else 15081 ticks = oticks; 15082 } 15083 15084 // clean up/labelify the supplied ticks, copy them over 15085 var i, v; 15086 axis.ticks = []; 15087 for (i = 0; i < ticks.length; ++i) { 15088 var label = null; 15089 var t = ticks[i]; 15090 if (typeof t == "object") { 15091 v = +t[0]; 15092 if (t.length > 1) 15093 label = t[1]; 15094 } 15095 else 15096 v = +t; 15097 if (label == null) 15098 label = axis.tickFormatter(v, axis); 15099 if (!isNaN(v)) 15100 axis.ticks.push({ v: v, label: label }); 15101 } 15102 } 15103 15104 function snapRangeToTicks(axis, ticks) { 15105 if (axis.options.autoscaleMargin && ticks.length > 0) { 15106 // snap to ticks 15107 if (axis.options.min == null) 15108 axis.min = Math.min(axis.min, ticks[0].v); 15109 if (axis.options.max == null && ticks.length > 1) 15110 axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); 15111 } 15112 } 15113 15114 function draw() { 15115 15116 surface.clear(); 15117 15118 executeHooks(hooks.drawBackground, [ctx]); 15119 15120 var grid = options.grid; 15121 15122 // draw background, if any 15123 if (grid.show && grid.backgroundColor) 15124 drawBackground(); 15125 15126 if (grid.show && !grid.aboveData) { 15127 drawGrid(); 15128 } 15129 15130 for (var i = 0; i < series.length; ++i) { 15131 executeHooks(hooks.drawSeries, [ctx, series[i]]); 15132 drawSeries(series[i]); 15133 } 15134 15135 executeHooks(hooks.draw, [ctx]); 15136 15137 if (grid.show && grid.aboveData) { 15138 drawGrid(); 15139 } 15140 15141 surface.render(); 15142 15143 // A draw implies that either the axes or data have changed, so we 15144 // should probably update the overlay highlights as well. 15145 15146 triggerRedrawOverlay(); 15147 } 15148 15149 function extractRange(ranges, coord) { 15150 var axis, from, to, key, axes = allAxes(); 15151 15152 for (var i = 0; i < axes.length; ++i) { 15153 axis = axes[i]; 15154 if (axis.direction == coord) { 15155 key = coord + axis.n + "axis"; 15156 if (!ranges[key] && axis.n == 1) 15157 key = coord + "axis"; // support x1axis as xaxis 15158 if (ranges[key]) { 15159 from = ranges[key].from; 15160 to = ranges[key].to; 15161 break; 15162 } 15163 } 15164 } 15165 15166 // backwards-compat stuff - to be removed in future 15167 if (!ranges[key]) { 15168 axis = coord == "x" ? xaxes[0] : yaxes[0]; 15169 from = ranges[coord + "1"]; 15170 to = ranges[coord + "2"]; 15171 } 15172 15173 // auto-reverse as an added bonus 15174 if (from != null && to != null && from > to) { 15175 var tmp = from; 15176 from = to; 15177 to = tmp; 15178 } 15179 15180 return { from: from, to: to, axis: axis }; 15181 } 15182 15183 function drawBackground() { 15184 ctx.save(); 15185 ctx.translate(plotOffset.left, plotOffset.top); 15186 15187 ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); 15188 ctx.fillRect(0, 0, plotWidth, plotHeight); 15189 ctx.restore(); 15190 } 15191 15192 function drawGrid() { 15193 var i, axes, bw, bc; 15194 15195 ctx.save(); 15196 ctx.translate(plotOffset.left, plotOffset.top); 15197 15198 // draw markings 15199 var markings = options.grid.markings; 15200 if (markings) { 15201 if ($.isFunction(markings)) { 15202 axes = plot.getAxes(); 15203 // xmin etc. is backwards compatibility, to be 15204 // removed in the future 15205 axes.xmin = axes.xaxis.min; 15206 axes.xmax = axes.xaxis.max; 15207 axes.ymin = axes.yaxis.min; 15208 axes.ymax = axes.yaxis.max; 15209 15210 markings = markings(axes); 15211 } 15212 15213 for (i = 0; i < markings.length; ++i) { 15214 var m = markings[i], 15215 xrange = extractRange(m, "x"), 15216 yrange = extractRange(m, "y"); 15217 15218 // fill in missing 15219 if (xrange.from == null) 15220 xrange.from = xrange.axis.min; 15221 if (xrange.to == null) 15222 xrange.to = xrange.axis.max; 15223 if (yrange.from == null) 15224 yrange.from = yrange.axis.min; 15225 if (yrange.to == null) 15226 yrange.to = yrange.axis.max; 15227 15228 // clip 15229 if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || 15230 yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) 15231 continue; 15232 15233 xrange.from = Math.max(xrange.from, xrange.axis.min); 15234 xrange.to = Math.min(xrange.to, xrange.axis.max); 15235 yrange.from = Math.max(yrange.from, yrange.axis.min); 15236 yrange.to = Math.min(yrange.to, yrange.axis.max); 15237 15238 var xequal = xrange.from === xrange.to, 15239 yequal = yrange.from === yrange.to; 15240 15241 if (xequal && yequal) { 15242 continue; 15243 } 15244 15245 // then draw 15246 xrange.from = Math.floor(xrange.axis.p2c(xrange.from)); 15247 xrange.to = Math.floor(xrange.axis.p2c(xrange.to)); 15248 yrange.from = Math.floor(yrange.axis.p2c(yrange.from)); 15249 yrange.to = Math.floor(yrange.axis.p2c(yrange.to)); 15250 15251 if (xequal || yequal) { 15252 var lineWidth = m.lineWidth || options.grid.markingsLineWidth, 15253 subPixel = lineWidth % 2 ? 0.5 : 0; 15254 ctx.beginPath(); 15255 ctx.strokeStyle = m.color || options.grid.markingsColor; 15256 ctx.lineWidth = lineWidth; 15257 if (xequal) { 15258 ctx.moveTo(xrange.to + subPixel, yrange.from); 15259 ctx.lineTo(xrange.to + subPixel, yrange.to); 15260 } else { 15261 ctx.moveTo(xrange.from, yrange.to + subPixel); 15262 ctx.lineTo(xrange.to, yrange.to + subPixel); 15263 } 15264 ctx.stroke(); 15265 } else { 15266 ctx.fillStyle = m.color || options.grid.markingsColor; 15267 ctx.fillRect(xrange.from, yrange.to, 15268 xrange.to - xrange.from, 15269 yrange.from - yrange.to); 15270 } 15271 } 15272 } 15273 15274 // draw the ticks 15275 axes = allAxes(); 15276 bw = options.grid.borderWidth; 15277 15278 for (var j = 0; j < axes.length; ++j) { 15279 var axis = axes[j], box = axis.box, 15280 t = axis.tickLength, x, y, xoff, yoff; 15281 if (!axis.show || axis.ticks.length == 0) 15282 continue; 15283 15284 ctx.lineWidth = 1; 15285 15286 // find the edges 15287 if (axis.direction == "x") { 15288 x = 0; 15289 if (t == "full") 15290 y = (axis.position == "top" ? 0 : plotHeight); 15291 else 15292 y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0); 15293 } 15294 else { 15295 y = 0; 15296 if (t == "full") 15297 x = (axis.position == "left" ? 0 : plotWidth); 15298 else 15299 x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0); 15300 } 15301 15302 // draw tick bar 15303 if (!axis.innermost) { 15304 ctx.strokeStyle = axis.options.color; 15305 ctx.beginPath(); 15306 xoff = yoff = 0; 15307 if (axis.direction == "x") 15308 xoff = plotWidth + 1; 15309 else 15310 yoff = plotHeight + 1; 15311 15312 if (ctx.lineWidth == 1) { 15313 if (axis.direction == "x") { 15314 y = Math.floor(y) + 0.5; 15315 } else { 15316 x = Math.floor(x) + 0.5; 15317 } 15318 } 15319 15320 ctx.moveTo(x, y); 15321 ctx.lineTo(x + xoff, y + yoff); 15322 ctx.stroke(); 15323 } 15324 15325 // draw ticks 15326 15327 ctx.strokeStyle = axis.options.tickColor; 15328 15329 ctx.beginPath(); 15330 for (i = 0; i < axis.ticks.length; ++i) { 15331 var v = axis.ticks[i].v; 15332 15333 xoff = yoff = 0; 15334 15335 if (isNaN(v) || v < axis.min || v > axis.max 15336 // skip those lying on the axes if we got a border 15337 || (t == "full" 15338 && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0) 15339 && (v == axis.min || v == axis.max))) 15340 continue; 15341 15342 if (axis.direction == "x") { 15343 x = axis.p2c(v); 15344 yoff = t == "full" ? -plotHeight : t; 15345 15346 if (axis.position == "top") 15347 yoff = -yoff; 15348 } 15349 else { 15350 y = axis.p2c(v); 15351 xoff = t == "full" ? -plotWidth : t; 15352 15353 if (axis.position == "left") 15354 xoff = -xoff; 15355 } 15356 15357 if (ctx.lineWidth == 1) { 15358 if (axis.direction == "x") 15359 x = Math.floor(x) + 0.5; 15360 else 15361 y = Math.floor(y) + 0.5; 15362 } 15363 15364 ctx.moveTo(x, y); 15365 ctx.lineTo(x + xoff, y + yoff); 15366 } 15367 15368 ctx.stroke(); 15369 } 15370 15371 15372 // draw border 15373 if (bw) { 15374 // If either borderWidth or borderColor is an object, then draw the border 15375 // line by line instead of as one rectangle 15376 bc = options.grid.borderColor; 15377 if(typeof bw == "object" || typeof bc == "object") { 15378 if (typeof bw !== "object") { 15379 bw = {top: bw, right: bw, bottom: bw, left: bw}; 15380 } 15381 if (typeof bc !== "object") { 15382 bc = {top: bc, right: bc, bottom: bc, left: bc}; 15383 } 15384 15385 if (bw.top > 0) { 15386 ctx.strokeStyle = bc.top; 15387 ctx.lineWidth = bw.top; 15388 ctx.beginPath(); 15389 ctx.moveTo(0 - bw.left, 0 - bw.top/2); 15390 ctx.lineTo(plotWidth, 0 - bw.top/2); 15391 ctx.stroke(); 15392 } 15393 15394 if (bw.right > 0) { 15395 ctx.strokeStyle = bc.right; 15396 ctx.lineWidth = bw.right; 15397 ctx.beginPath(); 15398 ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); 15399 ctx.lineTo(plotWidth + bw.right / 2, plotHeight); 15400 ctx.stroke(); 15401 } 15402 15403 if (bw.bottom > 0) { 15404 ctx.strokeStyle = bc.bottom; 15405 ctx.lineWidth = bw.bottom; 15406 ctx.beginPath(); 15407 ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); 15408 ctx.lineTo(0, plotHeight + bw.bottom / 2); 15409 ctx.stroke(); 15410 } 15411 15412 if (bw.left > 0) { 15413 ctx.strokeStyle = bc.left; 15414 ctx.lineWidth = bw.left; 15415 ctx.beginPath(); 15416 ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom); 15417 ctx.lineTo(0- bw.left/2, 0); 15418 ctx.stroke(); 15419 } 15420 } 15421 else { 15422 ctx.lineWidth = bw; 15423 ctx.strokeStyle = options.grid.borderColor; 15424 ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); 15425 } 15426 } 15427 15428 ctx.restore(); 15429 } 15430 15431 function drawAxisLabels() { 15432 15433 $.each(allAxes(), function (_, axis) { 15434 var box = axis.box, 15435 legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", 15436 layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, 15437 font = axis.options.font || "flot-tick-label tickLabel", 15438 tick, x, y, halign, valign; 15439 15440 // Remove text before checking for axis.show and ticks.length; 15441 // otherwise plugins, like flot-tickrotor, that draw their own 15442 // tick labels will end up with both theirs and the defaults. 15443 15444 surface.removeText(layer); 15445 15446 if (!axis.show || axis.ticks.length == 0) 15447 return; 15448 15449 for (var i = 0; i < axis.ticks.length; ++i) { 15450 15451 tick = axis.ticks[i]; 15452 if (!tick.label || tick.v < axis.min || tick.v > axis.max) 15453 continue; 15454 15455 if (axis.direction == "x") { 15456 halign = "center"; 15457 x = plotOffset.left + axis.p2c(tick.v); 15458 if (axis.position == "bottom") { 15459 y = box.top + box.padding; 15460 } else { 15461 y = box.top + box.height - box.padding; 15462 valign = "bottom"; 15463 } 15464 } else { 15465 valign = "middle"; 15466 y = plotOffset.top + axis.p2c(tick.v); 15467 if (axis.position == "left") { 15468 x = box.left + box.width - box.padding; 15469 halign = "right"; 15470 } else { 15471 x = box.left + box.padding; 15472 } 15473 } 15474 15475 surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); 15476 } 15477 }); 15478 } 15479 15480 function drawSeries(series) { 15481 if (series.lines.show) 15482 drawSeriesLines(series); 15483 if (series.bars.show) 15484 drawSeriesBars(series); 15485 if (series.points.show) 15486 drawSeriesPoints(series); 15487 } 15488 15489 function drawSeriesLines(series) { 15490 function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { 15491 var points = datapoints.points, 15492 ps = datapoints.pointsize, 15493 prevx = null, prevy = null; 15494 15495 ctx.beginPath(); 15496 for (var i = ps; i < points.length; i += ps) { 15497 var x1 = points[i - ps], y1 = points[i - ps + 1], 15498 x2 = points[i], y2 = points[i + 1]; 15499 15500 if (x1 == null || x2 == null) 15501 continue; 15502 15503 // clip with ymin 15504 if (y1 <= y2 && y1 < axisy.min) { 15505 if (y2 < axisy.min) 15506 continue; // line segment is outside 15507 // compute new intersection point 15508 x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; 15509 y1 = axisy.min; 15510 } 15511 else if (y2 <= y1 && y2 < axisy.min) { 15512 if (y1 < axisy.min) 15513 continue; 15514 x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; 15515 y2 = axisy.min; 15516 } 15517 15518 // clip with ymax 15519 if (y1 >= y2 && y1 > axisy.max) { 15520 if (y2 > axisy.max) 15521 continue; 15522 x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; 15523 y1 = axisy.max; 15524 } 15525 else if (y2 >= y1 && y2 > axisy.max) { 15526 if (y1 > axisy.max) 15527 continue; 15528 x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; 15529 y2 = axisy.max; 15530 } 15531 15532 // clip with xmin 15533 if (x1 <= x2 && x1 < axisx.min) { 15534 if (x2 < axisx.min) 15535 continue; 15536 y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; 15537 x1 = axisx.min; 15538 } 15539 else if (x2 <= x1 && x2 < axisx.min) { 15540 if (x1 < axisx.min) 15541 continue; 15542 y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; 15543 x2 = axisx.min; 15544 } 15545 15546 // clip with xmax 15547 if (x1 >= x2 && x1 > axisx.max) { 15548 if (x2 > axisx.max) 15549 continue; 15550 y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; 15551 x1 = axisx.max; 15552 } 15553 else if (x2 >= x1 && x2 > axisx.max) { 15554 if (x1 > axisx.max) 15555 continue; 15556 y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; 15557 x2 = axisx.max; 15558 } 15559 15560 if (x1 != prevx || y1 != prevy) 15561 ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); 15562 15563 prevx = x2; 15564 prevy = y2; 15565 ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); 15566 } 15567 ctx.stroke(); 15568 } 15569 15570 function plotLineArea(datapoints, axisx, axisy) { 15571 var points = datapoints.points, 15572 ps = datapoints.pointsize, 15573 bottom = Math.min(Math.max(0, axisy.min), axisy.max), 15574 i = 0, top, areaOpen = false, 15575 ypos = 1, segmentStart = 0, segmentEnd = 0; 15576 15577 // we process each segment in two turns, first forward 15578 // direction to sketch out top, then once we hit the 15579 // end we go backwards to sketch the bottom 15580 while (true) { 15581 if (ps > 0 && i > points.length + ps) 15582 break; 15583 15584 i += ps; // ps is negative if going backwards 15585 15586 var x1 = points[i - ps], 15587 y1 = points[i - ps + ypos], 15588 x2 = points[i], y2 = points[i + ypos]; 15589 15590 if (areaOpen) { 15591 if (ps > 0 && x1 != null && x2 == null) { 15592 // at turning point 15593 segmentEnd = i; 15594 ps = -ps; 15595 ypos = 2; 15596 continue; 15597 } 15598 15599 if (ps < 0 && i == segmentStart + ps) { 15600 // done with the reverse sweep 15601 ctx.fill(); 15602 areaOpen = false; 15603 ps = -ps; 15604 ypos = 1; 15605 i = segmentStart = segmentEnd + ps; 15606 continue; 15607 } 15608 } 15609 15610 if (x1 == null || x2 == null) 15611 continue; 15612 15613 // clip x values 15614 15615 // clip with xmin 15616 if (x1 <= x2 && x1 < axisx.min) { 15617 if (x2 < axisx.min) 15618 continue; 15619 y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; 15620 x1 = axisx.min; 15621 } 15622 else if (x2 <= x1 && x2 < axisx.min) { 15623 if (x1 < axisx.min) 15624 continue; 15625 y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; 15626 x2 = axisx.min; 15627 } 15628 15629 // clip with xmax 15630 if (x1 >= x2 && x1 > axisx.max) { 15631 if (x2 > axisx.max) 15632 continue; 15633 y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; 15634 x1 = axisx.max; 15635 } 15636 else if (x2 >= x1 && x2 > axisx.max) { 15637 if (x1 > axisx.max) 15638 continue; 15639 y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; 15640 x2 = axisx.max; 15641 } 15642 15643 if (!areaOpen) { 15644 // open area 15645 ctx.beginPath(); 15646 ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); 15647 areaOpen = true; 15648 } 15649 15650 // now first check the case where both is outside 15651 if (y1 >= axisy.max && y2 >= axisy.max) { 15652 ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); 15653 ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); 15654 continue; 15655 } 15656 else if (y1 <= axisy.min && y2 <= axisy.min) { 15657 ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); 15658 ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); 15659 continue; 15660 } 15661 15662 // else it's a bit more complicated, there might 15663 // be a flat maxed out rectangle first, then a 15664 // triangular cutout or reverse; to find these 15665 // keep track of the current x values 15666 var x1old = x1, x2old = x2; 15667 15668 // clip the y values, without shortcutting, we 15669 // go through all cases in turn 15670 15671 // clip with ymin 15672 if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { 15673 x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; 15674 y1 = axisy.min; 15675 } 15676 else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { 15677 x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; 15678 y2 = axisy.min; 15679 } 15680 15681 // clip with ymax 15682 if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { 15683 x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; 15684 y1 = axisy.max; 15685 } 15686 else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { 15687 x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; 15688 y2 = axisy.max; 15689 } 15690 15691 // if the x value was changed we got a rectangle 15692 // to fill 15693 if (x1 != x1old) { 15694 ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); 15695 // it goes to (x1, y1), but we fill that below 15696 } 15697 15698 // fill triangular section, this sometimes result 15699 // in redundant points if (x1, y1) hasn't changed 15700 // from previous line to, but we just ignore that 15701 ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); 15702 ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); 15703 15704 // fill the other rectangle if it's there 15705 if (x2 != x2old) { 15706 ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); 15707 ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); 15708 } 15709 } 15710 } 15711 15712 ctx.save(); 15713 ctx.translate(plotOffset.left, plotOffset.top); 15714 ctx.lineJoin = "round"; 15715 15716 var lw = series.lines.lineWidth, 15717 sw = series.shadowSize; 15718 // FIXME: consider another form of shadow when filling is turned on 15719 if (lw > 0 && sw > 0) { 15720 // draw shadow as a thick and thin line with transparency 15721 ctx.lineWidth = sw; 15722 ctx.strokeStyle = "rgba(0,0,0,0.1)"; 15723 // position shadow at angle from the mid of line 15724 var angle = Math.PI/18; 15725 plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); 15726 ctx.lineWidth = sw/2; 15727 plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); 15728 } 15729 15730 ctx.lineWidth = lw; 15731 ctx.strokeStyle = series.color; 15732 var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); 15733 if (fillStyle) { 15734 ctx.fillStyle = fillStyle; 15735 plotLineArea(series.datapoints, series.xaxis, series.yaxis); 15736 } 15737 15738 if (lw > 0) 15739 plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); 15740 ctx.restore(); 15741 } 15742 15743 function drawSeriesPoints(series) { 15744 function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { 15745 var points = datapoints.points, ps = datapoints.pointsize; 15746 15747 for (var i = 0; i < points.length; i += ps) { 15748 var x = points[i], y = points[i + 1]; 15749 if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) 15750 continue; 15751 15752 ctx.beginPath(); 15753 x = axisx.p2c(x); 15754 y = axisy.p2c(y) + offset; 15755 if (symbol == "circle") 15756 ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); 15757 else 15758 symbol(ctx, x, y, radius, shadow); 15759 ctx.closePath(); 15760 15761 if (fillStyle) { 15762 ctx.fillStyle = fillStyle; 15763 ctx.fill(); 15764 } 15765 ctx.stroke(); 15766 } 15767 } 15768 15769 ctx.save(); 15770 ctx.translate(plotOffset.left, plotOffset.top); 15771 15772 var lw = series.points.lineWidth, 15773 sw = series.shadowSize, 15774 radius = series.points.radius, 15775 symbol = series.points.symbol; 15776 15777 // If the user sets the line width to 0, we change it to a very 15778 // small value. A line width of 0 seems to force the default of 1. 15779 // Doing the conditional here allows the shadow setting to still be 15780 // optional even with a lineWidth of 0. 15781 15782 if( lw == 0 ) 15783 lw = 0.0001; 15784 15785 if (lw > 0 && sw > 0) { 15786 // draw shadow in two steps 15787 var w = sw / 2; 15788 ctx.lineWidth = w; 15789 ctx.strokeStyle = "rgba(0,0,0,0.1)"; 15790 plotPoints(series.datapoints, radius, null, w + w/2, true, 15791 series.xaxis, series.yaxis, symbol); 15792 15793 ctx.strokeStyle = "rgba(0,0,0,0.2)"; 15794 plotPoints(series.datapoints, radius, null, w/2, true, 15795 series.xaxis, series.yaxis, symbol); 15796 } 15797 15798 ctx.lineWidth = lw; 15799 ctx.strokeStyle = series.color; 15800 plotPoints(series.datapoints, radius, 15801 getFillStyle(series.points, series.color), 0, false, 15802 series.xaxis, series.yaxis, symbol); 15803 ctx.restore(); 15804 } 15805 15806 function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { 15807 var left, right, bottom, top, 15808 drawLeft, drawRight, drawTop, drawBottom, 15809 tmp; 15810 15811 // in horizontal mode, we start the bar from the left 15812 // instead of from the bottom so it appears to be 15813 // horizontal rather than vertical 15814 if (horizontal) { 15815 drawBottom = drawRight = drawTop = true; 15816 drawLeft = false; 15817 left = b; 15818 right = x; 15819 top = y + barLeft; 15820 bottom = y + barRight; 15821 15822 // account for negative bars 15823 if (right < left) { 15824 tmp = right; 15825 right = left; 15826 left = tmp; 15827 drawLeft = true; 15828 drawRight = false; 15829 } 15830 } 15831 else { 15832 drawLeft = drawRight = drawTop = true; 15833 drawBottom = false; 15834 left = x + barLeft; 15835 right = x + barRight; 15836 bottom = b; 15837 top = y; 15838 15839 // account for negative bars 15840 if (top < bottom) { 15841 tmp = top; 15842 top = bottom; 15843 bottom = tmp; 15844 drawBottom = true; 15845 drawTop = false; 15846 } 15847 } 15848 15849 // clip 15850 if (right < axisx.min || left > axisx.max || 15851 top < axisy.min || bottom > axisy.max) 15852 return; 15853 15854 if (left < axisx.min) { 15855 left = axisx.min; 15856 drawLeft = false; 15857 } 15858 15859 if (right > axisx.max) { 15860 right = axisx.max; 15861 drawRight = false; 15862 } 15863 15864 if (bottom < axisy.min) { 15865 bottom = axisy.min; 15866 drawBottom = false; 15867 } 15868 15869 if (top > axisy.max) { 15870 top = axisy.max; 15871 drawTop = false; 15872 } 15873 15874 left = axisx.p2c(left); 15875 bottom = axisy.p2c(bottom); 15876 right = axisx.p2c(right); 15877 top = axisy.p2c(top); 15878 15879 // fill the bar 15880 if (fillStyleCallback) { 15881 c.fillStyle = fillStyleCallback(bottom, top); 15882 c.fillRect(left, top, right - left, bottom - top) 15883 } 15884 15885 // draw outline 15886 if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { 15887 c.beginPath(); 15888 15889 // FIXME: inline moveTo is buggy with excanvas 15890 c.moveTo(left, bottom); 15891 if (drawLeft) 15892 c.lineTo(left, top); 15893 else 15894 c.moveTo(left, top); 15895 if (drawTop) 15896 c.lineTo(right, top); 15897 else 15898 c.moveTo(right, top); 15899 if (drawRight) 15900 c.lineTo(right, bottom); 15901 else 15902 c.moveTo(right, bottom); 15903 if (drawBottom) 15904 c.lineTo(left, bottom); 15905 else 15906 c.moveTo(left, bottom); 15907 c.stroke(); 15908 } 15909 } 15910 15911 function drawSeriesBars(series) { 15912 function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) { 15913 var points = datapoints.points, ps = datapoints.pointsize; 15914 15915 for (var i = 0; i < points.length; i += ps) { 15916 if (points[i] == null) 15917 continue; 15918 drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth); 15919 } 15920 } 15921 15922 ctx.save(); 15923 ctx.translate(plotOffset.left, plotOffset.top); 15924 15925 // FIXME: figure out a way to add shadows (for instance along the right edge) 15926 ctx.lineWidth = series.bars.lineWidth; 15927 ctx.strokeStyle = series.color; 15928 15929 var barLeft; 15930 15931 switch (series.bars.align) { 15932 case "left": 15933 barLeft = 0; 15934 break; 15935 case "right": 15936 barLeft = -series.bars.barWidth; 15937 break; 15938 default: 15939 barLeft = -series.bars.barWidth / 2; 15940 } 15941 15942 var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; 15943 plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis); 15944 ctx.restore(); 15945 } 15946 15947 function getFillStyle(filloptions, seriesColor, bottom, top) { 15948 var fill = filloptions.fill; 15949 if (!fill) 15950 return null; 15951 15952 if (filloptions.fillColor) 15953 return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); 15954 15955 var c = $.color.parse(seriesColor); 15956 c.a = typeof fill == "number" ? fill : 0.4; 15957 c.normalize(); 15958 return c.toString(); 15959 } 15960 15961 function insertLegend() { 15962 15963 if (options.legend.container != null) { 15964 $(options.legend.container).html(""); 15965 } else { 15966 placeholder.find(".legend").remove(); 15967 } 15968 15969 if (!options.legend.show) { 15970 return; 15971 } 15972 15973 var fragments = [], entries = [], rowStarted = false, 15974 lf = options.legend.labelFormatter, s, label; 15975 15976 // Build a list of legend entries, with each having a label and a color 15977 15978 for (var i = 0; i < series.length; ++i) { 15979 s = series[i]; 15980 if (s.label) { 15981 label = lf ? lf(s.label, s) : s.label; 15982 if (label) { 15983 entries.push({ 15984 label: label, 15985 color: s.color 15986 }); 15987 } 15988 } 15989 } 15990 15991 // Sort the legend using either the default or a custom comparator 15992 15993 if (options.legend.sorted) { 15994 if ($.isFunction(options.legend.sorted)) { 15995 entries.sort(options.legend.sorted); 15996 } else if (options.legend.sorted == "reverse") { 15997 entries.reverse(); 15998 } else { 15999 var ascending = options.legend.sorted != "descending"; 16000 entries.sort(function(a, b) { 16001 return a.label == b.label ? 0 : ( 16002 (a.label < b.label) != ascending ? 1 : -1 // Logical XOR 16003 ); 16004 }); 16005 } 16006 } 16007 16008 // Generate markup for the list of entries, in their final order 16009 16010 for (var i = 0; i < entries.length; ++i) { 16011 16012 var entry = entries[i]; 16013 16014 if (i % options.legend.noColumns == 0) { 16015 if (rowStarted) 16016 fragments.push('</tr>'); 16017 fragments.push('<tr>'); 16018 rowStarted = true; 16019 } 16020 16021 fragments.push( 16022 '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden"></div></div></td>' + 16023 '<td class="legendLabel">' + entry.label + '</td>' 16024 ); 16025 } 16026 16027 if (rowStarted) 16028 fragments.push('</tr>'); 16029 16030 if (fragments.length == 0) 16031 return; 16032 16033 var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>'; 16034 if (options.legend.container != null) 16035 $(options.legend.container).html(table); 16036 else { 16037 var pos = "", 16038 p = options.legend.position, 16039 m = options.legend.margin; 16040 if (m[0] == null) 16041 m = [m, m]; 16042 if (p.charAt(0) == "n") 16043 pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; 16044 else if (p.charAt(0) == "s") 16045 pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; 16046 if (p.charAt(1) == "e") 16047 pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; 16048 else if (p.charAt(1) == "w") 16049 pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; 16050 var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder); 16051 if (options.legend.backgroundOpacity != 0.0) { 16052 // put in the transparent background 16053 // separately to avoid blended labels and 16054 // label boxes 16055 var c = options.legend.backgroundColor; 16056 if (c == null) { 16057 c = options.grid.backgroundColor; 16058 if (c && typeof c == "string") 16059 c = $.color.parse(c); 16060 else 16061 c = $.color.extract(legend, 'background-color'); 16062 c.a = 1; 16063 c = c.toString(); 16064 } 16065 var div = legend.children(); 16066 $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity); 16067 } 16068 } 16069 } 16070 16071 16072 // interactive features 16073 16074 var highlights = [], 16075 redrawTimeout = null; 16076 16077 // returns the data item the mouse is over, or null if none is found 16078 function findNearbyItem(mouseX, mouseY, seriesFilter) { 16079 var maxDistance = options.grid.mouseActiveRadius, 16080 smallestDistance = maxDistance * maxDistance + 1, 16081 item = null, foundPoint = false, i, j, ps; 16082 16083 for (i = series.length - 1; i >= 0; --i) { 16084 if (!seriesFilter(series[i])) 16085 continue; 16086 16087 var s = series[i], 16088 axisx = s.xaxis, 16089 axisy = s.yaxis, 16090 points = s.datapoints.points, 16091 mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster 16092 my = axisy.c2p(mouseY), 16093 maxx = maxDistance / axisx.scale, 16094 maxy = maxDistance / axisy.scale; 16095 16096 ps = s.datapoints.pointsize; 16097 // with inverse transforms, we can't use the maxx/maxy 16098 // optimization, sadly 16099 if (axisx.options.inverseTransform) 16100 maxx = Number.MAX_VALUE; 16101 if (axisy.options.inverseTransform) 16102 maxy = Number.MAX_VALUE; 16103 16104 if (s.lines.show || s.points.show) { 16105 for (j = 0; j < points.length; j += ps) { 16106 var x = points[j], y = points[j + 1]; 16107 if (x == null) 16108 continue; 16109 16110 // For points and lines, the cursor must be within a 16111 // certain distance to the data point 16112 if (x - mx > maxx || x - mx < -maxx || 16113 y - my > maxy || y - my < -maxy) 16114 continue; 16115 16116 // We have to calculate distances in pixels, not in 16117 // data units, because the scales of the axes may be different 16118 var dx = Math.abs(axisx.p2c(x) - mouseX), 16119 dy = Math.abs(axisy.p2c(y) - mouseY), 16120 dist = dx * dx + dy * dy; // we save the sqrt 16121 16122 // use <= to ensure last point takes precedence 16123 // (last generally means on top of) 16124 if (dist < smallestDistance) { 16125 smallestDistance = dist; 16126 item = [i, j / ps]; 16127 } 16128 } 16129 } 16130 16131 if (s.bars.show && !item) { // no other point can be nearby 16132 16133 var barLeft, barRight; 16134 16135 switch (s.bars.align) { 16136 case "left": 16137 barLeft = 0; 16138 break; 16139 case "right": 16140 barLeft = -s.bars.barWidth; 16141 break; 16142 default: 16143 barLeft = -s.bars.barWidth / 2; 16144 } 16145 16146 barRight = barLeft + s.bars.barWidth; 16147 16148 for (j = 0; j < points.length; j += ps) { 16149 var x = points[j], y = points[j + 1], b = points[j + 2]; 16150 if (x == null) 16151 continue; 16152 16153 // for a bar graph, the cursor must be inside the bar 16154 if (series[i].bars.horizontal ? 16155 (mx <= Math.max(b, x) && mx >= Math.min(b, x) && 16156 my >= y + barLeft && my <= y + barRight) : 16157 (mx >= x + barLeft && mx <= x + barRight && 16158 my >= Math.min(b, y) && my <= Math.max(b, y))) 16159 item = [i, j / ps]; 16160 } 16161 } 16162 } 16163 16164 if (item) { 16165 i = item[0]; 16166 j = item[1]; 16167 ps = series[i].datapoints.pointsize; 16168 16169 return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), 16170 dataIndex: j, 16171 series: series[i], 16172 seriesIndex: i }; 16173 } 16174 16175 return null; 16176 } 16177 16178 function onMouseMove(e) { 16179 if (options.grid.hoverable) 16180 triggerClickHoverEvent("plothover", e, 16181 function (s) { return s["hoverable"] != false; }); 16182 } 16183 16184 function onMouseLeave(e) { 16185 if (options.grid.hoverable) 16186 triggerClickHoverEvent("plothover", e, 16187 function (s) { return false; }); 16188 } 16189 16190 function onClick(e) { 16191 triggerClickHoverEvent("plotclick", e, 16192 function (s) { return s["clickable"] != false; }); 16193 } 16194 16195 // trigger click or hover event (they send the same parameters 16196 // so we share their code) 16197 function triggerClickHoverEvent(eventname, event, seriesFilter) { 16198 var offset = eventHolder.offset(), 16199 canvasX = event.pageX - offset.left - plotOffset.left, 16200 canvasY = event.pageY - offset.top - plotOffset.top, 16201 pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); 16202 16203 pos.pageX = event.pageX; 16204 pos.pageY = event.pageY; 16205 16206 var item = findNearbyItem(canvasX, canvasY, seriesFilter); 16207 16208 if (item) { 16209 // fill in mouse pos for any listeners out there 16210 item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); 16211 item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); 16212 } 16213 16214 if (options.grid.autoHighlight) { 16215 // clear auto-highlights 16216 for (var i = 0; i < highlights.length; ++i) { 16217 var h = highlights[i]; 16218 if (h.auto == eventname && 16219 !(item && h.series == item.series && 16220 h.point[0] == item.datapoint[0] && 16221 h.point[1] == item.datapoint[1])) 16222 unhighlight(h.series, h.point); 16223 } 16224 16225 if (item) 16226 highlight(item.series, item.datapoint, eventname); 16227 } 16228 16229 placeholder.trigger(eventname, [ pos, item ]); 16230 } 16231 16232 function triggerRedrawOverlay() { 16233 var t = options.interaction.redrawOverlayInterval; 16234 if (t == -1) { // skip event queue 16235 drawOverlay(); 16236 return; 16237 } 16238 16239 if (!redrawTimeout) 16240 redrawTimeout = setTimeout(drawOverlay, t); 16241 } 16242 16243 function drawOverlay() { 16244 redrawTimeout = null; 16245 16246 // draw highlights 16247 octx.save(); 16248 overlay.clear(); 16249 octx.translate(plotOffset.left, plotOffset.top); 16250 16251 var i, hi; 16252 for (i = 0; i < highlights.length; ++i) { 16253 hi = highlights[i]; 16254 16255 if (hi.series.bars.show) 16256 drawBarHighlight(hi.series, hi.point); 16257 else 16258 drawPointHighlight(hi.series, hi.point); 16259 } 16260 octx.restore(); 16261 16262 executeHooks(hooks.drawOverlay, [octx]); 16263 } 16264 16265 function highlight(s, point, auto) { 16266 if (typeof s == "number") 16267 s = series[s]; 16268 16269 if (typeof point == "number") { 16270 var ps = s.datapoints.pointsize; 16271 point = s.datapoints.points.slice(ps * point, ps * (point + 1)); 16272 } 16273 16274 var i = indexOfHighlight(s, point); 16275 if (i == -1) { 16276 highlights.push({ series: s, point: point, auto: auto }); 16277 16278 triggerRedrawOverlay(); 16279 } 16280 else if (!auto) 16281 highlights[i].auto = false; 16282 } 16283 16284 function unhighlight(s, point) { 16285 if (s == null && point == null) { 16286 highlights = []; 16287 triggerRedrawOverlay(); 16288 return; 16289 } 16290 16291 if (typeof s == "number") 16292 s = series[s]; 16293 16294 if (typeof point == "number") { 16295 var ps = s.datapoints.pointsize; 16296 point = s.datapoints.points.slice(ps * point, ps * (point + 1)); 16297 } 16298 16299 var i = indexOfHighlight(s, point); 16300 if (i != -1) { 16301 highlights.splice(i, 1); 16302 16303 triggerRedrawOverlay(); 16304 } 16305 } 16306 16307 function indexOfHighlight(s, p) { 16308 for (var i = 0; i < highlights.length; ++i) { 16309 var h = highlights[i]; 16310 if (h.series == s && h.point[0] == p[0] 16311 && h.point[1] == p[1]) 16312 return i; 16313 } 16314 return -1; 16315 } 16316 16317 function drawPointHighlight(series, point) { 16318 var x = point[0], y = point[1], 16319 axisx = series.xaxis, axisy = series.yaxis, 16320 highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); 16321 16322 if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) 16323 return; 16324 16325 var pointRadius = series.points.radius + series.points.lineWidth / 2; 16326 octx.lineWidth = pointRadius; 16327 octx.strokeStyle = highlightColor; 16328 var radius = 1.5 * pointRadius; 16329 x = axisx.p2c(x); 16330 y = axisy.p2c(y); 16331 16332 octx.beginPath(); 16333 if (series.points.symbol == "circle") 16334 octx.arc(x, y, radius, 0, 2 * Math.PI, false); 16335 else 16336 series.points.symbol(octx, x, y, radius, false); 16337 octx.closePath(); 16338 octx.stroke(); 16339 } 16340 16341 function drawBarHighlight(series, point) { 16342 var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), 16343 fillStyle = highlightColor, 16344 barLeft; 16345 16346 switch (series.bars.align) { 16347 case "left": 16348 barLeft = 0; 16349 break; 16350 case "right": 16351 barLeft = -series.bars.barWidth; 16352 break; 16353 default: 16354 barLeft = -series.bars.barWidth / 2; 16355 } 16356 16357 octx.lineWidth = series.bars.lineWidth; 16358 octx.strokeStyle = highlightColor; 16359 16360 drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, 16361 function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); 16362 } 16363 16364 function getColorOrGradient(spec, bottom, top, defaultColor) { 16365 if (typeof spec == "string") 16366 return spec; 16367 else { 16368 // assume this is a gradient spec; IE currently only 16369 // supports a simple vertical gradient properly, so that's 16370 // what we support too 16371 var gradient = ctx.createLinearGradient(0, top, 0, bottom); 16372 16373 for (var i = 0, l = spec.colors.length; i < l; ++i) { 16374 var c = spec.colors[i]; 16375 if (typeof c != "string") { 16376 var co = $.color.parse(defaultColor); 16377 if (c.brightness != null) 16378 co = co.scale('rgb', c.brightness); 16379 if (c.opacity != null) 16380 co.a *= c.opacity; 16381 c = co.toString(); 16382 } 16383 gradient.addColorStop(i / (l - 1), c); 16384 } 16385 16386 return gradient; 16387 } 16388 } 16389 } 16390 16391 // Add the plot function to the top level of the jQuery object 16392 16393 $.plot = function(placeholder, data, options) { 16394 //var t0 = new Date(); 16395 var plot = new Plot($(placeholder), data, options, $.plot.plugins); 16396 //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); 16397 return plot; 16398 }; 16399 16400 $.plot.version = "0.8.3"; 16401 16402 $.plot.plugins = []; 16403 16404 // Also add the plot function as a chainable property 16405 16406 $.fn.plot = function(data, options) { 16407 return this.each(function() { 16408 $.plot(this, data, options); 16409 }); 16410 }; 16411 16412 // round to nearby lower multiple of base 16413 function floorInBase(n, base) { 16414 return base * Math.floor(n / base); 16415 } 16416 16417})(jQuery);
16418 16419;/* 16420 * jquery.flot.tooltip 16421 * 16422 * description: easy-to-use tooltips for Flot charts 16423 * version: 0.9.0 16424 * authors: Krzysztof Urbas @krzysu [myviews.pl],Evan Steinkerchner @Roundaround 16425 * website: https://github.com/krzysu/flot.tooltip 16426 * 16427 * build on 2016-07-26 16428 * released under MIT License, 2012 16429*/ 16430(function ($) { 16431 // plugin options, default values 16432 var defaultOptions = { 16433 tooltip: { 16434 show: false, 16435 cssClass: "flotTip", 16436 content: "%s | X: %x | Y: %y", 16437 // allowed templates are: 16438 // %s -> series label, 16439 // %c -> series color, 16440 // %lx -> x axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels), 16441 // %ly -> y axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels), 16442 // %x -> X value, 16443 // %y -> Y value, 16444 // %x.2 -> precision of X value, 16445 // %p -> percent 16446 // %n -> value (not percent) of pie chart 16447 xDateFormat: null, 16448 yDateFormat: null, 16449 monthNames: null, 16450 dayNames: null, 16451 shifts: { 16452 x: 10, 16453 y: 20 16454 }, 16455 defaultTheme: true, 16456 snap: true, 16457 lines: false, 16458 clickTips: false, 16459 16460 // callbacks 16461 onHover: function (flotItem, $tooltipEl) {}, 16462 16463 $compat: false 16464 } 16465 }; 16466 16467 // dummy default options object for legacy code (<0.8.5) - is deleted later 16468 defaultOptions.tooltipOpts = defaultOptions.tooltip; 16469 16470 // object 16471 var FlotTooltip = function (plot) { 16472 // variables 16473 this.tipPosition = {x: 0, y: 0}; 16474 16475 this.init(plot); 16476 }; 16477 16478 // main plugin function 16479 FlotTooltip.prototype.init = function (plot) { 16480 var that = this; 16481 16482 // detect other flot plugins 16483 var plotPluginsLength = $.plot.plugins.length; 16484 this.plotPlugins = []; 16485 16486 if (plotPluginsLength) { 16487 for (var p = 0; p < plotPluginsLength; p++) { 16488 this.plotPlugins.push($.plot.plugins[p].name); 16489 } 16490 } 16491 16492 plot.hooks.bindEvents.push(function (plot, eventHolder) { 16493 16494 // get plot options 16495 that.plotOptions = plot.getOptions(); 16496 16497 // for legacy (<0.8.5) implementations 16498 if (typeof(that.plotOptions.tooltip) === 'boolean') { 16499 that.plotOptions.tooltipOpts.show = that.plotOptions.tooltip; 16500 that.plotOptions.tooltip = that.plotOptions.tooltipOpts; 16501 delete that.plotOptions.tooltipOpts; 16502 } 16503 16504 // if not enabled return 16505 if (that.plotOptions.tooltip.show === false || typeof that.plotOptions.tooltip.show === 'undefined') return; 16506 16507 // shortcut to access tooltip options 16508 that.tooltipOptions = that.plotOptions.tooltip; 16509 16510 if (that.tooltipOptions.$compat) { 16511 that.wfunc = 'width'; 16512 that.hfunc = 'height'; 16513 } else { 16514 that.wfunc = 'innerWidth'; 16515 that.hfunc = 'innerHeight'; 16516 } 16517 16518 // create tooltip DOM element 16519 var $tip = that.getDomElement(); 16520 16521 // bind event 16522 $( plot.getPlaceholder() ).bind("plothover", plothover); 16523 if (that.tooltipOptions.clickTips) { 16524 $( plot.getPlaceholder() ).bind("plotclick", plotclick); 16525 } 16526 that.clickmode = false; 16527 16528 $(eventHolder).bind('mousemove', mouseMove); 16529 }); 16530 16531 plot.hooks.shutdown.push(function (plot, eventHolder){ 16532 $(plot.getPlaceholder()).unbind("plothover", plothover); 16533 $(plot.getPlaceholder()).unbind("plotclick", plotclick); 16534 plot.removeTooltip(); 16535 $(eventHolder).unbind("mousemove", mouseMove); 16536 }); 16537 16538 function mouseMove(e){ 16539 var pos = {}; 16540 pos.x = e.pageX; 16541 pos.y = e.pageY; 16542 plot.setTooltipPosition(pos); 16543 } 16544 16545 /** 16546 * open the tooltip (if not already open) and freeze it on the current position till the next click 16547 */ 16548 function plotclick(event, pos, item) { 16549 if (! that.clickmode) { 16550 // it is the click activating the clicktip 16551 plothover(event, pos, item); 16552 if (that.getDomElement().is(":visible")) { 16553 $(plot.getPlaceholder()).unbind("plothover", plothover); 16554 that.clickmode = true; 16555 } 16556 } else { 16557 // it is the click deactivating the clicktip 16558 $( plot.getPlaceholder() ).bind("plothover", plothover); 16559 plot.hideTooltip(); 16560 that.clickmode = false; 16561 } 16562 } 16563 16564 function plothover(event, pos, item) { 16565 // Simple distance formula. 16566 var lineDistance = function (p1x, p1y, p2x, p2y) { 16567 return Math.sqrt((p2x - p1x) * (p2x - p1x) + (p2y - p1y) * (p2y - p1y)); 16568 }; 16569 16570 // Here is some voodoo magic for determining the distance to a line form a given point {x, y}. 16571 var dotLineLength = function (x, y, x0, y0, x1, y1, o) { 16572 if (o && !(o = 16573 function (x, y, x0, y0, x1, y1) { 16574 if (typeof x0 !== 'undefined') return { x: x0, y: y }; 16575 else if (typeof y0 !== 'undefined') return { x: x, y: y0 }; 16576 16577 var left, 16578 tg = -1 / ((y1 - y0) / (x1 - x0)); 16579 16580 return { 16581 x: left = (x1 * (x * tg - y + y0) + x0 * (x * -tg + y - y1)) / (tg * (x1 - x0) + y0 - y1), 16582 y: tg * left - tg * x + y 16583 }; 16584 } (x, y, x0, y0, x1, y1), 16585 o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1)) 16586 ) { 16587 var l1 = lineDistance(x, y, x0, y0), l2 = lineDistance(x, y, x1, y1);
16588 return l1 > l2 ? l2 : l1; 16589 } else { 16590 var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1; 16591 return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b); 16592 } 16593 }; 16594 16595 if (item) { 16596 plot.showTooltip(item, that.tooltipOptions.snap ? item : pos); 16597 } else if (that.plotOptions.series.lines.show && that.tooltipOptions.lines === true) { 16598 var maxDistance = that.plotOptions.grid.mouseActiveRadius; 16599 16600 var closestTrace = { 16601 distance: maxDistance + 1 16602 }; 16603 16604 var ttPos = pos; 16605 16606 $.each(plot.getData(), function (i, series) { 16607 var xBeforeIndex = 0, 16608 xAfterIndex = -1; 16609 16610 // Our search here assumes our data is sorted via the x-axis. 16611 // TODO: Improve efficiency somehow - search smaller sets of data. 16612 for (var j = 1; j < series.data.length; j++) { 16613 if (series.data[j - 1][0] <= pos.x && series.data[j][0] >= pos.x) { 16614 xBeforeIndex = j - 1; 16615 xAfterIndex = j; 16616 } 16617 } 16618 16619 if (xAfterIndex === -1) { 16620 plot.hideTooltip(); 16621 return; 16622 } 16623 16624 var pointPrev = { x: series.data[xBeforeIndex][0], y: series.data[xBeforeIndex][1] }, 16625 pointNext = { x: series.data[xAfterIndex][0], y: series.data[xAfterIndex][1] }; 16626 16627 var distToLine = dotLineLength(series.xaxis.p2c(pos.x), series.yaxis.p2c(pos.y), series.xaxis.p2c(pointPrev.x), 16628 series.yaxis.p2c(pointPrev.y), series.xaxis.p2c(pointNext.x), series.yaxis.p2c(pointNext.y), false); 16629 16630 if (distToLine < closestTrace.distance) { 16631 16632 var closestIndex = lineDistance(pointPrev.x, pointPrev.y, pos.x, pos.y) < 16633 lineDistance(pos.x, pos.y, pointNext.x, pointNext.y) ? xBeforeIndex : xAfterIndex; 16634 16635 var pointSize = series.datapoints.pointsize; 16636 16637 // Calculate the point on the line vertically closest to our cursor. 16638 var pointOnLine = [ 16639 pos.x, 16640 pointPrev.y + ((pointNext.y - pointPrev.y) * ((pos.x - pointPrev.x) / (pointNext.x - pointPrev.x))) 16641 ]; 16642 16643 var item = { 16644 datapoint: pointOnLine, 16645 dataIndex: closestIndex, 16646 series: series, 16647 seriesIndex: i 16648 }; 16649 16650 closestTrace = { 16651 distance: distToLine, 16652 item: item 16653 }; 16654 16655 if (that.tooltipOptions.snap) { 16656 ttPos = { 16657 pageX: series.xaxis.p2c(pointOnLine[0]), 16658 pageY: series.yaxis.p2c(pointOnLine[1]) 16659 }; 16660 } 16661 } 16662 }); 16663 16664 if (closestTrace.distance < maxDistance + 1) 16665 plot.showTooltip(closestTrace.item, ttPos); 16666 else 16667 plot.hideTooltip(); 16668 } else { 16669 plot.hideTooltip(); 16670 } 16671 } 16672 16673 // Quick little function for setting the tooltip position. 16674 plot.setTooltipPosition = function (pos) { 16675 var $tip = that.getDomElement(); 16676 16677 var totalTipWidth = $tip.outerWidth() + that.tooltipOptions.shifts.x; 16678 var totalTipHeight = $tip.outerHeight() + that.tooltipOptions.shifts.y; 16679 if ((pos.x - $(window).scrollLeft()) > ($(window)[that.wfunc]() - totalTipWidth)) { 16680 pos.x -= totalTipWidth; 16681 pos.x = Math.max(pos.x, 0); 16682 } 16683 if ((pos.y - $(window).scrollTop()) > ($(window)[that.hfunc]() - totalTipHeight)) { 16684 pos.y -= totalTipHeight; 16685 } 16686 16687 /* 16688 The section applies the new positioning ONLY if pos.x and pos.y 16689 are numbers. If they are undefined or not a number, use the last 16690 known numerical position. This hack fixes a bug that kept pie 16691 charts from keeping their tooltip positioning. 16692 */ 16693 16694 if (isNaN(pos.x)) { 16695 that.tipPosition.x = that.tipPosition.xPrev; 16696 } 16697 else { 16698 that.tipPosition.x = pos.x; 16699 that.tipPosition.xPrev = pos.x; 16700 } 16701 if (isNaN(pos.y)) { 16702 that.tipPosition.y = that.tipPosition.yPrev; 16703 } 16704 else { 16705 that.tipPosition.y = pos.y; 16706 that.tipPosition.yPrev = pos.y; 16707 } 16708 16709 }; 16710 16711 // Quick little function for showing the tooltip. 16712 plot.showTooltip = function (target, position, targetPosition) { 16713 var $tip = that.getDomElement(); 16714 16715 // convert tooltip content template to real tipText 16716 var tipText = that.stringFormat(that.tooltipOptions.content, target); 16717 if (tipText === '') 16718 return; 16719 16720 $tip.html(tipText); 16721 plot.setTooltipPosition({ x: that.tipPosition.x, y: that.tipPosition.y }); 16722 $tip.css({ 16723 left: that.tipPosition.x + that.tooltipOptions.shifts.x, 16724 top: that.tipPosition.y + that.tooltipOptions.shifts.y 16725 }).show(); 16726 16727 // run callback 16728 if (typeof that.tooltipOptions.onHover === 'function') { 16729 that.tooltipOptions.onHover(target, $tip); 16730 } 16731 }; 16732 16733 // Quick little function for hiding the tooltip. 16734 plot.hideTooltip = function () { 16735 that.getDomElement().hide().html(''); 16736 }; 16737 16738 plot.removeTooltip = function() { 16739 that.getDomElement().remove(); 16740 }; 16741 }; 16742 16743 /** 16744 * get or create tooltip DOM element 16745 * @return jQuery object 16746 */ 16747 FlotTooltip.prototype.getDomElement = function () { 16748 var $tip = $('<div>'); 16749 if (this.tooltipOptions && this.tooltipOptions.cssClass) { 16750 $tip = $('.' + this.tooltipOptions.cssClass); 16751 16752 if( $tip.length === 0 ){ 16753 $tip = $('<div />').addClass(this.tooltipOptions.cssClass); 16754 $tip.appendTo('body').hide().css({position: 'absolute'}); 16755 16756 if(this.tooltipOptions.defaultTheme) { 16757 $tip.css({ 16758 'background': '#fff', 16759 'z-index': '1040', 16760 'padding': '0.4em 0.6em', 16761 'border-radius': '0.5em', 16762 'font-size': '0.8em', 16763 'border': '1px solid #111', 16764 'display': 'none', 16765 'white-space': 'nowrap' 16766 }); 16767 } 16768 } 16769 } 16770 16771 return $tip; 16772 }; 16773 16774 /** 16775 * core function, create tooltip content 16776 * @param {string} content - template with tooltip content 16777 * @param {object} item - Flot item 16778 * @return {string} real tooltip content for current item 16779 */ 16780 FlotTooltip.prototype.stringFormat = function (content, item) { 16781 var percentPattern = /%p\.{0,1}(\d{0,})/; 16782 var seriesPattern = /%s/; 16783 var colorPattern = /%c/; 16784 var xLabelPattern = /%lx/;
16784 // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded 16785 var yLabelPattern = /%ly/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded 16786 var xPattern = /%x\.{0,1}(\d{0,})/; 16787 var yPattern = /%y\.{0,1}(\d{0,})/; 16788 var xPatternWithoutPrecision = "%x"; 16789 var yPatternWithoutPrecision = "%y"; 16790 var customTextPattern = "%ct"; 16791 var nPiePattern = "%n"; 16792 16793 var x, y, customText, p, n; 16794 16795 // for threshold plugin we need to read data from different place 16796 if (typeof item.series.threshold !== "undefined") { 16797 x = item.datapoint[0]; 16798 y = item.datapoint[1]; 16799 customText = item.datapoint[2]; 16800 } 16801 16802 // for CurvedLines plugin we need to read data from different place 16803 else if (typeof item.series.curvedLines !== "undefined") { 16804 x = item.datapoint[0]; 16805 y = item.datapoint[1]; 16806 } 16807 16808 else if (typeof item.series.lines !== "undefined" && item.series.lines.steps) { 16809 x = item.series.datapoints.points[item.dataIndex * 2]; 16810 y = item.series.datapoints.points[item.dataIndex * 2 + 1]; 16811 // TODO: where to find custom text in this variant? 16812 customText = ""; 16813 } else { 16814 x = item.series.data[item.dataIndex][0]; 16815 y = item.series.data[item.dataIndex][1]; 16816 customText = item.series.data[item.dataIndex][2]; 16817 } 16818 16819 // I think this is only in case of threshold plugin 16820 if (item.series.label === null && item.series.originSeries) { 16821 item.series.label = item.series.originSeries.label; 16822 } 16823 16824 // if it is a function callback get the content string 16825 if (typeof(content) === 'function') { 16826 content = content(item.series.label, x, y, item); 16827 } 16828 16829 // the case where the passed content is equal to false 16830 if (typeof(content) === 'boolean' && !content) { 16831 return ''; 16832 } 16833 16834 /* replacement of %ct and other multi-character templates must 16835 precede the replacement of single-character templates 16836 to avoid conflict between '%c' and '%ct' and similar substrings 16837 */ 16838 if (customText) { 16839 content = content.replace(customTextPattern, customText); 16840 } 16841 16842 // percent match for pie charts and stacked percent 16843 if (typeof (item.series.percent) !== 'undefined') { 16844 p = item.series.percent; 16845 } else if (typeof (item.series.percents) !== 'undefined') { 16846 p = item.series.percents[item.dataIndex]; 16847 } 16848 if (typeof p === 'number') { 16849 content = this.adjustValPrecision(percentPattern, content, p); 16850 } 16851 16852 // replace %n with number of items represented by slice in pie charts 16853 if (item.series.hasOwnProperty('pie')) { 16854 if (typeof item.series.data[0][1] !== 'undefined') { 16855 n = item.series.data[0][1]; 16856 } 16857 } 16858 if (typeof n === 'number') { 16859 content = content.replace(nPiePattern, n); 16860 } 16861 16862 // series match 16863 if (typeof(item.series.label) !== 'undefined') { 16864 content = content.replace(seriesPattern, item.series.label); 16865 } else { 16866 //remove %s if label is undefined 16867 content = content.replace(seriesPattern, ""); 16868 } 16869 16870 // color match 16871 if (typeof(item.series.color) !== 'undefined') { 16872 content = content.replace(colorPattern, item.series.color); 16873 } else { 16874 //remove %s if color is undefined 16875 content = content.replace(colorPattern, ""); 16876 } 16877 16878 // x axis label match 16879 if (this.hasAxisLabel('xaxis', item)) { 16880 content = content.replace(xLabelPattern, item.series.xaxis.options.axisLabel); 16881 } else { 16882 //remove %lx if axis label is undefined or axislabels plugin not present 16883 content = content.replace(xLabelPattern, ""); 16884 } 16885 16886 // y axis label match 16887 if (this.hasAxisLabel('yaxis', item)) { 16888 content = content.replace(yLabelPattern, item.series.yaxis.options.axisLabel); 16889 } else { 16890 //remove %ly if axis label is undefined or axislabels plugin not present 16891 content = content.replace(yLabelPattern, ""); 16892 } 16893 16894 // time mode axes with custom dateFormat 16895 if (this.isTimeMode('xaxis', item) && this.isXDateFormat(item)) { 16896 content = content.replace(xPattern, this.timestampToDate(x, this.tooltipOptions.xDateFormat, item.series.xaxis.options)); 16897 } 16898 if (this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) { 16899 content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat, item.series.yaxis.options)); 16900 } 16901 16902 // set precision if defined 16903 if (typeof x === 'number') { 16904 content = this.adjustValPrecision(xPattern, content, x); 16905 } 16906 if (typeof y === 'number') { 16907 content = this.adjustValPrecision(yPattern, content, y); 16908 } 16909 16910 // change x from number to given label, if given 16911 if (typeof item.series.xaxis.ticks !== 'undefined') { 16912 16913 var ticks; 16914 if (this.hasRotatedXAxisTicks(item)) { 16915 // xaxis.ticks will be an empty array if tickRotor is being used, but the values are available in rotatedTicks 16916 ticks = 'rotatedTicks'; 16917 } else { 16918 ticks = 'ticks'; 16919 } 16920 16921 // see https://github.com/krzysu/flot.tooltip/issues/65 16922 var tickIndex = item.dataIndex + item.seriesIndex; 16923 16924 for (var xIndex in item.series.xaxis[ticks]) { 16925 if (item.series.xaxis[ticks].hasOwnProperty(tickIndex) && !this.isTimeMode('xaxis', item)) { 16926 var valueX = (this.isCategoriesMode('xaxis', item)) ? item.series.xaxis[ticks][tickIndex].label : item.series.xaxis[ticks][tickIndex].v; 16927 if (valueX === x) { 16928 content = content.replace(xPattern, item.series.xaxis[ticks][tickIndex].label.replace(/\$/g, '$$$$')); 16929 } 16930 } 16931 } 16932 } 16933 16934 // change y from number to given label, if given 16935 if (typeof item.series.yaxis.ticks !== 'undefined') { 16936 for (var yIndex in item.series.yaxis.ticks) { 16937 if (item.series.yaxis.ticks.hasOwnProperty(yIndex)) { 16938 var valueY = (this.isCategoriesMode('yaxis', item)) ? item.series.yaxis.ticks[yIndex].label : item.series.yaxis.ticks[yIndex].v; 16939 if (valueY === y) { 16940 content = content.replace(yPattern, item.series.yaxis.ticks[yIndex].label.replace(/\$/g, '$$$$')); 16941 } 16942 } 16943 } 16944 } 16945 16946 // if no value customization, use tickFormatter by default 16947 if (typeof item.series.xaxis.tickFormatter !== 'undefined') { 16948 //escape dollar 16949 content = content.replace(xPatternWithoutPrecision, item.series.xaxis.tickFormatter(x, item.series.xaxis).replace(/\$/g, '$$')); 16950 } 16951 if (typeof item.series.yaxis.tickFormatter !== 'undefined') { 16952 //escape dollar 16953 content = content.replace(yPatternWithoutPrecision, item.series.yaxis.tickFormatter(y, item.series.yaxis).replace(/\$/g, '$$')); 16954 } 16955 16956 return content; 16957 }; 16958 16959 // helpers just for readability 16960 FlotTooltip.prototype.isTimeMode = function (axisName, item) { 16961 return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'time'); 16962 }; 16963 16964 FlotTooltip.prototype.isXDateFormat = function (item) { 16965 return (typeof this.tooltipOptions.xDateFormat !== 'undefined' && this.tooltipOptions.xDateFormat !== null); 16966 }; 16967 16968 FlotTooltip.prototype.isYDateFormat = function (item) { 16969 return (typeof this.tooltipOptions.yDateFormat !== 'undefined' && this.tooltipOptions.yDateFormat !== null); 16970 }; 16971 16972 FlotTooltip.prototype.isCategoriesMode = function (axisName, item) { 16973 return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'categories'); 16974 }; 16975 16976 // 16977 FlotTooltip.prototype.timestampToDate = function (tmst, dateFormat, options) { 16978 var theDate = $.plot.dateGenerator(tmst, options); 16979 return $.plot.formatDate(theDate, dateFormat, this.tooltipOptions.monthNames, this.tooltipOptions.dayNames); 16980 }; 16981 16982 // 16983 FlotTooltip.prototype.adjustValPrecision = function (pattern, content, value) { 16984 16985 var precision; 16986 var matchResult = content.match(pattern); 16987 if( matchResult !== null ) { 16988 if(RegExp.$1 !== '') { 16989 precision = RegExp.$1; 16990 value = value.toFixed(precision); 16991 16992 // only replace content if precision exists, in other case use thickformater 16993 content = content.replace(pattern, value); 16994 } 16995 } 16996 return content; 16997 }; 16998 16999 // other plugins detection below 17000 17001 // check if flot-axislabels plugin (https://github.com/markrc
vendor: 4,216 bytes, lines 17001-17086
17001ote/flot-axislabels) is used and that an axis label is given 17002 FlotTooltip.prototype.hasAxisLabel = function (axisName, item) { 17003 return ($.inArray('axisLabels', this.plotPlugins) !== -1 && typeof item.series[axisName].options.axisLabel !== 'undefined' && item.series[axisName].options.axisLabel.length > 0); 17004 }; 17005 17006 // check whether flot-tickRotor, a plugin which allows rotation of X-axis ticks, is being used 17007 FlotTooltip.prototype.hasRotatedXAxisTicks = function (item) { 17008 return ($.inArray('tickRotor',this.plotPlugins) !== -1 && typeof item.series.xaxis.rotatedTicks !== 'undefined'); 17009 }; 17010 17011 // 17012 var init = function (plot) { 17013 new FlotTooltip(plot); 17014 }; 17015 17016 // define Flot plugin 17017 $.plot.plugins.push({ 17018 init: init, 17019 options: defaultOptions, 17020 name: 'tooltip', 17021 version: '0.8.5' 17022 }); 17023 17024})(jQuery); 17025 17026;/* Flot plugin for automatically redrawing plots as the placeholder resizes. 17027 17028Copyright (c) 2007-2014 IOLA and Ole Laursen. 17029Licensed under the MIT license. 17030 17031It works by listening for changes on the placeholder div (through the jQuery 17032resize event plugin) - if the size changes, it will redraw the plot. 17033 17034There are no options. If you need to disable the plugin for some plots, you 17035can just fix the size of their placeholders. 17036 17037*/ 17038 17039/* Inline dependency: 17040 * jQuery resize event - v1.1 - 3/14/2010 17041 * http://benalman.com/projects/jquery-resize-plugin/ 17042 * 17043 * Copyright (c) 2010 "Cowboy" Ben Alman 17044 * Dual licensed under the MIT and GPL licenses. 17045 * http://benalman.com/about/license/ 17046 */ 17047(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this); 17048 17049(function ($) { 17050 var options = { }; // no options 17051 17052 function init(plot) { 17053 function onResize() { 17054 var placeholder = plot.getPlaceholder(); 17055 17056 // somebody might have hidden us and we can't plot 17057 // when we don't have the dimensions 17058 if (placeholder.width() == 0 || placeholder.height() == 0) 17059 return; 17060 17061 plot.resize(); 17062 plot.setupGrid(); 17063 plot.draw(); 17064 } 17065 17066 function bindEvents(plot, eventHolder) { 17067 plot.getPlaceholder().resize(onResize); 17068 } 17069 17070 function shutdown(plot, eventHolder) { 17071 plot.getPlaceholder().unbind("resize", onResize); 17072 } 17073 17074 plot.hooks.bindEvents.push(bindEvents); 17075 plot.hooks.shutdown.push(shutdown); 17076 } 17077 17078 $.plot.plugins.push({ 17079 init: init, 17080 options: options, 17081 name: 'resize', 17082 version: '1.0' 17083 }); 17084})(jQuery); 17085 17086;
vendor: 23,809 bytes, lines 17086-17905
17086/* Flot plugin for rendering pie charts. 17087 17088Copyright (c) 2007-2014 IOLA and Ole Laursen. 17089Licensed under the MIT license. 17090 17091The plugin assumes that each series has a single data value, and that each 17092value is a positive integer or zero. Negative numbers don't make sense for a 17093pie chart, and have unpredictable results. The values do NOT need to be 17094passed in as percentages; the plugin will calculate the total and per-slice 17095percentages internally. 17096 17097* Created by Brian Medendorp 17098 17099* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars 17100 17101The plugin supports these options: 17102 17103 series: { 17104 pie: { 17105 show: true/false 17106 radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto' 17107 innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect 17108 startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result 17109 tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show) 17110 offset: { 17111 top: integer value to move the pie up or down 17112 left: integer value to move the pie left or right, or 'auto' 17113 }, 17114 stroke: { 17115 color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF') 17116 width: integer pixel width of the stroke 17117 }, 17118 label: { 17119 show: true/false, or 'auto' 17120 formatter: a user-defined function that modifies the text/style of the label text 17121 radius: 0-1 for percentage of fullsize, or a specified pixel length 17122 background: { 17123 color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000') 17124 opacity: 0-1 17125 }, 17126 threshold: 0-1 for the percentage value at which to hide labels (if they're too small) 17127 }, 17128 combine: { 17129 threshold: 0-1 for the percentage value at which to combine slices (if they're too small) 17130 color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined 17131 label: any text value of what the combined slice should be labeled 17132 } 17133 highlight: { 17134 opacity: 0-1 17135 } 17136 } 17137 } 17138 17139More detail and specific examples can be found in the included HTML file. 17140 17141*/ 17142 17143(function($) { 17144 17145 // Maximum redraw attempts when fitting labels within the plot 17146 17147 var REDRAW_ATTEMPTS = 10; 17148 17149 // Factor by which to shrink the pie when fitting labels within the plot 17150 17151 var REDRAW_SHRINK = 0.95; 17152 17153 function init(plot) { 17154 17155 var canvas = null, 17156 target = null, 17157 options = null, 17158 maxRadius = null, 17159 centerLeft = null, 17160 centerTop = null, 17161 processed = false, 17162 ctx = null; 17163 17164 // interactive variables 17165 17166 var highlights = []; 17167 17168 // add hook to determine if pie plugin in enabled, and then perform necessary operations 17169 17170 plot.hooks.processOptions.push(function(plot, options) { 17171 if (options.series.pie.show) { 17172 17173 options.grid.show = false; 17174 17175 // set labels.show 17176 17177 if (options.series.pie.label.show == "auto") { 17178 if (options.legend.show) { 17179 options.series.pie.label.show = false; 17180 } else { 17181 options.series.pie.label.show = true; 17182 } 17183 } 17184 17185 // set radius 17186 17187 if (options.series.pie.radius == "auto") { 17188 if (options.series.pie.label.show) { 17189 options.series.pie.radius = 3/4; 17190 } else { 17191 options.series.pie.radius = 1; 17192 } 17193 } 17194 17195 // ensure sane tilt 17196 17197 if (options.series.pie.tilt > 1) { 17198 options.series.pie.tilt = 1; 17199 } else if (options.series.pie.tilt < 0) { 17200 options.series.pie.tilt = 0; 17201 } 17202 } 17203 }); 17204 17205 plot.hooks.bindEvents.push(function(plot, eventHolder) { 17206 var options = plot.getOptions(); 17207 if (options.series.pie.show) { 17208 if (options.grid.hoverable) { 17209 eventHolder.unbind("mousemove").mousemove(onMouseMove); 17210 } 17211 if (options.grid.clickable) { 17212 eventHolder.unbind("click").click(onClick); 17213 } 17214 } 17215 }); 17216 17217 plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) { 17218 var options = plot.getOptions(); 17219 if (options.series.pie.show) { 17220 processDatapoints(plot, series, data, datapoints); 17221 } 17222 }); 17223 17224 plot.hooks.drawOverlay.push(function(plot, octx) { 17225 var options = plot.getOptions(); 17226 if (options.series.pie.show) { 17227 drawOverlay(plot, octx); 17228 } 17229 }); 17230 17231 plot.hooks.draw.push(function(plot, newCtx) { 17232 var options = plot.getOptions(); 17233 if (options.series.pie.show) { 17234 draw(plot, newCtx); 17235 } 17236 }); 17237 17238 function processDatapoints(plot, series, datapoints) { 17239 if (!processed) { 17240 processed = true; 17241 canvas = plot.getCanvas(); 17242 target = $(canvas).parent(); 17243 options = plot.getOptions(); 17244 plot.setData(combine(plot.getData())); 17245 } 17246 } 17247 17248 function combine(data) { 17249 17250 var total = 0, 17251 combined = 0, 17252 numCombined = 0, 17253 color = options.series.pie.combine.color, 17254 newdata = []; 17255 17256 // Fix up the raw data from Flot, ensuring the data is numeric 17257 17258 for (var i = 0; i < data.length; ++i) { 17259 17260 var value = data[i].data; 17261 17262 // If the data is an array, we'll assume that it's a standard 17263 // Flot x-y pair, and are concerned only with the second value. 17264 17265 // Note how we use the original array, rather than creating a 17266 // new one; this is more efficient and preserves any extra data 17267 // that the user may have stored in higher indexes. 17268 17269 if ($.isArray(value) && value.length == 1) { 17270 value = value[0]; 17271 } 17272 17273 if ($.isArray(value)) { 17274 // Equivalent to $.isNumeric() but compatible with jQuery < 1.7 17275 if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) { 17276 value[1] = +value[1]; 17277 } else { 17278 value[1] = 0; 17279 } 17280 } else if (!isNaN(parseFloat(value)) && isFinite(value)) { 17281 value = [1, +value]; 17282 } else { 17283 value = [1, 0]; 17284 } 17285 17286 data[i].data = [value]; 17287 } 17288 17289 // Sum up all the slices, so we can calculate percentages for each 17290 17291 for (var i = 0; i < data.length; ++i) { 17292 total += data[i].data[0][1]; 17293 } 17294 17295 // Count the number of slices with percentages below the combine 17296 // threshold; if it turns out to be just one, we won't combine. 17297 17298 for (var i = 0; i < data.length; ++i) { 17299 var value = data[i].data[0][1]; 17300 if (value / total <= options.series.pie.combine.threshold) { 17301 combined += value; 17302 numCombined++; 17303 if (!color) { 17304 color = data[i].color; 17305 } 17306 } 17307 } 17308 17309 for (var i = 0; i < data.length; ++i) { 17310 var value = data[i].data[0][1]; 17311 if (numCombined < 2 || value / total > options.series.pie.combine.threshold) { 17312 newdata.push( 17313 $.extend(data[i], { /* extend to allow keeping all other original data values 17314 and using them e.g. in labelFormatter. */ 17315 data: [[1, value]], 17316 color: data[i].color, 17317 label: data[i].label, 17318 angle: value * Math.PI * 2 / total, 17319 percent: value / (total / 100) 17320 }) 17321 ); 17322 } 17323 } 17324 17325 if (numCombined > 1) { 17326 newdata.push({ 17327 data: [[1, combined]], 17328 color: color, 17329 label: options.series.pie.combine.label, 17330 angle: combined * Math.PI * 2 / total, 17331 percent: combined / (total / 100) 17332 }); 17333 } 17334 17335 return newdata; 17336 } 17337 17338 function draw(plot, newCtx) { 17339 17340 if (!target) { 17341 return; // if no series were passed 17342 } 17343 17344 var canvasWidth = plot.getPlaceholder().width(), 17345 canvasHeight = plot.getPlaceholder().height(), 17346 legendWidth = target.children().filter(".legend").children().width() || 0; 17347 17348 ctx = newCtx; 17349 17350 // WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE! 17351 17352 // When combining smaller slices into an 'other' slice, we need to 17353 // add a new series. Since Flot gives plugins no way to modify the 17354 // list of series, the pie plugin uses a hack where the first call 17355 // to processDatapoints results in a call to setData with the new 17356 // list of series, then subsequent processDatapoints do nothing. 17357 17358 // The plugin-global 'processed' flag is used to control this hack; 17359 // it starts out false, and is set to true after the first call to 17360 // processDatapoints. 17361 17362 // Unfortunately this turns future setData calls into no-ops; they 17363 // call processDatapoints, the flag is true, and nothing happens. 17364 17365 // To fix this we'll set the flag back to false here in draw, when 17366 // all series have been processed, so the next sequence of calls to 17367 // processDatapoints once again starts out with a slice-combine. 17368 // This is really a hack; in 0.9 we need to give plugins a proper 17369 // way to modify series before any processing begins. 17370 17371 processed = false; 17372 17373 // calculate maximum radius and center point 17374 17375 maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2; 17376 centerTop = canvasHeight / 2 + options.series.pie.offset.top; 17377 centerLeft = canvasWidth / 2; 17378 17379 if (options.series.pie.offset.left == "auto") { 17380 if (options.legend.position.match("w")) { 17381 centerLeft += legendWidth / 2; 17382 } else { 17383 centerLeft -= legendWidth / 2; 17384 } 17385 if (centerLeft < maxRadius) { 17386 centerLeft = maxRadius; 17387 } else if (centerLeft > canvasWidth - maxRadius) { 17388 centerLeft = canvasWidth - maxRadius; 17389 } 17390 } else { 17391 centerLeft += options.series.pie.offset.left; 17392 } 17393 17394 var slices = plot.getData(), 17395 attempts = 0; 17396 17397 // Keep shrinking the pie's radius until drawPie returns true, 17398 // indicating that all the labels fit, or we try too many times. 17399 17400 do { 17401 if (attempts > 0) { 17402 maxRadius *= REDRAW_SHRINK; 17403 } 17404 attempts += 1; 17405 clear(); 17406 if (options.series.pie.tilt <= 0.8) { 17407 drawShadow(); 17408 } 17409 } while (!drawPie() && attempts < REDRAW_ATTEMPTS) 17410 17411 if (attempts >= REDRAW_ATTEMPTS) { 17412 clear(); 17413 target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>"); 17414 } 17415 17416 if (plot.setSeries && plot.insertLegend) { 17417 plot.setSeries(slices); 17418 plot.insertLegend(); 17419 } 17420 17421 // we're actually done at this point, just defining internal functions at this point 17422 17423 function clear() { 17424 ctx.clearRect(0, 0, canvasWidth, canvasHeight); 17425 target.children().filter(".pieLabel, .pieLabelBackground").remove(); 17426 } 17427 17428 function drawShadow() { 17429 17430 var shadowLeft = options.series.pie.shadow.left; 17431 var shadowTop = options.series.pie.shadow.top; 17432 var edge = 10; 17433 var alpha = options.series.pie.shadow.alpha; 17434 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; 17435 17436 if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) { 17437 return; // shadow would be outside canvas, so don't draw it 17438 } 17439 17440 ctx.save(); 17441 ctx.translate(shadowLeft,shadowTop); 17442 ctx.globalAlpha = alpha; 17443 ctx.fillStyle = "#000"; 17444 17445 // center and rotate to starting position 17446 17447 ctx.translate(centerLeft,centerTop); 17448 ctx.scale(1, options.series.pie.tilt); 17449 17450 //radius -= edge; 17451 17452 for (var i = 1; i <= edge; i++) { 17453 ctx.beginPath(); 17454 ctx.arc(0, 0, radius, 0, Math.PI * 2, false); 17455 ctx.fill(); 17456 radius -= i; 17457 } 17458 17459 ctx.restore(); 17460 } 17461 17462 function drawPie() { 17463 17464 var startAngle = Math.PI * options.series.pie.startAngle; 17465 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; 17466 17467 // center and rotate to starting position 17468 17469 ctx.save(); 17470 ctx.translate(centerLeft,centerTop); 17471 ctx.scale(1, options.series.pie.tilt); 17472 //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera 17473 17474 // draw slices 17475 17476 ctx.save(); 17477 var currentAngle = startAngle; 17478 for (var i = 0; i < slices.length; ++i) { 17479 slices[i].startAngle = currentAngle; 17480 drawSlice(slices[i].angle, slices[i].color, true); 17481 } 17482 ctx.restore(); 17483 17484 // draw slice outlines 17485 17486 if (options.series.pie.stroke.width > 0) { 17487 ctx.save(); 17488 ctx.lineWidth = options.series.pie.stroke.width; 17489 currentAngle = startAngle; 17490 for (var i = 0; i < slices.length; ++i) { 17491 drawSlice(slices[i].angle, options.series.pie.stroke.color, false); 17492 } 17493 ctx.restore(); 17494 } 17495 17496 // draw donut hole 17497 17498 drawDonutHole(ctx); 17499 17500 ctx.restore(); 17501 17502 // Draw the labels, returning true if they fit within the plot 17503 17504 if (options.series.pie.label.show) { 17505 return drawLabels(); 17506 } else return true; 17507 17508 function drawSlice(angle, color, fill) { 17509 17510 if (angle <= 0 || isNaN(angle)) { 17511 return; 17512 } 17513 17514 if (fill) { 17515 ctx.fillStyle = color; 17516 } else { 17517 ctx.strokeStyle = color; 17518 ctx.lineJoin = "round"; 17519 } 17520 17521 ctx.beginPath(); 17522 if (Math.abs(angle - Math.PI * 2) > 0.000000001) { 17523 ctx.moveTo(0, 0); // Center of the pie 17524 } 17525 17526 //ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera 17527 ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false); 17528 ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false); 17529 ctx.closePath(); 17530 //ctx.rotate(angle); // This doesn't work properly in Opera 17531 currentAngle += angle; 17532 17533 if (fill) { 17534 ctx.fill(); 17535 } else { 17536 ctx.stroke(); 17537 } 17538 } 17539 17540 function drawLabels() { 17541 17542 var currentAngle = startAngle; 17543 var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius; 17544 17545 for (var i = 0; i < slices.length; ++i) { 17546 if (slices[i].percent >= options.series.pie.label.threshold * 100) { 17547 if (!drawLabel(slices[i], currentAngle, i)) { 17548 return false; 17549 } 17550 } 17551 currentAngle += slices[i].angle; 17552 } 17553 17554 return true; 17555 17556 function drawLabel(slice, startAngle, index) { 17557 17558 if (slice.data[0][1] == 0) { 17559 return true; 17560 } 17561 17562 // format label text 17563 17564 var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter; 17565 17566 if (lf) { 17567 text = lf(slice.label, slice); 17568 } else { 17569 text = slice.label; 17570 } 17571 17572 if (plf) { 17573 text = plf(text, slice); 17574 } 17575 17576 var halfAngle = ((startAngle + slice.angle) + startAngle) / 2; 17577 var x = centerLeft + Math.round(Math.cos(halfAngle) * radius); 17578 var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt; 17579 17580 var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>"; 17581 target.append(html); 17582 17583 var label = target.children("#pieLabel" + index); 17584 var labelTop = (y - label.height() / 2); 17585 var labelLeft = (x - label.width() / 2); 17586 17587 label.css("top", labelTop); 17588 label.css("left", labelLeft); 17589 17590 // check to make sure that the label is not outside the canvas 17591 17592 if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) { 17593 return false; 17594 } 17595 17596 if (options.series.pie.label.background.opacity != 0) { 17597 17598 // put in the transparent background separately to avoid blended labels and label boxes 17599 17600 var c = options.series.pie.label.background.color; 17601 17602 if (c == null) { 17603 c = slice.color; 17604 } 17605 17606 var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;"; 17607 $("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>") 17608 .css("opacity", options.series.pie.label.background.opacity) 17609 .insertBefore(label); 17610 } 17611 17612 return true; 17613 } // end individual label function 17614 } // end drawLabels function 17615 } // end drawPie function 17616 } // end draw function 17617 17618 // Placed here because it needs to be accessed from multiple locations 17619 17620 function drawDonutHole(layer) { 17621 if (options.series.pie.innerRadius > 0) { 17622 17623 // subtract the center 17624 17625 layer.save(); 17626 var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius; 17627 layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color 17628 layer.beginPath(); 17629 layer.fillStyle = options.series.pie.stroke.color; 17630 layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); 17631 layer.fill(); 17632 layer.closePath(); 17633 layer.restore(); 17634 17635 // add inner stroke 17636 17637 layer.save(); 17638 layer.beginPath(); 17639 layer.strokeStyle = options.series.pie.stroke.color; 17640 layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); 17641 layer.stroke(); 17642 layer.closePath(); 17643 layer.restore(); 17644 17645 // TODO: add extra shadow inside hole (with a mask) if the pie is tilted. 17646 } 17647 } 17648 17649 //-- Additional Interactive related functions -- 17650 17651 function isPointInPoly(poly, pt) { 17652 for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i) 17653 ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1])) 17654 && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0]) 17655 && (c = !c); 17656 return c; 17657 } 17658 17659 function findNearbySlice(mouseX, mouseY) { 17660 17661 var slices = plot.getData(), 17662 options = plot.getOptions(), 17663 radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius, 17664 x, y; 17665 17666 for (var i = 0; i < slices.length; ++i) { 17667 17668 var s = slices[i]; 17669 17670 if (s.pie.show) { 17671 17672 ctx.save(); 17673 ctx.beginPath(); 17674 ctx.moveTo(0, 0); // Center of the pie 17675 //ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here. 17676 ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false); 17677 ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false); 17678 ctx.closePath(); 17679 x = mouseX - centerLeft; 17680 y = mouseY - centerTop; 17681 17682 if (ctx.isPointInPath) { 17683 if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) { 17684 ctx.restore(); 17685 return { 17686 datapoint: [s.percent, s.data], 17687 dataIndex: 0, 17688 series: s, 17689 seriesIndex: i 17690 }; 17691 } 17692 } else { 17693 17694 // excanvas for IE doesn;t support isPointInPath, this is a workaround. 17695 17696 var p1X = radius * Math.cos(s.startAngle), 17697 p1Y = radius * Math.sin(s.startAngle), 17698 p2X = radius * Math.cos(s.startAngle + s.angle / 4), 17699 p2Y = radius * Math.sin(s.startAngle + s.angle / 4), 17700 p3X = radius * Math.cos(s.startAngle + s.angle / 2), 17701 p3Y = radius * Math.sin(s.startAngle + s.angle / 2), 17702 p4X = radius * Math.cos(s.startAngle + s.angle / 1.5), 17703 p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5), 17704 p5X = radius * Math.cos(s.startAngle + s.angle), 17705 p5Y = radius * Math.sin(s.startAngle + s.angle), 17706 arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]], 17707 arrPoint = [x, y]; 17708 17709 // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt? 17710 17711 if (isPointInPoly(arrPoly, arrPoint)) { 17712 ctx.restore(); 17713 return { 17714 datapoint: [s.percent, s.data], 17715 dataIndex: 0, 17716 series: s, 17717 seriesIndex: i 17718 }; 17719 } 17720 } 17721 17722 ctx.restore(); 17723 } 17724 } 17725 17726 return null; 17727 } 17728 17729 function onMouseMove(e) { 17730 triggerClickHoverEvent("plothover", e); 17731 } 17732 17733 function onClick(e) { 17734 triggerClickHoverEvent("plotclick", e); 17735 } 17736 17737 // trigger click or hover event (they send the same parameters so we share their code) 17738 17739 function triggerClickHoverEvent(eventname, e) { 17740 17741 var offset = plot.offset(); 17742 var canvasX = parseInt(e.pageX - offset.left); 17743 var canvasY = parseInt(e.pageY - offset.top); 17744 var item = findNearbySlice(canvasX, canvasY); 17745 17746 if (options.grid.autoHighlight) { 17747 17748 // clear auto-highlights 17749 17750 for (var i = 0; i < highlights.length; ++i) { 17751 var h = highlights[i]; 17752 if (h.auto == eventname && !(item && h.series == item.series)) { 17753 unhighlight(h.series); 17754 } 17755 } 17756 } 17757 17758 // highlight the slice 17759 17760 if (item) { 17761 highlight(item.series, eventname); 17762 } 17763 17764 // trigger any hover bind events 17765 17766 var pos = { pageX: e.pageX, pageY: e.pageY }; 17767 target.trigger(eventname, [pos, item]); 17768 } 17769 17770 function highlight(s, auto) { 17771 //if (typeof s == "number") { 17772 // s = series[s]; 17773 //} 17774 17775 var i = indexOfHighlight(s); 17776 17777 if (i == -1) { 17778 highlights.push({ series: s, auto: auto }); 17779 plot.triggerRedrawOverlay(); 17780 } else if (!auto) { 17781 highlights[i].auto = false; 17782 } 17783 } 17784 17785 function unhighlight(s) { 17786 if (s == null) { 17787 highlights = []; 17788 plot.triggerRedrawOverlay(); 17789 } 17790 17791 //if (typeof s == "number") { 17792 // s = series[s]; 17793 //} 17794 17795 var i = indexOfHighlight(s); 17796 17797 if (i != -1) { 17798 highlights.splice(i, 1); 17799 plot.triggerRedrawOverlay(); 17800 } 17801 } 17802 17803 function indexOfHighlight(s) { 17804 for (var i = 0; i < highlights.length; ++i) { 17805 var h = highlights[i]; 17806 if (h.series == s) 17807 return i; 17808 } 17809 return -1; 17810 } 17811 17812 function drawOverlay(plot, octx) { 17813 17814 var options = plot.getOptions(); 17815 17816 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; 17817 17818 octx.save(); 17819 octx.translate(centerLeft, centerTop); 17820 octx.scale(1, options.series.pie.tilt); 17821 17822 for (var i = 0; i < highlights.length; ++i) { 17823 drawHighlight(highlights[i].series); 17824 } 17825 17826 drawDonutHole(octx); 17827 17828 octx.restore(); 17829 17830 function drawHighlight(series) { 17831 17832 if (series.angle <= 0 || isNaN(series.angle)) { 17833 return; 17834 } 17835 17836 //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString(); 17837 octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor 17838 octx.beginPath(); 17839 if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) { 17840 octx.moveTo(0, 0); // Center of the pie 17841 } 17842 octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false); 17843 octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false); 17844 octx.closePath(); 17845 octx.fill(); 17846 } 17847 } 17848 } // end init (plugin body) 17849 17850 // define pie specific options and their default values 17851 17852 var options = { 17853 series: { 17854 pie: { 17855 show: false, 17856 radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value) 17857 innerRadius: 0, /* for donut */ 17858 startAngle: 3/2, 17859 tilt: 1, 17860 shadow: { 17861 left: 5, // shadow left offset 17862 top: 15, // shadow top offset 17863 alpha: 0.02 // shadow alpha 17864 }, 17865 offset: { 17866 top: 0, 17867 left: "auto" 17868 }, 17869 stroke: { 17870 color: "#fff", 17871 width: 1 17872 }, 17873 label: { 17874 show: "auto", 17875 formatter: function(label, slice) { 17876 return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>"; 17877 }, // formatter function 17878 radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value) 17879 background: { 17880 color: null, 17881 opacity: 0 17882 }, 17883 threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow) 17884 }, 17885 combine: { 17886 threshold: -1, // percentage at which to combine little slices into one larger slice 17887 color: null, // color to give the new slice (auto-generated if null) 17888 label: "Other" // label to give the new slice 17889 }, 17890 highlight: { 17891 //color: "#fff", // will add this functionality once parseColor is available 17892 opacity: 0.5 17893 } 17894 } 17895 } 17896 }; 17897 17898 $.plot.plugins.push({ 17899 init: init, 17900 options: options, 17901 name: "pie", 17902 version: "1.1" 17903 }); 17904 17905})(jQuery);
17906 17907;
vendor: 11,768 bytes, lines 17907-18338
17907/* Pretty handling of time axes. 17908 17909Copyright (c) 2007-2014 IOLA and Ole Laursen. 17910Licensed under the MIT license. 17911 17912Set axis.mode to "time" to enable. See the section "Time series data" in 17913API.txt for details. 17914 17915*/ 17916 17917(function($) { 17918 17919 var options = { 17920 xaxis: { 17921 timezone: null, // "browser" for local to the client or timezone for timezone-js 17922 timeformat: null, // format string to use 17923 twelveHourClock: false, // 12 or 24 time in time mode 17924 monthNames: null // list of names of months 17925 } 17926 }; 17927 17928 // round to nearby lower multiple of base 17929 17930 function floorInBase(n, base) { 17931 return base * Math.floor(n / base); 17932 } 17933 17934 // Returns a string with the date d formatted according to fmt. 17935 // A subset of the Open Group's strftime format is supported. 17936 17937 function formatDate(d, fmt, monthNames, dayNames) { 17938 17939 if (typeof d.strftime == "function") { 17940 return d.strftime(fmt); 17941 } 17942 17943 var leftPad = function(n, pad) { 17944 n = "" + n; 17945 pad = "" + (pad == null ? "0" : pad); 17946 return n.length == 1 ? pad + n : n; 17947 }; 17948 17949 var r = []; 17950 var escape = false; 17951 var hours = d.getHours(); 17952 var isAM = hours < 12; 17953 17954 if (monthNames == null) { 17955 monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; 17956 } 17957 17958 if (dayNames == null) { 17959 dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 17960 } 17961 17962 var hours12; 17963 17964 if (hours > 12) { 17965 hours12 = hours - 12; 17966 } else if (hours == 0) { 17967 hours12 = 12; 17968 } else { 17969 hours12 = hours; 17970 } 17971 17972 for (var i = 0; i < fmt.length; ++i) { 17973 17974 var c = fmt.charAt(i); 17975 17976 if (escape) { 17977 switch (c) { 17978 case 'a': c = "" + dayNames[d.getDay()]; break; 17979 case 'b': c = "" + monthNames[d.getMonth()]; break; 17980 case 'd': c = leftPad(d.getDate()); break; 17981 case 'e': c = leftPad(d.getDate(), " "); break; 17982 case 'h': // For back-compat with 0.7; remove in 1.0 17983 case 'H': c = leftPad(hours); break; 17984 case 'I': c = leftPad(hours12); break; 17985 case 'l': c = leftPad(hours12, " "); break; 17986 case 'm': c = leftPad(d.getMonth() + 1); break; 17987 case 'M': c = leftPad(d.getMinutes()); break; 17988 // quarters not in Open Group's strftime specification 17989 case 'q': 17990 c = "" + (Math.floor(d.getMonth() / 3) + 1); break; 17991 case 'S': c = leftPad(d.getSeconds()); break; 17992 case 'y': c = leftPad(d.getFullYear() % 100); break; 17993 case 'Y': c = "" + d.getFullYear(); break; 17994 case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; 17995 case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; 17996 case 'w': c = "" + d.getDay(); break; 17997 } 17998 r.push(c); 17999 escape = false; 18000 } else { 18001 if (c == "%") { 18002 escape = true; 18003 } else { 18004 r.push(c); 18005 } 18006 } 18007 } 18008 18009 return r.join(""); 18010 } 18011 18012 // To have a consistent view of time-based data independent of which time 18013 // zone the client happens to be in we need a date-like object independent 18014 // of time zones. This is done through a wrapper that only calls the UTC 18015 // versions of the accessor methods. 18016 18017 function makeUtcWrapper(d) { 18018 18019 function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { 18020 sourceObj[sourceMethod] = function() { 18021 return targetObj[targetMethod].apply(targetObj, arguments); 18022 }; 18023 }; 18024 18025 var utc = { 18026 date: d 18027 }; 18028 18029 // support strftime, if found 18030 18031 if (d.strftime != undefined) { 18032 addProxyMethod(utc, "strftime", d, "strftime"); 18033 } 18034 18035 addProxyMethod(utc, "getTime", d, "getTime"); 18036 addProxyMethod(utc, "setTime", d, "setTime"); 18037 18038 var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"]; 18039 18040 for (var p = 0; p < props.length; p++) { 18041 addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]); 18042 addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); 18043 } 18044 18045 return utc; 18046 }; 18047 18048 // select time zone strategy. This returns a date-like object tied to the 18049 // desired timezone 18050 18051 function dateGenerator(ts, opts) { 18052 if (opts.timezone == "browser") { 18053 return new Date(ts); 18054 } else if (!opts.timezone || opts.timezone == "utc") { 18055 return makeUtcWrapper(new Date(ts)); 18056 } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { 18057 var d = new timezoneJS.Date(); 18058 // timezone-js is fickle, so be sure to set the time zone before 18059 // setting the time. 18060 d.setTimezone(opts.timezone); 18061 d.setTime(ts); 18062 return d; 18063 } else { 18064 return makeUtcWrapper(new Date(ts)); 18065 } 18066 } 18067 18068 // map of app. size of time units in milliseconds 18069 18070 var timeUnitSize = { 18071 "second": 1000, 18072 "minute": 60 * 1000, 18073 "hour": 60 * 60 * 1000, 18074 "day": 24 * 60 * 60 * 1000, 18075 "month": 30 * 24 * 60 * 60 * 1000, 18076 "quarter": 3 * 30 * 24 * 60 * 60 * 1000, 18077 "year": 365.2425 * 24 * 60 * 60 * 1000 18078 }; 18079 18080 // the allowed tick sizes, after 1 year we use 18081 // an integer algorithm 18082 18083 var baseSpec = [ 18084 [1, "second"], [2, "second"], [5, "second"], [10, "second"], 18085 [30, "second"], 18086 [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], 18087 [30, "minute"], 18088 [1, "hour"], [2, "hour"], [4, "hour"], 18089 [8, "hour"], [12, "hour"], 18090 [1, "day"], [2, "day"], [3, "day"], 18091 [0.25, "month"], [0.5, "month"], [1, "month"], 18092 [2, "month"] 18093 ]; 18094 18095 // we don't know which variant(s) we'll need yet, but generating both is 18096 // cheap 18097 18098 var specMonths = baseSpec.concat([[3, "month"], [6, "month"], 18099 [1, "year"]]); 18100 var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"], 18101 [1, "year"]]); 18102 18103 function init(plot) { 18104 plot.hooks.processOptions.push(function (plot, options) { 18105 $.each(plot.getAxes(), function(axisName, axis) { 18106 18107 var opts = axis.options; 18108 18109 if (opts.mode == "time") { 18110 axis.tickGenerator = function(axis) { 18111 18112 var ticks = []; 18113 var d = dateGenerator(axis.min, opts); 18114 var minSize = 0; 18115 18116 // make quarter use a possibility if quarters are 18117 // mentioned in either of these options 18118 18119 var spec = (opts.tickSize && opts.tickSize[1] === 18120 "quarter") || 18121 (opts.minTickSize && opts.minTickSize[1] === 18122 "quarter") ? specQuarters : specMonths; 18123 18124 if (opts.minTickSize != null) { 18125 if (typeof opts.tickSize == "number") { 18126 minSize = opts.tickSize; 18127 } else { 18128 minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; 18129 } 18130 } 18131 18132 for (var i = 0; i < spec.length - 1; ++i) { 18133 if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] 18134 + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 18135 && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) { 18136 break; 18137 } 18138 } 18139 18140 var size = spec[i][0]; 18141 var unit = spec[i][1]; 18142 18143 // special-case the possibility of several years 18144 18145 if (unit == "year") { 18146 18147 // if given a minTickSize in years, just use it, 18148 // ensuring that it's an integer 18149 18150 if (opts.minTickSize != null && opts.minTickSize[1] == "year") { 18151 size = Math.floor(opts.minTickSize[0]); 18152 } else { 18153 18154 var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); 18155 var norm = (axis.delta / timeUnitSize.year) / magn; 18156 18157 if (norm < 1.5) { 18158 size = 1; 18159 } else if (norm < 3) { 18160 size = 2; 18161 } else if (norm < 7.5) { 18162 size = 5; 18163 } else { 18164 size = 10; 18165 } 18166 18167 size *= magn; 18168 } 18169 18170 // minimum size for years is 1 18171 18172 if (size < 1) { 18173 size = 1; 18174 } 18175 } 18176 18177 axis.tickSize = opts.tickSize || [size, unit]; 18178 var tickSize = axis.tickSize[0]; 18179 unit = axis.tickSize[1]; 18180 18181 var step = tickSize * timeUnitSize[unit]; 18182 18183 if (unit == "second") { 18184 d.setSeconds(floorInBase(d.getSeconds(), tickSize)); 18185 } else if (unit == "minute") { 18186 d.setMinutes(floorInBase(d.getMinutes(), tickSize)); 18187 } else if (unit == "hour") { 18188 d.setHours(floorInBase(d.getHours(), tickSize)); 18189 } else if (unit == "month") { 18190 d.setMonth(floorInBase(d.getMonth(), tickSize)); 18191 } else if (unit == "quarter") { 18192 d.setMonth(3 * floorInBase(d.getMonth() / 3, 18193 tickSize)); 18194 } else if (unit == "year") { 18195 d.setFullYear(floorInBase(d.getFullYear(), tickSize)); 18196 } 18197 18198 // reset smaller components 18199 18200 d.setMilliseconds(0); 18201 18202 if (step >= timeUnitSize.minute) { 18203 d.setSeconds(0); 18204 } 18205 if (step >= timeUnitSize.hour) { 18206 d.setMinutes(0); 18207 } 18208 if (step >= timeUnitSize.day) { 18209 d.setHours(0); 18210 } 18211 if (step >= timeUnitSize.day * 4) { 18212 d.setDate(1); 18213 } 18214 if (step >= timeUnitSize.month * 2) { 18215 d.setMonth(floorInBase(d.getMonth(), 3)); 18216 } 18217 if (step >= timeUnitSize.quarter * 2) { 18218 d.setMonth(floorInBase(d.getMonth(), 6)); 18219 } 18220 if (step >= timeUnitSize.year) { 18221 d.setMonth(0); 18222 } 18223 18224 var carry = 0; 18225 var v = Number.NaN; 18226 var prev; 18227 18228 do { 18229 18230 prev = v; 18231 v = d.getTime(); 18232 ticks.push(v); 18233 18234 if (unit == "month" || unit == "quarter") { 18235 if (tickSize < 1) { 18236 18237 // a bit complicated - we'll divide the 18238 // month/quarter up but we need to take 18239 // care of fractions so we don't end up in 18240 // the middle of a day 18241 18242 d.setDate(1); 18243 var start = d.getTime(); 18244 d.setMonth(d.getMonth() + 18245 (unit == "quarter" ? 3 : 1)); 18246 var end = d.getTime(); 18247 d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); 18248 carry = d.getHours(); 18249 d.setHours(0); 18250 } else { 18251 d.setMonth(d.getMonth() + 18252 tickSize * (unit == "quarter" ? 3 : 1)); 18253 } 18254 } else if (unit == "year") { 18255 d.setFullYear(d.getFullYear() + tickSize); 18256 } else { 18257 d.setTime(v + step); 18258 } 18259 } while (v < axis.max && v != prev); 18260 18261 return ticks; 18262 }; 18263 18264 axis.tickFormatter = function (v, axis) { 18265 18266 var d = dateGenerator(v, axis.options); 18267 18268 // first check global format 18269 18270 if (opts.timeformat != null) { 18271 return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); 18272 } 18273 18274 // possibly use quarters if quarters are mentioned in 18275 // any of these places 18276 18277 var useQuarters = (axis.options.tickSize && 18278 axis.options.tickSize[1] == "quarter") || 18279 (axis.options.minTickSize && 18280 axis.options.minTickSize[1] == "quarter"); 18281 18282 var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; 18283 var span = axis.max - axis.min; 18284 var suffix = (opts.twelveHourClock) ? " %p" : ""; 18285 var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; 18286 var fmt; 18287 18288 if (t < timeUnitSize.minute) { 18289 fmt = hourCode + ":%M:%S" + suffix; 18290 } else if (t < timeUnitSize.day) { 18291 if (span < 2 * timeUnitSize.day) { 18292 fmt = hourCode + ":%M" + suffix; 18293 } else { 18294 fmt = "%b %d " + hourCode + ":%M" + suffix; 18295 } 18296 } else if (t < timeUnitSize.month) { 18297 fmt = "%b %d"; 18298 } else if ((useQuarters && t < timeUnitSize.quarter) || 18299 (!useQuarters && t < timeUnitSize.year)) { 18300 if (span < timeUnitSize.year) { 18301 fmt = "%b"; 18302 } else { 18303 fmt = "%b %Y"; 18304 } 18305 } else if (useQuarters && t < timeUnitSize.year) { 18306 if (span < timeUnitSize.year) { 18307 fmt = "Q%q"; 18308 } else { 18309 fmt = "Q%q %Y"; 18310 } 18311 } else { 18312 fmt = "%Y"; 18313 } 18314 18315 var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); 18316 18317 return rt; 18318 }; 18319 } 18320 }); 18321 }); 18322 } 18323 18324 $.plot.plugins.push({ 18325 init: init, 18326 options: options, 18327 name: 'time', 18328 version: '1.0' 18329 }); 18330 18331 // Time-axis support used to be in Flot core, which exposed the 18332 // formatDate function on the plot object. Various plugins depend 18333 // on the function, so we need to re-expose it here. 18334 18335 $.plot.formatDate = formatDate; 18336 $.plot.dateGenerator = dateGenerator; 18337 18338})(jQuery);
18339 18340;/* Flot plugin for plotting textual data or categories. 18341 18342Copyright (c) 2007-2014 IOLA and Ole Laursen. 18343Licensed under the MIT license. 18344 18345Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin 18346allows you to plot such a dataset directly. 18347 18348To enable it, you must specify mode: "categories" on the axis with the textual 18349labels, e.g. 18350 18351 $.plot("#placeholder", data, { xaxis: { mode: "categories" } }); 18352 18353By default, the labels are ordered as they are met in the data series. If you 18354need a different ordering, you can specify "categories" on the axis options 18355and list the categories there: 18356 18357 xaxis: { 18358 mode: "categories", 18359 categories: ["February", "March", "April"] 18360 } 18361 18362If you need to customize the distances between the categories, you can specify 18363"categories" as an object mapping labels to values 18364 18365 xaxis: { 18366 mode: "categories", 18367 categories: { "February": 1, "March": 3, "April": 4 } 18368 } 18369 18370If you don't specify all categories, the remaining categories will be numbered
18371from the max value plus 1 (with a spacing of 1 between each). 18372 18373Internally, the plugin works by transforming the input data through an auto- 18374generated mapping where the first category becomes 0, the second 1, etc. 18375Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this 18376is visible in hover and click events that return numbers rather than the 18377category labels). The plugin also overrides the tick generator to spit out the 18378categories as ticks instead of the values. 18379 18380If you need to map a value back to its label, the mapping is always accessible 18381as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories. 18382 18383*/ 18384 18385(function ($) { 18386 var options = { 18387 xaxis: { 18388 categories: null 18389 }, 18390 yaxis: { 18391 categories: null 18392 } 18393 }; 18394 18395 function processRawData(plot, series, data, datapoints) { 18396 // if categories are enabled, we need to disable 18397 // auto-transformation to numbers so the strings are intact 18398 // for later processing 18399 18400 var xCategories = series.xaxis.options.mode == "categories", 18401 yCategories = series.yaxis.options.mode == "categories"; 18402 18403 if (!(xCategories || yCategories)) 18404 return; 18405 18406 var format = datapoints.format; 18407 18408 if (!format) { 18409 // FIXME: auto-detection should really not be defined here 18410 var s = series; 18411 format = []; 18412 format.push({ x: true, number: true, required: true }); 18413 format.push({ y: true, number: true, required: true }); 18414 18415 if (s.bars.show || (s.lines.show && s.lines.fill)) { 18416 var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); 18417 format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); 18418 if (s.bars.horizontal) { 18419 delete format[format.length - 1].y; 18420 format[format.length - 1].x = true; 18421 } 18422 } 18423 18424 datapoints.format = format; 18425 } 18426 18427 for (var m = 0; m < format.length; ++m) { 18428 if (format[m].x && xCategories) 18429 format[m].number = false; 18430 18431 if (format[m].y && yCategories) 18432 format[m].number = false; 18433 } 18434 } 18435 18436 function getNextIndex(categories) { 18437 var index = -1; 18438 18439 for (var v in categories) 18440 if (categories[v] > index) 18441 index = categories[v]; 18442 18443 return index + 1; 18444 } 18445 18446 function categoriesTickGenerator(axis) { 18447 var res = []; 18448 for (var label in axis.categories) { 18449 var v = axis.categories[label]; 18450 if (v >= axis.min && v <= axis.max) 18451 res.push([v, label]); 18452 } 18453 18454 res.sort(function (a, b) { return a[0] - b[0]; }); 18455 18456 return res; 18457 } 18458 18459 function setupCategoriesForAxis(series, axis, datapoints) { 18460 if (series[axis].options.mode != "categories") 18461 return; 18462 18463 if (!series[axis].categories) { 18464 // parse options 18465 var c = {}, o = series[axis].options.categories || {}; 18466 if ($.isArray(o)) { 18467 for (var i = 0; i < o.length; ++i) 18468 c[o[i]] = i; 18469 } 18470 else { 18471 for (var v in o) 18472 c[v] = o[v]; 18473 } 18474 18475 series[axis].categories = c; 18476 } 18477 18478 // fix ticks 18479 if (!series[axis].options.ticks) 18480 series[axis].options.ticks = categoriesTickGenerator; 18481 18482 transformPointsOnAxis(datapoints, axis, series[axis].categories); 18483 } 18484 18485 function transformPointsOnAxis(datapoints, axis, categories) { 18486 // go through the points, transforming them 18487 var points = datapoints.points, 18488 ps = datapoints.pointsize, 18489 format = datapoints.format, 18490 formatColumn = axis.charAt(0), 18491 index = getNextIndex(categories); 18492 18493 for (var i = 0; i < points.length; i += ps) { 18494 if (points[i] == null) 18495 continue; 18496 18497 for (var m = 0; m < ps; ++m) { 18498 var val = points[i + m]; 18499 18500 if (val == null || !format[m][formatColumn]) 18501 continue; 18502 18503 if (!(val in categories)) { 18504 categories[val] = index; 18505 ++index; 18506 } 18507 18508 points[i + m] = categories[val]; 18509 } 18510 } 18511 } 18512 18513 function processDatapoints(plot, series, datapoints) { 18514 setupCategoriesForAxis(series, "xaxis", datapoints); 18515 setupCategoriesForAxis(series, "yaxis", datapoints); 18516 } 18517 18518 function init(plot) { 18519 plot.hooks.processRawData.push(processRawData); 18520 plot.hooks.processDatapoints.push(processDatapoints); 18521 } 18522 18523 $.plot.plugins.push({ 18524 init: init, 18525 options: options, 18526 name: 'categories', 18527 version: '1.0' 18528 }); 18529})(jQuery); 18530 18531; 18532;
vendor: 124,013 bytes, lines 18532-21599
18532/** 18533* 18534* jquery.sparkline.js 18535* 18536* v2.4.1 18537* (c) Splunk, Inc 18538* Contact: Gareth Watts ([email protected]) 18539* http://omnipotent.net/jquery.sparkline/ 18540* 18541* Generates inline sparkline charts from data supplied either to the method 18542* or inline in HTML 18543* 18544* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag 18545* (Firefox 2.0+, Safari, Opera, etc) 18546* 18547* License: New BSD License 18548* 18549* Copyright (c) 2012, Splunk Inc. 18550* All rights reserved. 18551* 18552* Redistribution and use in source and binary forms, with or without modification, 18553* are permitted provided that the following conditions are met: 18554* 18555* * Redistributions of source code must retain the above copyright notice, 18556* this list of conditions and the following disclaimer. 18557* * Redistributions in binary form must reproduce the above copyright notice, 18558* this list of conditions and the following disclaimer in the documentation 18559* and/or other materials provided with the distribution. 18560* * Neither the name of Splunk Inc nor the names of its contributors may 18561* be used to endorse or promote products derived from this software without 18562* specific prior written permission. 18563* 18564* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 18565* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18566* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 18567* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18568* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 18569* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 18570* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 18571* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 18572* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18573* 18574* 18575* Usage: 18576* $(selector).sparkline(values, options) 18577* 18578* If values is undefined or set to 'html' then the data values are read from the specified tag: 18579* <p>Sparkline: <span class="sparkline">1,4,6,6,8,5,3,5</span></p> 18580* $('.sparkline').sparkline(); 18581* There must be no spaces in the enclosed data set 18582* 18583* Otherwise values must be an array of numbers or null values 18584* <p>Sparkline: <span id="sparkline1">This text replaced if the browser is compatible</span></p> 18585* $('#sparkline1').sparkline([1,4,6,6,8,5,3,5]) 18586* $('#sparkline2').sparkline([1,4,6,null,null,5,3,5]) 18587* 18588* Values can also be specified in an HTML comment, or as a values attribute: 18589* <p>Sparkline: <span class="sparkline"><!--1,4,6,6,8,5,3,5 --></span></p> 18590* <p>Sparkline: <span class="sparkline" values="1,4,6,6,8,5,3,5"></span></p> 18591* $('.sparkline').sparkline(); 18592* 18593* For line charts, x values can also be specified: 18594* <p>Sparkline: <span class="sparkline">1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5</span></p> 18595* $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ]) 18596* 18597* By default, options should be passed in as the second argument to the sparkline function: 18598* $('.sparkline').sparkline([1,2,3,4], {type: 'bar'}) 18599* 18600* Options can also be set by passing them on the tag itself. This feature is disabled by default though 18601* as there's a slight performance overhead: 18602* $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true}) 18603* <p>Sparkline: <span class="sparkline" sparkType="bar" sparkBarColor="red">loading</span></p> 18604* Prefix all options supplied as tag attribute with "spark" (configurable by setting tagOptionsPrefix) 18605* 18606* Supported options: 18607* lineColor - Color of the line used for the chart 18608* fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart 18609* width - Width of the chart - Defaults to 3 times the number of values in pixels 18610* height - Height of the chart - Defaults to the height of the containing element 18611* chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied 18612* chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied 18613* chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax 18614* chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied 18615* chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied 18616* composite - If true then don't erase any existing chart attached to the tag, but draw 18617* another chart over the top - Note that width and height are ignored if an 18618* existing chart is detected. 18619* tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values' 18620* enableTagOptions - Whether to check tags for sparkline options 18621* tagOptionsPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark' 18622* disableHiddenCheck - If set to true, then the plugin will assume that charts will never be drawn into a 18623* hidden dom element, avoding a browser reflow 18624* disableInteraction - If set to true then all mouseover/click interaction behaviour will be disabled, 18625* making the plugin perform much like it did in 1.x 18626* disableTooltips - If set to true then tooltips will be disabled - Defaults to false (tooltips enabled) 18627* disableHighlight - If set to true then highlighting of selected chart elements on mouseover will be disabled 18628* defaults to false (highlights enabled) 18629* highlightLighten - Factor to lighten/darken highlighted chart values by - Defaults to 1.4 for a 40% increase 18630* tooltipContainer - Specify which DOM element the tooltip should be rendered into - defaults to document.body 18631* tooltipClassname - Optional CSS classname to apply to tooltips - If not specified then a default style will be applied 18632* tooltipOffsetX - How many pixels away from the mouse pointer to render the tooltip on the X axis 18633* tooltipOffsetY - How many pixels away from the mouse pointer to render the tooltip on the r axis 18634* tooltipFormatter - Optional callback that allows you to override the HTML displayed in the tooltip 18635* callback is given arguments of (sparkline, options, fields) 18636* tooltipChartTitle - If specified then the tooltip uses the string specified by this setting as a title 18637* tooltipFormat - A format string or SPFormat object (or an array thereof for multiple entries) 18638* to control the format of the tooltip 18639* tooltipPrefix - A string to prepend to each field displayed in a tooltip 18640* tooltipSuffix - A string to append to each field displayed in a tooltip 18641* tooltipSkipNull - If true then null values will not have a tooltip displayed (defaults to true) 18642* tooltipValueLookups - An object or range map to map field values to tooltip strings 18643* (eg. to map -1 to "Lost", 0 to "Draw", and 1 to "Win") 18644* numberFormatter - Optional callback for formatting numbers in tooltips 18645* numberDigitGroupSep - Character to use for group separator in numbers "1,234" - Defaults to "," 18646* numberDecimalMark - Character to use for the decimal point when formatting numbers - Defaults to "." 18647* numberDigitGroupCount - Number of digits between group separator - Defaults to 3 18648* 18649* There are 7 types of sparkline, selected by supplying a "type" option of 'line' (default), 18650* 'bar', 'tristate', 'bullet', 'discrete', 'pie' or 'box' 18651* line - Line chart. Options: 18652* spotColor - Set to '' to not end each line in a circular spot 18653* minSpotColor - If set, color of spot at minimum value 18654* maxSpotColor - If set, color of spot at maximum value 18655* spotRadius - Radius in pixels 18656* lineWidth - Width of line in pixels 18657* normalRangeMin 18658* normalRangeMax - If set draws a filled horizontal bar between these two values marking the "normal" 18659* or expected range of values 18660* normalRangeColor - Color to use for the above bar 18661* drawNormalOnTop - Draw the normal range above the chart fill color if true 18662* defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart 18663* highlightSpotColor - The color to use for drawing a highlight spot on mouseover - Set to null to disable 18664* highlightLineColor - The color to use for drawing a highlight line on mouseover - Set to null to disable 18665* valueSpots - Specify which points to draw spots on, and in which color. Accepts a range map 18666* 18667* bar - Bar chart. Options: 18668* barColor - Color of bars for postive values 18669* negBarColor - Color of bars for negative values 18670* zeroColor - Color of bars with zero values 18671* nullColor - Color of bars with null values - Defaults to omitting the bar entirely 18672* barWidth - Width of bars in pixels 18673* colorMap - Optional mappnig of values to colors to override the *BarColor values above 18674* can be an Array of values to control the color of individual bars or a range map 18675* to specify colors for individual ranges of values 18676* barSpacing - Gap between bars in pixels 18677* zeroAxis - Centers the y-axis around zero if true 18678* 18679* tristate - Charts values of win (>0), lose (<0) or draw (=0) 18680* posBarColor - Color of win values 18681* negBarColor - Color of lose values 18682* zeroBarColor - Color of draw values 18683* barWidth - Width of bars in pixels 18684* barSpacing - Gap between bars in pixels 18685* colorMap - Optional mappnig of values to colors to override the *BarColor values above 18686* can be an Array of values to control the color of individual bars or a range map 18687* to specify colors for individual ranges of values 18688* 18689* discrete - Options: 18690* lineHeight - Height of each line in pixels - Defaults to 30% of the graph height 18691* thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor 18692* thresholdColor 18693* 18694* bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ... 18695* options: 18696* targetColor - The color of the vertical target marker 18697* targetWidth - The width of the target marker in pixels 18698* performanceColor - The color of the performance measure horizontal bar 18699* rangeColors - Colors to use for each qualitative range background color 18700* 18701* pie - Pie chart. Options: 18702* sliceColors - An array of colors to use for pie slices 18703* offset - Angle in degrees to offset the first slice - Try -90 or +90 18704* borderWidth - Width of border to draw around the pie chart, in pixels - Defaults to 0 (no border) 18705* borderColor - Color to use for the pie chart border - Defaults to #000 18706* 18707* box - Box plot. Options: 18708* raw - Set to true to supply pre-computed plot points as values 18709* values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier 18710* When set to false you can supply any number of values and the box plot will 18711* be computed for you. Default is false. 18712* showOutliers - Set to true (default) to display outliers as circles 18713* outlierIQR - Interquartile range used to determine outliers. Default 1.5 18714* boxLineColor - Outline color of the box 18715* boxFillColor - Fill color for the box 18716* whiskerColor - Line color used for whiskers 18717* outlierLineColor - Outline color of outlier circles 18718* outlierFillColor - Fill color of the outlier circles 18719* spotRadius - Radius of outlier circles 18720* medianColor - Line color of the median line 18721* target - Draw a target cross hair at the supplied value (default undefined) 18722* 18723* 18724* 18725* Examples: 18726* $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false }); 18727* $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 }); 18728* $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }): 18729* $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' }); 18730* $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' }); 18731* $('#pie').sparkline([1,1,2], { type:'pie' }); 18732*/ 18733 18734/*jslint regexp: true, browser: true, jquery: true, white: true, nomen: false, plusplus: false, maxerr: 500, indent: 4 */ 18735 18736(function(document, Math, undefined) { // performance/minified-size optimization 18737(function(factory) { 18738 if(typeof define === 'function' && define.amd) { 18739 define(['jquery'], factory); 18740 } else if (jQuery && !jQuery.fn.sparkline) { 18741 factory(jQuery); 18742 } 18743} 18744(function($) { 18745 'use strict'; 18746 18747 var UNSET_OPTION = {}, 18748 getDefaults, createClass, SPFormat, clipval, quartile, normalizeValue, normalizeValues, 18749 remove, isNumber, all, sum, addCSS, ensureArray, formatNumber, RangeMap, 18750 MouseHandler, Tooltip, barHighlightMixin, 18751 line, bar, tristate, discrete, bullet, pie, box, defaultStyles, initStyles, 18752 VShape, VCanvas_base, VCanvas_canvas, VCanvas_vml, pending, shapeCount = 0; 18753 18754 /** 18755 * Default configuration settings 18756 */ 18757 getDefaults = function () { 18758 return { 18759 // Settings common to most/all chart types 18760 common: { 18761 type: 'line', 18762 lineColor: '#00f', 18763 fillColor: '#cdf', 18764 defaultPixelsPerValue: 3, 18765 width: 'auto', 18766 height: 'auto', 18767 composite: false, 18768 tagValuesAttribute: 'values', 18769 tagOptionsPrefix: 'spark', 18770 enableTagOptions: false, 18771 enableHighlight: true, 18772 highlightLighten: 1.4, 18773 tooltipSkipNull: true, 18774 tooltipPrefix: '', 18775 tooltipSuffix: '', 18776 disableHiddenCheck: false, 18777 numberFormatter: false, 18778 numberDigitGroupCount: 3, 18779 numberDigitGroupSep: ',', 18780 numberDecimalMark: '.', 18781 disableTooltips: false, 18782 disableInteraction: false 18783 }, 18784 // Defaults for line charts 18785 line: { 18786 spotColor: '#f80', 18787 highlightSpotColor: '#5f5', 18788 highlightLineColor: '#f22', 18789 spotRadius: 1.5, 18790 minSpotColor: '#f80', 18791 maxSpotColor: '#f80', 18792 lineWidth: 1, 18793 normalRangeMin: undefined, 18794 normalRangeMax: undefined, 18795 normalRangeColor: '#ccc', 18796 drawNormalOnTop: false, 18797 chartRangeMin: undefined, 18798 chartRangeMax: undefined, 18799 chartRangeMinX: undefined, 18800 chartRangeMaxX: undefined, 18801 tooltipFormat: new SPFormat('<span style="color: {{color}}">●</span> {{prefix}}{{y}}{{suffix}}') 18802 }, 18803 // Defaults for bar charts 18804 bar: { 18805 barColor: '#3366cc', 18806 negBarColor: '#f44', 18807 stackedBarColor: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', 18808 '#dd4477', '#0099c6', '#990099'], 18809 zeroColor: undefined, 18810 nullColor: undefined, 18811 zeroAxis: true, 18812 barWidth: 4, 18813 barSpacing: 1, 18814 chartRangeMax: undefined, 18815 chartRangeMin: undefined, 18816 chartRangeClip: false, 18817 colorMap: undefined, 18818 tooltipFormat: new SPFormat('<span style="color: {{color}}">●</span> {{prefix}}{{value}}{{suffix}}') 18819 }, 18820 // Defaults for tristate charts 18821 tristate: { 18822 barWidth: 4, 18823 barSpacing: 1, 18824 posBarColor: '#6f6', 18825 negBarColor: '#f44', 18826 zeroBarColor: '#999', 18827 colorMap: {}, 18828 tooltipFormat: new SPFormat('<span style="color: {{color}}">●</span> {{value:map}}'), 18829 tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } } 18830 }, 18831 // Defaults for discrete charts 18832 discrete: { 18833 lineHeight: 'auto', 18834 thresholdColor: undefined, 18835 thresholdValue: 0, 18836 chartRangeMax: undefined, 18837 chartRangeMin: undefined, 18838 chartRangeClip: false, 18839 tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}') 18840 }, 18841 // Defaults for bullet charts 18842 bullet: { 18843 targetColor: '#f33', 18844 targetWidth: 3, // width of the target bar in pixels 18845 performanceColor: '#33f', 18846 rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff'], 18847 base: undefined, // set this to a number to change the base start number 18848 tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'), 18849 tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} } 18850 }, 18851 // Defaults for pie charts 18852 pie: { 18853 offset: 0, 18854 sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', 18855 '#dd4477', '#0099c6', '#990099'], 18856 borderWidth: 0, 18857 borderColor: '#000', 18858 tooltipFormat: new SPFormat('<span style="color: {{color}}">●</span> {{value}} ({{percent.1}}%)') 18859 }, 18860 // Defaults for box plots 18861 box: { 18862 raw: false, 18863 boxLineColor: '#000', 18864 boxFillColor: '#cdf', 18865 whiskerColor: '#000', 18866 outlierLineColor: '#333', 18867 outlierFillColor: '#fff', 18868 medianColor: '#f00', 18869 showOutliers: true, 18870 outlierIQR: 1.5, 18871 spotRadius: 1.5, 18872 target: undefined, 18873 targetColor: '#4a2', 18874 chartRangeMax: undefined, 18875 chartRangeMin: undefined, 18876 tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'), 18877 tooltipFormatFieldlistKey: 'field', 18878 tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median', 18879 uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier', 18880 lw: 'Left Whisker', rw: 'Right Whisker'} } 18881 } 18882 }; 18883 }; 18884 18885 // You can have tooltips use a css class other than jqstooltip by specifying tooltipClassname 18886 defaultStyles = '.jqstooltip { ' + 18887 'position: absolute;' + 18888 'left: 0px;' + 18889 'top: 0px;' + 18890 'visibility: hidden;' + 18891 'background: rgb(0, 0, 0) transparent;' + 18892 'background-color: rgba(0,0,0,0.6);' + 18893 'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);' + 18894 '-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";' + 18895 'color: white;' + 18896 'font: 10px arial, san serif;' + 18897 'text-align: left;' + 18898 'white-space: nowrap;' + 18899 'padding: 5px;' + 18900 'border: 1px solid white;' + 18901 'box-sizing: content-box;' + 18902 'z-index: 10000;' + 18903 '}' + 18904 '.jqsfield { ' + 18905 'color: white;' + 18906 'font: 10px arial, san serif;' + 18907 'text-align: left;' + 18908 '}'; 18909 18910 /** 18911 * Utilities 18912 */ 18913 18914 createClass = function (/* [baseclass, [mixin, ...]], definition */) { 18915 var Class, args; 18916 Class = function () { 18917 this.init.apply(this, arguments); 18918 }; 18919 if (arguments.length > 1) { 18920 if (arguments[0]) { 18921 Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]); 18922 Class._super = arguments[0].prototype; 18923 } else { 18924 Class.prototype = arguments[arguments.length - 1]; 18925 } 18926 if (arguments.length > 2) { 18927 args = Array.prototype.slice.call(arguments, 1, -1); 18928 args.unshift(Class.prototype); 18929 $.extend.apply($, args); 18930 } 18931 } else { 18932 Class.prototype = arguments[0]; 18933 } 18934 Class.prototype.cls = Class; 18935 return Class; 18936 }; 18937 18938 /** 18939 * Wraps a format string for tooltips 18940 * {{x}} 18941 * {{x.2} 18942 * {{x:months}} 18943 */ 18944 $.SPFormatClass = SPFormat = createClass({ 18945 fre: /\{\{([\w.]+?)(:(.+?))?\}\}/g, 18946 precre: /(\w+)\.(\d+)/, 18947 18948 init: function (format, fclass) { 18949 this.format = format; 18950 this.fclass = fclass; 18951 }, 18952 18953 render: function (fieldset, lookups, options) { 18954 var self = this, 18955 fields = fieldset, 18956 match, token, lookupkey, fieldvalue, prec; 18957 return this.format.replace(this.fre, function () { 18958 var lookup; 18959 token = arguments[1]; 18960 lookupkey = arguments[3]; 18961 match = self.precre.exec(token); 18962 if (match) { 18963 prec = match[2]; 18964 token = match[1]; 18965 } else { 18966 prec = false; 18967 } 18968 fieldvalue = fields[token]; 18969 if (fieldvalue === undefined) { 18970 return ''; 18971 } 18972 if (lookupkey && lookups && lookups[lookupkey]) { 18973 lookup = lookups[lookupkey]; 18974 if (lookup.get) { // RangeMap 18975 return lookups[lookupkey].get(fieldvalue) || fieldvalue; 18976 } else { 18977 return lookups[lookupkey][fieldvalue] || fieldvalue; 18978 } 18979 } 18980 if (isNumber(fieldvalue)) { 18981 if (options.get('numberFormatter')) { 18982 fieldvalue = options.get('numberFormatter')(fieldvalue); 18983 } else { 18984 fieldvalue = formatNumber(fieldvalue, prec, 18985 options.get('numberDigitGroupCount'), 18986 options.get('numberDigitGroupSep'), 18987 options.get('numberDecimalMark')); 18988 } 18989 } 18990 return fieldvalue; 18991 }); 18992 } 18993 }); 18994 18995 // convience method to avoid needing the new operator 18996 $.spformat = function(format, fclass) { 18997 return new SPFormat(format, fclass); 18998 }; 18999 19000 clipval = function (val, min, max) { 19001 if (val < min) { 19002 return min; 19003 } 19004 if (val > max) { 19005 return max; 19006 } 19007 return val; 19008 }; 19009 19010 quartile = function (values, q) { 19011 var vl; 19012 if (q === 2) { 19013 vl = Math.floor(values.length / 2); 19014 return values.length % 2 ? values[vl] : (values[vl-1] + values[vl]) / 2; 19015 } else { 19016 if (values.length % 2 ) { // odd 19017 vl = (values.length * q + q) / 4; 19018 return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1]; 19019 } else { //even 19020 vl = (values.length * q + 2) / 4; 19021 return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1]; 19022 19023 } 19024 } 19025 }; 19026 19027 normalizeValue = function (val) { 19028 var nf; 19029 switch (val) { 19030 case 'undefined': 19031 val = undefined; 19032 break; 19033 case 'null': 19034 val = null; 19035 break; 19036 case 'true': 19037 val = true; 19038 break; 19039 case 'false': 19040 val = false; 19041 break; 19042 default: 19043 nf = parseFloat(val); 19044 if (val == nf) { 19045 val = nf; 19046 } 19047 } 19048 return val; 19049 }; 19050 19051 normalizeValues = function (vals) { 19052 var i, result = []; 19053 for (i = vals.length; i--;) { 19054 result[i] = normalizeValue(vals[i]); 19055 } 19056 return result; 19057 }; 19058 19059 remove = function (vals, filter) { 19060 var i, vl, result = []; 19061 for (i = 0, vl = vals.length; i < vl; i++) { 19062 if (vals[i] !== filter) { 19063 result.push(vals[i]); 19064 } 19065 } 19066 return result; 19067 }; 19068 19069 isNumber = function (num) { 19070 return !isNaN(parseFloat(num)) && isFinite(num); 19071 }; 19072 19073 formatNumber = function (num, prec, groupsize, groupsep, decsep) { 19074 var p, i; 19075 num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split(''); 19076 p = (p = $.inArray('.', num)) < 0 ? num.length : p; 19077 if (p < num.length) { 19078 num[p] = decsep; 19079 } 19080 for (i = p - groupsize; i > 0; i -= groupsize) { 19081 num.splice(i, 0, groupsep); 19082 } 19083 return num.join(''); 19084 }; 19085 19086 // determine if all values of an array match a value 19087 // returns true if the array is empty 19088 all = function (val, arr, ignoreNull) { 19089 var i; 19090 for (i = arr.length; i--; ) { 19091 if (ignoreNull && arr[i] === null) continue; 19092 if (arr[i] !== val) { 19093 return false; 19094 } 19095 } 19096 return true; 19097 }; 19098 19099 // sums the numeric values in an array, ignoring other values 19100 sum = function (vals) { 19101 var total = 0, i; 19102 for (i = vals.length; i--;) { 19103 total += typeof vals[i] === 'number' ? vals[i] : 0; 19104 } 19105 return total; 19106 }; 19107 19108 ensureArray = function (val) { 19109 return $.isArray(val) ? val : [val]; 19110 }; 19111 19112 // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/ 19113 addCSS = function(css) { 19114 var tag, iefail; 19115 if (document.createStyleSheet) { 19116 try { 19117 document.createStyleSheet().cssText = css; 19118 return; 19119 } catch (e) { 19120 // IE <= 9 maxes out at 31 stylesheets; inject into page instead. 19121 iefail = true; 19122 } 19123 } 19124 tag = document.createElement('style'); 19125 tag.type = 'text/css'; 19126 document.getElementsByTagName('head')[0].appendChild(tag); 19127 if (iefail) { 19128 document.styleSheets[document.styleSheets.length - 1].cssText = css; 19129 } else { 19130 tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css; 19131 } 19132 }; 19133 19134 // Provide a cross-browser interface to a few simple drawing primitives 19135 $.fn.simpledraw = function (width, height, useExisting, interact) { 19136 var target, mhandler; 19137 if (useExisting && (target = this.data('_jqs_vcanvas'))) { 19138 return target; 19139 } 19140 19141 if ($.fn.sparkline.canvas === false) { 19142 // We've already determined that neither Canvas nor VML are available 19143 return false; 19144 19145 } else if ($.fn.sparkline.canvas === undefined) { 19146 // No function defined yet -- need to see if we support Canvas or VML 19147 var el = document.createElement('canvas'); 19148 if (!!(el.getContext && el.getContext('2d'))) { 19149 // Canvas is available 19150 $.fn.sparkline.canvas = function(width, height, target, interact) { 19151 return new VCanvas_canvas(width, height, target, interact); 19152 }; 19153 } else if (document.namespaces && !document.namespaces.v) { 19154 // VML is available 19155 document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML'); 19156 $.fn.sparkline.canvas = function(width, height, target, interact) { 19157 return new VCanvas_vml(width, height, target); 19158 }; 19159 } else { 19160 // Neither Canvas nor VML are available 19161 $.fn.sparkline.canvas = false; 19162 return false; 19163 } 19164 } 19165 19166 if (width === undefined) { 19167 width = $(this).innerWidth(); 19168 } 19169 if (height === undefined) { 19170 height = $(this).innerHeight(); 19171 } 19172 19173 target = $.fn.sparkline.canvas(width, height, this, interact); 19174 19175 mhandler = $(this).data('_jqs_mhandler'); 19176 if (mhandler) { 19177 mhandler.registerCanvas(target); 19178 } 19179 return target; 19180 }; 19181 19182 $.fn.cleardraw = function () { 19183 var target = this.data('_jqs_vcanvas'); 19184 if (target) { 19185 target.reset(); 19186 } 19187 }; 19188 19189 $.RangeMapClass = RangeMap = createClass({ 19190 init: function (map) { 19191 var key, range, rangelist = []; 19192 for (key in map) { 19193 if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) { 19194 range = key.split(':'); 19195 range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]); 19196 range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]); 19197 range[2] = map[key]; 19198 rangelist.push(range); 19199 } 19200 } 19201 this.map = map; 19202 this.rangelist = rangelist || false; 19203 }, 19204 19205 get: function (value) { 19206 var rangelist = this.rangelist, 19207 i, range, result; 19208 if ((result = this.map[value]) !== undefined) { 19209 return result; 19210 } 19211 if (rangelist) { 19212 for (i = rangelist.length; i--;) { 19213 range = rangelist[i]; 19214 if (range[0] <= value && range[1] >= value) { 19215 return range[2]; 19216 } 19217 } 19218 } 19219 return undefined; 19220 } 19221 }); 19222 19223 // Convenience function 19224 $.range_map = function(map) { 19225 return new RangeMap(map); 19226 }; 19227 19228 MouseHandler = createClass({ 19229 init: function (el, options) { 19230 var $el = $(el); 19231 this.$el = $el; 19232 this.options = options; 19233 this.currentPageX = 0; 19234 this.currentPageY = 0; 19235 this.el = el; 19236 this.splist = []; 19237 this.tooltip = null; 19238 this.over = false; 19239 this.displayTooltips = !options.get('disableTooltips'); 19240 this.highlightEnabled = !options.get('disableHighlight'); 19241 }, 19242 19243 registerSparkline: function (sp) { 19244 this.splist.push(sp); 19245 if (this.over) { 19246 this.updateDisplay(); 19247 } 19248 }, 19249 19250 registerCanvas: function (canvas) { 19251 var $canvas = $(canvas.canvas); 19252 this.canvas = canvas; 19253 this.$canvas = $canvas; 19254 $canvas.mouseenter($.proxy(this.mouseenter, this)); 19255 $canvas.mouseleave($.proxy(this.mouseleave, this)); 19256 $canvas.click($.proxy(this.mouseclick, this)); 19257 }, 19258 19259 reset: function (removeTooltip) { 19260 this.splist = []; 19261 if (this.tooltip && removeTooltip) { 19262 this.tooltip.remove(); 19263 this.tooltip = undefined; 19264 } 19265 }, 19266 19267 mouseclick: function (e) { 19268 var clickEvent = $.Event('sparklineClick'); 19269 clickEvent.originalEvent = e; 19270 clickEvent.sparklines = this.splist; 19271 this.$el.trigger(clickEvent); 19272 }, 19273 19274 mouseenter: function (e) { 19275 $(document.body).unbind('mousemove.jqs'); 19276 $(document.body).bind('mousemove.jqs', $.proxy(this.mousemove, this)); 19277 this.over = true; 19278 this.currentPageX = e.pageX; 19279 this.currentPageY = e.pageY; 19280 this.currentEl = e.target; 19281 if (!this.tooltip && this.displayTooltips) { 19282 this.tooltip = new Tooltip(this.options); 19283 this.tooltip.updatePosition(e.pageX, e.pageY); 19284 } 19285 this.updateDisplay(); 19286 }, 19287 19288 mouseleave: function () { 19289 $(document.body).unbind('mousemove.jqs'); 19290 var splist = this.splist, 19291 spcount = splist.length, 19292 needsRefresh = false, 19293 sp, i; 19294 this.over = false; 19295 this.currentEl = null; 19296 19297 if (this.tooltip) { 19298 this.tooltip.remove(); 19299 this.tooltip = null; 19300 } 19301 19302 for (i = 0; i < spcount; i++) { 19303 sp = splist[i]; 19304 if (sp.clearRegionHighlight()) { 19305 needsRefresh = true; 19306 } 19307 } 19308 19309 if (needsRefresh) { 19310 this.canvas.render(); 19311 } 19312 }, 19313 19314 mousemove: function (e) { 19315 this.currentPageX = e.pageX; 19316 this.currentPageY = e.pageY; 19317 this.currentEl = e.target; 19318 if (this.tooltip) { 19319 this.tooltip.updatePosition(e.pageX, e.pageY); 19320 } 19321 this.updateDisplay(); 19322 }, 19323 19324 updateDisplay: function () { 19325 var splist = this.splist, 19326 spcount = splist.length, 19327 needsRefresh = false, 19328 offset = this.$canvas.offset(), 19329 localX = this.currentPageX - offset.left, 19330 localY = this.currentPageY - offset.top, 19331 tooltiphtml, sp, i, result, changeEvent; 19332 if (!this.over) { 19333 return; 19334 } 19335 for (i = 0; i < spcount; i++) { 19336 sp = splist[i]; 19337 result = sp.setRegionHighlight(this.currentEl, localX, localY); 19338 if (result) { 19339 needsRefresh = true; 19340 } 19341 } 19342 if (needsRefresh) { 19343 changeEvent = $.Event('sparklineRegionChange'); 19344 changeEvent.sparklines = this.splist; 19345 this.$el.trigger(changeEvent); 19346 if (this.tooltip) { 19347 tooltiphtml = ''; 19348 for (i = 0; i < spcount; i++) { 19349 sp = splist[i]; 19350 tooltiphtml += sp.getCurrentRegionTooltip(); 19351 } 19352 this.tooltip.setContent(tooltiphtml); 19353 } 19354 if (!this.disableHighlight) { 19355 this.canvas.render(); 19356 } 19357 } 19358 if (result === null) { 19359 this.mouseleave(); 19360 } 19361 } 19362 }); 19363 19364 19365 Tooltip = createClass({ 19366 sizeStyle: 'position: static !important;' + 19367 'display: block !important;' + 19368 'visibility: hidden !important;' + 19369 'float: left !important;', 19370 19371 init: function (options) { 19372 var tooltipClassname = options.get('tooltipClassname', 'jqstooltip'), 19373 sizetipStyle = this.sizeStyle, 19374 offset; 19375 this.container = options.get('tooltipContainer') || document.body; 19376 this.tooltipOffsetX = options.get('tooltipOffsetX', 10); 19377 this.tooltipOffsetY = options.get('tooltipOffsetY', 12); 19378 // remove any previous lingering tooltip 19379 $('#jqssizetip').remove(); 19380 $('#jqstooltip').remove(); 19381 this.sizetip = $('<div/>', { 19382 id: 'jqssizetip', 19383 style: sizetipStyle, 19384 'class': tooltipClassname 19385 }); 19386 this.tooltip = $('<div/>', { 19387 id: 'jqstooltip', 19388 'class': tooltipClassname 19389 }).appendTo(this.container); 19390 // account for the container's location 19391 offset = this.tooltip.offset(); 19392 this.offsetLeft = offset.left; 19393 this.offsetTop = offset.top; 19394 this.hidden = true; 19395 $(window).unbind('resize.jqs scroll.jqs'); 19396 $(window).bind('resize.jqs scroll.jqs', $.proxy(this.updateWindowDims, this)); 19397 this.updateWindowDims(); 19398 }, 19399 19400 updateWindowDims: function () { 19401 this.scrollTop = $(window).scrollTop(); 19402 this.scrollLeft = $(window).scrollLeft(); 19403 this.scrollRight = this.scrollLeft + $(window).width(); 19404 this.updatePosition(); 19405 }, 19406 19407 getSize: function (content) { 19408 this.sizetip.html(content).appendTo(this.container); 19409 this.width = this.sizetip.width() + 1; 19410 this.height = this.sizetip.height(); 19411 this.sizetip.remove(); 19412 }, 19413 19414 setContent: function (content) { 19415 if (!content) { 19416 this.tooltip.css('visibility', 'hidden'); 19417 this.hidden = true; 19418 return; 19419 } 19420 this.getSize(content); 19421 this.tooltip.html(content) 19422 .css({ 19423 'width': this.width, 19424 'height': this.height, 19425 'visibility': 'visible' 19426 }); 19427 if (this.hidden) { 19428 this.hidden = false; 19429 this.updatePosition(); 19430 } 19431 }, 19432 19433 updatePosition: function (x, y) { 19434 if (x === undefined) { 19435 if (this.mousex === undefined) { 19436 return; 19437 } 19438 x = this.mousex - this.offsetLeft; 19439 y = this.mousey - this.offsetTop; 19440 19441 } else { 19442 this.mousex = x = x - this.offsetLeft; 19443 this.mousey = y = y - this.offsetTop; 19444 } 19445 if (!this.height || !this.width || this.hidden) { 19446 return; 19447 } 19448 19449 y -= this.height + this.tooltipOffsetY; 19450 x += this.tooltipOffsetX; 19451 19452 if (y < this.scrollTop) { 19453 y = this.scrollTop; 19454 } 19455 if (x < this.scrollLeft) { 19456 x = this.scrollLeft; 19457 } else if (x + this.width > this.scrollRight) { 19458 x = this.scrollRight - this.width; 19459 } 19460 19461 this.tooltip.css({ 19462 'left': x, 19463 'top': y 19464 }); 19465 }, 19466 19467 remove: function () { 19468 this.tooltip.remove(); 19469 this.sizetip.remove(); 19470 this.sizetip = this.tooltip = undefined; 19471 $(window).unbind('resize.jqs scroll.jqs'); 19472 } 19473 }); 19474 19475 initStyles = function() { 19476 addCSS(defaultStyles); 19477 }; 19478 19479 $(initStyles); 19480 19481 pending = []; 19482 $.fn.sparkline = function (userValues, userOptions) { 19483 return this.each(function () { 19484 var options = new $.fn.sparkline.options(this, userOptions), 19485 $this = $(this), 19486 render, i; 19487 render = function () { 19488 var values, width, height, tmp, mhandler, sp, vals; 19489 if (userValues === 'html' || userValues === undefined) { 19490 vals = this.getAttribute(options.get('tagValuesAttribute')); 19491 if (vals === undefined || vals === null) { 19492 vals = $this.html(); 19493 } 19494 values = vals.replace(/(^\s*<!--)|(-->\s*$)|\s+/g, '').split(','); 19495 } else { 19496 values = userValues; 19497 } 19498 19499 width = options.get('width') === 'auto' ? values.length * options.get('defaultPixelsPerValue') : options.get('width'); 19500 if (options.get('height') === 'auto') { 19501 if (!options.get('composite') || !$.data(this, '_jqs_vcanvas')) { 19502 // must be a better way to get the line height 19503 tmp = document.createElement('span'); 19504 tmp.innerHTML = 'a'; 19505 $this.html(tmp); 19506 height = $(tmp).innerHeight() || $(tmp).height(); 19507 $(tmp).remove(); 19508 tmp = null; 19509 } 19510 } else { 19511 height = options.get('height'); 19512 } 19513 19514 if (!options.get('disableInteraction')) { 19515 mhandler = $.data(this, '_jqs_mhandler'); 19516 if (!mhandler) { 19517 mhandler = new MouseHandler(this, options); 19518 $.data(this, '_jqs_mhandler', mhandler); 19519 } else if (!options.get('composite')) { 19520 mhandler.reset(); 19521 } 19522 } else { 19523 mhandler = false; 19524 } 19525 19526 if (options.get('composite') && !$.data(this, '_jqs_vcanvas')) { 19527 if (!$.data(this, '_jqs_errnotify')) { 19528 alert('Attempted to attach a composite sparkline to an element with no existing sparkline'); 19529 $.data(this, '_jqs_errnotify', true); 19530 } 19531 return; 19532 } 19533 19534 sp = new $.fn.sparkline[options.get('type')](this, values, options, width, height); 19535 19536 sp.render(); 19537 19538 if (mhandler) { 19539 mhandler.registerSparkline(sp); 19540 } 19541 }; 19542 if (($(this).html() && !options.get('disableHiddenCheck') && $(this).is(':hidden')) || !$(this).parents('body').length) { 19543 if (!options.get('composite') && $.data(this, '_jqs_pending')) { 19544 // remove any existing references to the element 19545 for (i = pending.length; i; i--) { 19546 if (pending[i - 1][0] == this) { 19547 pending.splice(i - 1, 1); 19548 } 19549 } 19550 } 19551 pending.push([this, render]); 19552 $.data(this, '_jqs_pending', true); 19553 } else { 19554 render.call(this); 19555 } 19556 }); 19557 }; 19558 19559 $.fn.sparkline.defaults = getDefaults(); 19560 19561 19562 $.sparkline_display_visible = function () { 19563 var el, i, pl; 19564 var done = []; 19565 for (i = 0, pl = pending.length; i < pl; i++) { 19566 el = pending[i][0]; 19567 if ($(el).is(':visible') && !$(el).parents().is(':hidden')) { 19568 pending[i][1].call(el); 19569 $.data(pending[i][0], '_jqs_pending', false); 19570 done.push(i); 19571 } else if (!$(el).closest('html').length && !$.data(el, '_jqs_pending')) { 19572 // element has been inserted and removed from the DOM 19573 // If it was not yet inserted into the dom then the .data request 19574 // will return true. 19575 // removing from the dom causes the data to be removed. 19576 $.data(pending[i][0], '_jqs_pending', false); 19577 done.push(i); 19578 } 19579 } 19580 for (i = done.length; i; i--) { 19581 pending.splice(done[i - 1], 1); 19582 } 19583 }; 19584 19585 19586 /** 19587 * User option handler 19588 */ 19589 $.fn.sparkline.options = createClass({ 19590 init: function (tag, userOptions) { 19591 var extendedOptions, defaults, base, tagOptionType; 19592 this.userOptions = userOptions = userOptions || {}; 19593 this.tag = tag; 19594 this.tagValCache = {}; 19595 defaults = $.fn.sparkline.defaults; 19596 base = defaults.common; 19597 this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix); 19598 19599 tagOptionType = this.getTagSetting('type'); 19600 if (tagOptionType === UNSET_OPTION) { 19601 extendedOptions = defaults[userOptions.type || base.type]; 19602 } else { 19603 extendedOptions = defaults[tagOptionType]; 19604 } 19605 this.mergedOptions = $.extend({}, base, extendedOptions, userOptions); 19606 }, 19607 19608 19609 getTagSetting: function (key) { 19610 var prefix = this.tagOptionsPrefix, 19611 val, i, pairs, keyval; 19612 if (prefix === false || prefix === undefined) { 19613 return UNSET_OPTION; 19614 } 19615 if (this.tagValCache.hasOwnProperty(key)) { 19616 val = this.tagValCache.key; 19617 } else { 19618 val = this.tag.getAttribute(prefix + key); 19619 if (val === undefined || val === null) { 19620 val = UNSET_OPTION; 19621 } else if (val.substr(0, 1) === '[') { 19622 val = val.substr(1, val.length - 2).split(','); 19623 for (i = val.length; i--;) { 19624 val[i] = normalizeValue(val[i].replace(/(^\s*)|(\s*$)/g, '')); 19625 } 19626 } else if (val.substr(0, 1) === '{') { 19627 pairs = val.substr(1, val.length - 2).split(','); 19628 val = {}; 19629 for (i = pairs.length; i--;) { 19630 keyval = pairs[i].split(':', 2); 19631 val[keyval[0].replace(/(^\s*)|(\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\s*)|(\s*$)/g, '')); 19632 } 19633 } else { 19634 val = normalizeValue(val); 19635 } 19636 this.tagValCache.key = val; 19637 } 19638 return val; 19639 }, 19640 19641 get: function (key, defaultval) { 19642 var tagOption = this.getTagSetting(key), 19643 result; 19644 if (tagOption !== UNSET_OPTION) { 19645 return tagOption; 19646 } 19647 return (result = this.mergedOptions[key]) === undefined ? defaultval : result; 19648 } 19649 }); 19650 19651 19652 $.fn.sparkline._base = createClass({ 19653 disabled: false, 19654 19655 init: function (el, values, options, width, height) { 19656 this.el = el; 19657 this.$el = $(el); 19658 this.values = values; 19659 this.options = options; 19660 this.width = width; 19661 this.height = height; 19662 this.currentRegion = undefined; 19663 }, 19664 19665 /** 19666 * Setup the canvas 19667 */ 19668 initTarget: function () { 19669 var interactive = !this.options.get('disableInteraction'); 19670 if (!(this.target = this.$el.simpledraw(this.width, this.height, this.options.get('composite'), interactive))) { 19671 this.disabled = true; 19672 } else { 19673 this.canvasWidth = this.target.pixelWidth; 19674 this.canvasHeight = this.target.pixelHeight; 19675 } 19676 }, 19677 19678 /** 19679 * Actually render the chart to the canvas 19680 */ 19681 render: function () { 19682 if (this.disabled) { 19683 this.el.innerHTML = ''; 19684 return false; 19685 } 19686 return true; 19687 }, 19688 19689 /** 19690 * Return a region id for a given x/y co-ordinate 19691 */ 19692 getRegion: function (x, y) { 19693 }, 19694 19695 /** 19696 * Highlight an item based on the moused-over x,y co-ordinate 19697 */ 19698 setRegionHighlight: function (el, x, y) { 19699 var currentRegion = this.currentRegion, 19700 highlightEnabled = !this.options.get('disableHighlight'), 19701 newRegion; 19702 if (x > this.canvasWidth || y > this.canvasHeight || x < 0 || y < 0) { 19703 return null; 19704 } 19705 newRegion = this.getRegion(el, x, y); 19706 if (currentRegion !== newRegion) { 19707 if (currentRegion !== undefined && highlightEnabled) { 19708 this.removeHighlight(); 19709 } 19710 this.currentRegion = newRegion; 19711 if (newRegion !== undefined && highlightEnabled) { 19712 this.renderHighlight(); 19713 } 19714 return true; 19715 } 19716 return false; 19717 }, 19718 19719 /** 19720 * Reset any currently highlighted item 19721 */ 19722 clearRegionHighlight: function () { 19723 if (this.currentRegion !== undefined) { 19724 this.removeHighlight(); 19725 this.currentRegion = undefined; 19726 return true; 19727 } 19728 return false; 19729 }, 19730 19731 renderHighlight: function () { 19732 this.changeHighlight(true); 19733 }, 19734 19735 removeHighlight: function () { 19736 this.changeHighlight(false); 19737 }, 19738 19739 changeHighlight: function (highlight) {}, 19740 19741 /** 19742 * Fetch the HTML to display as a tooltip 19743 */ 19744 getCurrentRegionTooltip: function () { 19745 var options = this.options, 19746 header = '', 19747 entries = [], 19748 fields, formats, formatlen, fclass, text, i, 19749 showFields, showFieldsKey, newFields, fv, 19750 formatter, format, fieldlen, j; 19751 if (this.currentRegion === undefined) { 19752 return ''; 19753 } 19754 fields = this.getCurrentRegionFields(); 19755 formatter = options.get('tooltipFormatter'); 19756 if (formatter) { 19757 return formatter(this, options, fields); 19758 } 19759 if (options.get('tooltipChartTitle')) { 19760 header += '<div class="jqs jqstitle">' + options.get('tooltipChartTitle') + '</div>\n'; 19761 } 19762 formats = this.options.get('tooltipFormat'); 19763 if (!formats) { 19764 return ''; 19765 } 19766 if (!$.isArray(formats)) { 19767 formats = [formats]; 19768 } 19769 if (!$.isArray(fields)) { 19770 fields = [fields]; 19771 } 19772 showFields = this.options.get('tooltipFormatFieldlist'); 19773 showFieldsKey = this.options.get('tooltipFormatFieldlistKey'); 19774 if (showFields && showFieldsKey) { 19775 // user-selected ordering of fields 19776 newFields = []; 19777 for (i = fields.length; i--;) { 19778 fv = fields[i][showFieldsKey]; 19779 if ((j = $.inArray(fv, showFields)) != -1) { 19780 newFields[j] = fields[i]; 19781 } 19782 } 19783 fields = newFields; 19784 } 19785 formatlen = formats.length; 19786 fieldlen = fields.length; 19787 for (i = 0; i < formatlen; i++) { 19788 format = formats[i]; 19789 if (typeof format === 'string') { 19790 format = new SPFormat(format); 19791 } 19792 fclass = format.fclass || 'jqsfield'; 19793 for (j = 0; j < fieldlen; j++) { 19794 if (!fields[j].isNull || !options.get('tooltipSkipNull')) { 19795 $.extend(fields[j], { 19796 prefix: options.get('tooltipPrefix'), 19797 suffix: options.get('tooltipSuffix') 19798 }); 19799 text = format.render(fields[j], options.get('tooltipValueLookups'), options); 19800 entries.push('<div class="' + fclass + '">' + text + '</div>'); 19801 } 19802 } 19803 } 19804 if (entries.length) { 19805 return header + entries.join('\n'); 19806 } 19807 return ''; 19808 }, 19809 19810 getCurrentRegionFields: function () {}, 19811 19812 calcHighlightColor: function (color, options) { 19813 var highlightColor = options.get('highlightColor'), 19814 lighten = options.get('highlightLighten'), 19815 parse, mult, rgbnew, i; 19816 if (highlightColor) { 19817 return highlightColor; 19818 } 19819 if (lighten) { 19820 // extract RGB values 19821 parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color); 19822 if (parse) { 19823 rgbnew = []; 19824 mult = color.length === 4 ? 16 : 1; 19825 for (i = 0; i < 3; i++) { 19826 rgbnew[i] = clipval(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255); 19827 } 19828 return 'rgb(' + rgbnew.join(',') + ')'; 19829 } 19830 19831 } 19832 return color; 19833 } 19834 19835 }); 19836 19837 barHighlightMixin = { 19838 changeHighlight: function (highlight) { 19839 var currentRegion = this.currentRegion, 19840 target = this.target, 19841 shapeids = this.regionShapes[currentRegion], 19842 newShapes; 19843 // will be null if the region value was null 19844 if (shapeids) { 19845 newShapes = this.renderRegion(currentRegion, highlight); 19846 if ($.isArray(newShapes) || $.isArray(shapeids)) { 19847 target.replaceWithShapes(shapeids, newShapes); 19848 this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) { 19849 return newShape.id; 19850 }); 19851 } else { 19852 target.replaceWithShape(shapeids, newShapes); 19853 this.regionShapes[currentRegion] = newShapes.id; 19854 } 19855 } 19856 }, 19857 19858 render: function () { 19859 var values = this.values, 19860 target = this.target, 19861 regionShapes = this.regionShapes, 19862 shapes, ids, i, j; 19863 19864 if (!this.cls._super.render.call(this)) { 19865 return; 19866 } 19867 for (i = values.length; i--;) { 19868 shapes = this.renderRegion(i); 19869 if (shapes) { 19870 if ($.isArray(shapes)) { 19871 ids = []; 19872 for (j = shapes.length; j--;) { 19873 shapes[j].append(); 19874 ids.push(shapes[j].id); 19875 } 19876 regionShapes[i] = ids; 19877 } else { 19878 shapes.append(); 19879 regionShapes[i] = shapes.id; // store just the shapeid 19880 } 19881 } else { 19882 // null value 19883 regionShapes[i] = null; 19884 } 19885 } 19886 target.render(); 19887 } 19888 }; 19889 19890 /** 19891 * Line charts 19892 */ 19893 $.fn.sparkline.line = line = createClass($.fn.sparkline._base, { 19894 type: 'line', 19895 19896 init: function (el, values, options, width, height) { 19897 line._super.init.call(this, el, values, options, width, height); 19898 this.vertices = []; 19899 this.regionMap = []; 19900 this.xvalues = []; 19901 this.yvalues = []; 19902 this.yminmax = []; 19903 this.hightlightSpotId = null; 19904 this.lastShapeId = null; 19905 this.initTarget(); 19906 }, 19907 19908 getRegion: function (el, x, y) { 19909 var i, 19910 regionMap = this.regionMap; // maps regions to value positions 19911 for (i = regionMap.length; i--;) { 19912 if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) { 19913 return regionMap[i][2]; 19914 } 19915 } 19916 return undefined; 19917 }, 19918 19919 getCurrentRegionFields: function () { 19920 var currentRegion = this.currentRegion; 19921 return { 19922 isNull: this.yvalues[currentRegion] === null, 19923 x: this.xvalues[currentRegion], 19924 y: this.yvalues[currentRegion], 19925 color: this.options.get('lineColor'), 19926 fillColor: this.options.get('fillColor'), 19927 offset: currentRegion 19928 }; 19929 }, 19930 19931 renderHighlight: function () { 19932 var currentRegion = this.currentRegion, 19933 target = this.target, 19934 vertex = this.vertices[currentRegion], 19935 options = this.options, 19936 spotRadius = options.get('spotRadius'), 19937 highlightSpotColor = options.get('highlightSpotColor'), 19938 highlightLineColor = options.get('highlightLineColor'), 19939 highlightSpot, highlightLine; 19940 19941 if (!vertex) { 19942 return; 19943 } 19944 if (spotRadius && highlightSpotColor) { 19945 highlightSpot = target.drawCircle(vertex[0], vertex[1], 19946 spotRadius, undefined, highlightSpotColor); 19947 this.highlightSpotId = highlightSpot.id; 19948 target.insertAfterShape(this.lastShapeId, highlightSpot); 19949 } 19950 if (highlightLineColor) { 19951 highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0], 19952 this.canvasTop + this.canvasHeight, highlightLineColor); 19953 this.highlightLineId = highlightLine.id; 19954 target.insertAfterShape(this.lastShapeId, highlightLine); 19955 } 19956 }, 19957 19958 removeHighlight: function () { 19959 var target = this.target; 19960 if (this.highlightSpotId) { 19961 target.removeShapeId(this.highlightSpotId); 19962 this.highlightSpotId = null; 19963 } 19964 if (this.highlightLineId) { 19965 target.removeShapeId(this.highlightLineId); 19966 this.highlightLineId = null; 19967 } 19968 }, 19969 19970 scanValues: function () { 19971 var values = this.values, 19972 valcount = values.length, 19973 xvalues = this.xvalues, 19974 yvalues = this.yvalues, 19975 yminmax = this.yminmax, 19976 i, val, isStr, isArray, sp; 19977 for (i = 0; i < valcount; i++) { 19978 val = values[i]; 19979 isStr = typeof(values[i]) === 'string'; 19980 isArray = typeof(values[i]) === 'object' && values[i] instanceof Array; 19981 sp = isStr && values[i].split(':'); 19982 if (isStr && sp.length === 2) { // x:y 19983 xvalues.push(Number(sp[0])); 19984 yvalues.push(Number(sp[1])); 19985 yminmax.push(Number(sp[1])); 19986 } else if (isArray) { 19987 xvalues.push(val[0]); 19988 yvalues.push(val[1]); 19989 yminmax.push(val[1]); 19990 } else { 19991 xvalues.push(i); 19992 if (values[i] === null || values[i] === 'null') { 19993 yvalues.push(null); 19994 } else { 19995 yvalues.push(Number(val)); 19996 yminmax.push(Number(val)); 19997 } 19998 } 19999 } 20000 if (this.options.get('xvalues')) { 20001 xvalues = this.options.get('xvalues'); 20002 } 20003 20004 this.maxy = this.maxyorg = Math.max.apply(Math, yminmax); 20005 this.miny = this.minyorg = Math.min.apply(Math, yminmax); 20006 20007 this.maxx = Math.max.apply(Math, xvalues); 20008 this.minx = Math.min.apply(Math, xvalues); 20009 20010 this.xvalues = xvalues; 20011 this.yvalues = yvalues; 20012 this.yminmax = yminmax; 20013 20014 }, 20015 20016 processRangeOptions: function () { 20017 var options = this.options, 20018 normalRangeMin = options.get('normalRangeMin'), 20019 normalRangeMax = options.get('normalRangeMax'); 20020 20021 if (normalRangeMin !== undefined) { 20022 if (normalRangeMin < this.miny) { 20023 this.miny = normalRangeMin; 20024 } 20025 if (normalRangeMax > this.maxy) { 20026 this.maxy = normalRangeMax; 20027 } 20028 } 20029 if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) { 20030 this.miny = options.get('chartRangeMin'); 20031 } 20032 if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) { 20033 this.maxy = options.get('chartRangeMax'); 20034 } 20035 if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) { 20036 this.minx = options.get('chartRangeMinX'); 20037 } 20038 if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) { 20039 this.maxx = options.get('chartRangeMaxX'); 20040 } 20041 20042 }, 20043 20044 drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) { 20045 var normalRangeMin = this.options.get('normalRangeMin'), 20046 normalRangeMax = this.options.get('normalRangeMax'), 20047 ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))), 20048 height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey); 20049 this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append(); 20050 }, 20051 20052 render: function () { 20053 var options = this.options, 20054 target = this.target, 20055 canvasWidth = this.canvasWidth, 20056 canvasHeight = this.canvasHeight, 20057 vertices = this.vertices, 20058 spotRadius = options.get('spotRadius'), 20059 regionMap = this.regionMap, 20060 rangex, rangey, yvallast, 20061 canvasTop, canvasLeft, 20062 vertex, path, paths, x, y, xnext, xpos, xposnext, 20063 last, next, yvalcount, lineShapes, fillShapes, plen, 20064 valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i; 20065 20066 if (!line._super.render.call(this)) { 20067 return; 20068 } 20069 20070 this.scanValues(); 20071 this.processRangeOptions(); 20072 20073 xvalues = this.xvalues; 20074 yvalues = this.yvalues; 20075 20076 if (!this.yminmax.length || this.yvalues.length < 2) { 20077 // empty or all null valuess 20078 return; 20079 } 20080 20081 canvasTop = canvasLeft = 0; 20082 20083 rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx; 20084 rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny; 20085 yvallast = this.yvalues.length - 1; 20086 20087 if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) { 20088 spotRadius = 0; 20089 } 20090 if (spotRadius) { 20091 // adjust the canvas size as required so that spots will fit 20092 hlSpotsEnabled = options.get('highlightSpotColor') && !options.get('disableInteraction'); 20093 if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) { 20094 canvasHeight -= Math.ceil(spotRadius); 20095 } 20096 if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) { 20097 canvasHeight -= Math.ceil(spotRadius); 20098 canvasTop += Math.ceil(spotRadius); 20099 } 20100 if (hlSpotsEnabled || 20101 ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) { 20102 canvasLeft += Math.ceil(spotRadius); 20103 canvasWidth -= Math.ceil(spotRadius); 20104 } 20105 if (hlSpotsEnabled || options.get('spotColor') || 20106 (options.get('minSpotColor') || options.get('maxSpotColor') && 20107 (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) { 20108 canvasWidth -= Math.ceil(spotRadius); 20109 } 20110 } 20111 20112 20113 canvasHeight--; 20114 20115 if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) { 20116 this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey); 20117 } 20118 20119 path = []; 20120 paths = [path]; 20121 last = next = null; 20122 yvalcount = yvalues.length; 20123 for (i = 0; i < yvalcount; i++) { 20124 x = xvalues[i]; 20125 xnext = xvalues[i + 1]; 20126 y = yvalues[i]; 20127 xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)); 20128 xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth; 20129 next = xpos + ((xposnext - xpos) / 2); 20130 regionMap[i] = [last || 0, next, i]; 20131 last = next; 20132 if (y === null) { 20133 if (i) { 20134 if (yvalues[i - 1] !== null) { 20135 path = []; 20136 paths.push(path); 20137 } 20138 vertices.push(null); 20139 } 20140 } else { 20141 if (y < this.miny) { 20142 y = this.miny; 20143 } 20144 if (y > this.maxy) { 20145 y = this.maxy; 20146 } 20147 if (!path.length) { 20148 // previous value was null 20149 path.push([xpos, canvasTop + canvasHeight]); 20150 } 20151 vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))]; 20152 path.push(vertex); 20153 vertices.push(vertex); 20154 } 20155 } 20156 20157 lineShapes = []; 20158 fillShapes = []; 20159 plen = paths.length; 20160 for (i = 0; i < plen; i++) { 20161 path = paths[i]; 20162 if (path.length) { 20163 if (options.get('fillColor')) { 20164 path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]); 20165 fillShapes.push(path.slice(0)); 20166 path.pop(); 20167 } 20168 // if there's only a single point in this path, then we want to display it 20169 // as a vertical line which means we keep path[0] as is 20170 if (path.length > 2) { 20171 // else we want the first value 20172 path[0] = [path[0][0], path[1][1]]; 20173 } 20174 lineShapes.push(path); 20175 } 20176 } 20177 20178 // draw the fill first, then optionally the normal range, then the line on top of that 20179 plen = fillShapes.length; 20180 for (i = 0; i < plen; i++) { 20181 target.drawShape(fillShapes[i], 20182 options.get('fillColor'), options.get('fillColor')).append(); 20183 } 20184 20185 if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) { 20186 this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey); 20187 } 20188 20189 plen = lineShapes.length; 20190 for (i = 0; i < plen; i++) { 20191 target.drawShape(lineShapes[i], options.get('lineColor'), undefined, 20192 options.get('lineWidth')).append(); 20193 } 20194 20195 if (spotRadius && options.get('valueSpots')) { 20196 valueSpots = options.get('valueSpots'); 20197 if (valueSpots.get === undefined) { 20198 valueSpots = new RangeMap(valueSpots); 20199 } 20200 for (i = 0; i < yvalcount; i++) { 20201 color = valueSpots.get(yvalues[i]); 20202 if (color) { 20203 target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)), 20204 canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))), 20205 spotRadius, undefined, 20206 color).append(); 20207 } 20208 } 20209 20210 } 20211 if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) { 20212 target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)), 20213 canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))), 20214 spotRadius, undefined, 20215 options.get('spotColor')).append(); 20216 } 20217 if (this.maxy !== this.minyorg) { 20218 if (spotRadius && options.get('minSpotColor')) { 20219 x = xvalues[$.inArray(this.minyorg, yvalues)]; 20220 target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)), 20221 canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))), 20222 spotRadius, undefined, 20223 options.get('minSpotColor')).append(); 20224 } 20225 if (spotRadius && options.get('maxSpotColor')) { 20226 x = xvalues[$.inArray(this.maxyorg, yvalues)]; 20227 target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)), 20228 canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))), 20229 spotRadius, undefined, 20230 options.get('maxSpotColor')).append(); 20231 } 20232 } 20233 20234 this.lastShapeId = target.getLastShapeId(); 20235 this.canvasTop = canvasTop; 20236 target.render(); 20237 } 20238 }); 20239 20240 /** 20241 * Bar charts 20242 */ 20243 $.fn.sparkline.bar = bar = createClass($.fn.sparkline._base, barHighlightMixin, { 20244 type: 'bar', 20245 20246 init: function (el, values, options, width, height) { 20247 var barWidth = parseInt(options.get('barWidth'), 10), 20248 barSpacing = parseInt(options.get('barSpacing'), 10), 20249 chartRangeMin = options.get('chartRangeMin'), 20250 chartRangeMax = options.get('chartRangeMax'), 20251 chartRangeClip = options.get('chartRangeClip'), 20252 stackMin = Infinity, 20253 stackMax = -Infinity, 20254 isStackString, groupMin, groupMax, stackRanges, 20255 numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax, 20256 stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf; 20257 bar._super.init.call(this, el, values, options, width, height); 20258 20259 // scan values to determine whether to stack bars 20260 for (i = 0, vlen = values.length; i < vlen; i++) { 20261 val = values[i]; 20262 isStackString = typeof(val) === 'string' && val.indexOf(':') > -1; 20263 if (isStackString || $.isArray(val)) { 20264 stacked = true; 20265 if (isStackString) { 20266 val = values[i] = normalizeValues(val.split(':')); 20267 } 20268 val = remove(val, null); // min/max will treat null as zero 20269 groupMin = Math.min.apply(Math, val); 20270 groupMax = Math.max.apply(Math, val); 20271 if (groupMin < stackMin) { 20272 stackMin = groupMin; 20273 } 20274 if (groupMax > stackMax) { 20275 stackMax = groupMax; 20276 } 20277 } 20278 } 20279 20280 this.stacked = stacked; 20281 this.regionShapes = {}; 20282 this.barWidth = barWidth; 20283 this.barSpacing = barSpacing; 20284 this.totalBarWidth = barWidth + barSpacing; 20285 this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing); 20286 20287 this.initTarget(); 20288 20289 if (chartRangeClip) { 20290 clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin; 20291 clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax; 20292 } 20293 20294 numValues = []; 20295 stackRanges = stacked ? [] : numValues; 20296 var stackTotals = []; 20297 var stackRangesNeg = []; 20298 for (i = 0, vlen = values.length; i < vlen; i++) { 20299 if (stacked) { 20300 vlist = values[i]; 20301 values[i] = svals = []; 20302 stackTotals[i] = 0; 20303 stackRanges[i] = stackRangesNeg[i] = 0; 20304 for (j = 0, slen = vlist.length; j < slen; j++) { 20305 val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j]; 20306 if (val !== null) { 20307 if (val > 0) { 20308 stackTotals[i] += val; 20309 } 20310 if (stackMin < 0 && stackMax > 0) { 20311 if (val < 0) { 20312 stackRangesNeg[i] += Math.abs(val); 20313 } else { 20314 stackRanges[i] += val; 20315 } 20316 } else { 20317 stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin)); 20318 } 20319 numValues.push(val); 20320 } 20321 } 20322 } else { 20323 val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i]; 20324 val = values[i] = normalizeValue(val); 20325 if (val !== null) { 20326 numValues.push(val); 20327 } 20328 } 20329 } 20330 this.max = max = Math.max.apply(Math, numValues); 20331 this.min = min = Math.min.apply(Math, numValues); 20332 this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max; 20333 this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min; 20334 20335 if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < min)) { 20336 min = options.get('chartRangeMin'); 20337 } 20338 if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > max)) { 20339 max = options.get('chartRangeMax'); 20340 } 20341 20342 this.zeroAxis = zeroAxis = options.get('zeroAxis', true); 20343 if (min <= 0 && max >= 0 && zeroAxis) { 20344 xaxisOffset = 0; 20345 } else if (zeroAxis == false) { 20346 xaxisOffset = min; 20347 } else if (min > 0) { 20348 xaxisOffset = min; 20349 } else { 20350 xaxisOffset = max; 20351 } 20352 this.xaxisOffset = xaxisOffset; 20353 20354 range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min; 20355 20356 // as we plot zero/min values a single pixel line, we add a pixel to all other 20357 // values - Reduce the effective canvas size to suit 20358 this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1; 20359 20360 if (min < xaxisOffset) { 20361 yMaxCalc = (stacked && max >= 0) ? stackMax : max; 20362 yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight; 20363 if (yoffset !== Math.ceil(yoffset)) { 20364 this.canvasHeightEf -= 2; 20365 yoffset = Math.ceil(yoffset); 20366 } 20367 } else { 20368 yoffset = this.canvasHeight; 20369 } 20370 this.yoffset = yoffset; 20371 20372 if ($.isArray(options.get('colorMap'))) { 20373 this.colorMapByIndex = options.get('colorMap'); 20374 this.colorMapByValue = null; 20375 } else { 20376 this.colorMapByIndex = null; 20377 this.colorMapByValue = options.get('colorMap'); 20378 if (this.colorMapByValue && this.colorMapByValue.get === undefined) { 20379 this.colorMapByValue = new RangeMap(this.colorMapByValue); 20380 } 20381 } 20382 20383 this.range = range; 20384 }, 20385 20386 getRegion: function (el, x, y) { 20387 var result = Math.floor(x / this.totalBarWidth); 20388 return (result < 0 || result >= this.values.length) ? undefined : result; 20389 }, 20390 20391 getCurrentRegionFields: function () { 20392 var currentRegion = this.currentRegion, 20393 values = ensureArray(this.values[currentRegion]), 20394 result = [], 20395 value, i; 20396 for (i = values.length; i--;) { 20397 value = values[i]; 20398 result.push({ 20399 isNull: value === null, 20400 value: value, 20401 color: this.calcColor(i, value, currentRegion), 20402 offset: currentRegion 20403 }); 20404 } 20405 return result; 20406 }, 20407 20408 calcColor: function (stacknum, value, valuenum) { 20409 var colorMapByIndex = this.colorMapByIndex, 20410 colorMapByValue = this.colorMapByValue, 20411 options = this.options, 20412 color, newColor; 20413 if (this.stacked) { 20414 color = options.get('stackedBarColor'); 20415 } else { 20416 color = (value < 0) ? options.get('negBarColor') : options.get('barColor'); 20417 } 20418 if (value === 0 && options.get('zeroColor') !== undefined) { 20419 color = options.get('zeroColor'); 20420 } 20421 if (colorMapByValue && (newColor = colorMapByValue.get(value))) { 20422 color = newColor; 20423 } else if (colorMapByIndex && colorMapByIndex.length > valuenum) { 20424 color = colorMapByIndex[valuenum]; 20425 } 20426 return $.isArray(color) ? color[stacknum % color.length] : color; 20427 }, 20428 20429 /** 20430 * Render bar(s) for a region 20431 */ 20432 renderRegion: function (valuenum, highlight) { 20433 var vals = this.values[valuenum], 20434 options = this.options, 20435 xaxisOffset = this.xaxisOffset, 20436 result = [], 20437 range = this.range, 20438 stacked = this.stacked, 20439 target = this.target, 20440 x = valuenum * this.totalBarWidth, 20441 canvasHeightEf = this.canvasHeightEf, 20442 yoffset = this.yoffset, 20443 y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin; 20444 20445 vals = $.isArray(vals) ? vals : [vals]; 20446 valcount = vals.length; 20447 val = vals[0]; 20448 isNull = all(null, vals); 20449 allMin = all(xaxisOffset, vals, true); 20450 20451 if (isNull) { 20452 if (options.get('nullColor')) { 20453 color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options); 20454 y = (yoffset > 0) ? yoffset - 1 : yoffset; 20455 return target.drawRect(x, y, this.barWidth - 1, 0, color, color); 20456 } else { 20457 return undefined; 20458 } 20459 } 20460 yoffsetNeg = yoffset; 20461 for (i = 0; i < valcount; i++) { 20462 val = vals[i]; 20463 20464 if (stacked && val === xaxisOffset) { 20465 if (!allMin || minPlotted) { 20466 continue; 20467 } 20468 minPlotted = true; 20469 } 20470 20471 if (range > 0) { 20472 height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1; 20473 } else { 20474 height = 1; 20475 } 20476 if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) { 20477 y = yoffsetNeg; 20478 yoffsetNeg += height; 20479 } else { 20480 y = yoffset - height; 20481 yoffset -= height; 20482 } 20483 color = this.calcColor(i, val, valuenum); 20484 if (highlight) { 20485 color = this.calcHighlightColor(color, options); 20486 } 20487 result.push(target.drawRect(x, y, this.barWidth - 1, height - 1, color, color)); 20488 } 20489 if (result.length === 1) { 20490 return result[0]; 20491 } 20492 return result; 20493 } 20494 }); 20495 20496 /** 20497 * Tristate charts 20498 */ 20499 $.fn.sparkline.tristate = tristate = createClass($.fn.sparkline._base, barHighlightMixin, { 20500 type: 'tristate', 20501 20502 init: function (el, values, options, width, height) { 20503 var barWidth = parseInt(options.get('barWidth'), 10), 20504 barSpacing = parseInt(options.get('barSpacing'), 10); 20505 tristate._super.init.call(this, el, values, options, width, height); 20506 20507 this.regionShapes = {}; 20508 this.barWidth = barWidth; 20509 this.barSpacing = barSpacing; 20510 this.totalBarWidth = barWidth + barSpacing; 20511 this.values = $.map(values, Number); 20512 this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing); 20513 20514 if ($.isArray(options.get('colorMap'))) { 20515 this.colorMapByIndex = options.get('colorMap'); 20516 this.colorMapByValue = null; 20517 } else { 20518 this.colorMapByIndex = null; 20519 this.colorMapByValue = options.get('colorMap'); 20520 if (this.colorMapByValue && this.colorMapByValue.get === undefined) { 20521 this.colorMapByValue = new RangeMap(this.colorMapByValue); 20522 } 20523 } 20524 this.initTarget(); 20525 }, 20526 20527 getRegion: function (el, x, y) { 20528 return Math.floor(x / this.totalBarWidth); 20529 }, 20530 20531 getCurrentRegionFields: function () { 20532 var currentRegion = this.currentRegion; 20533 return { 20534 isNull: this.values[currentRegion] === undefined, 20535 value: this.values[currentRegion], 20536 color: this.calcColor(this.values[currentRegion], currentRegion), 20537 offset: currentRegion 20538 }; 20539 }, 20540 20541 calcColor: function (value, valuenum) { 20542 var values = this.values, 20543 options = this.options, 20544 colorMapByIndex = this.colorMapByIndex, 20545 colorMapByValue = this.colorMapByValue, 20546 color, newColor; 20547 20548 if (colorMapByValue && (newColor = colorMapByValue.get(value))) { 20549 color = newColor; 20550 } else if (colorMapByIndex && colorMapByIndex.length > valuenum) { 20551 color = colorMapByIndex[valuenum]; 20552 } else if (values[valuenum] < 0) { 20553 color = options.get('negBarColor'); 20554 } else if (values[valuenum] > 0) { 20555 color = options.get('posBarColor'); 20556 } else { 20557 color = options.get('zeroBarColor'); 20558 } 20559 return color; 20560 }, 20561 20562 renderRegion: function (valuenum, highlight) { 20563 var values = this.values, 20564 options = this.options, 20565 target = this.target, 20566 canvasHeight, height, halfHeight, 20567 x, y, color; 20568 20569 canvasHeight = target.pixelHeight; 20570 halfHeight = Math.round(canvasHeight / 2); 20571 20572 x = valuenum * this.totalBarWidth; 20573 if (values[valuenum] < 0) { 20574 y = halfHeight; 20575 height = halfHeight - 1; 20576 } else if (values[valuenum] > 0) { 20577 y = 0; 20578 height = halfHeight - 1; 20579 } else { 20580 y = halfHeight - 1; 20581 height = 2; 20582 } 20583 color = this.calcColor(values[valuenum], valuenum); 20584 if (color === null) { 20585 return; 20586 } 20587 if (highlight) { 20588 color = this.calcHighlightColor(color, options); 20589 } 20590 return target.drawRect(x, y, this.barWidth - 1, height - 1, color, color); 20591 } 20592 }); 20593 20594 /** 20595 * Discrete charts 20596 */ 20597 $.fn.sparkline.discrete = discrete = createClass($.fn.sparkline._base, barHighlightMixin, { 20598 type: 'discrete', 20599 20600 init: function (el, values, options, width, height) { 20601 discrete._super.init.call(this, el, values, options, width, height); 20602 20603 this.regionShapes = {}; 20604 this.values = values = $.map(values, Number); 20605 this.min = Math.min.apply(Math, values); 20606 this.max = Math.max.apply(Math, values); 20607 this.range = this.max - this.min; 20608 this.width = width = options.get('width') === 'auto' ? values.length * 2 : this.width; 20609 this.interval = Math.floor(width / values.length); 20610 this.itemWidth = width / values.length; 20611 if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) { 20612 this.min = options.get('chartRangeMin'); 20613 } 20614 if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) { 20615 this.max = options.get('chartRangeMax'); 20616 } 20617 this.initTarget(); 20618 if (this.target) { 20619 this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight'); 20620 } 20621 }, 20622 20623 getRegion: function (el, x, y) { 20624 return Math.floor(x / this.itemWidth); 20625 }, 20626 20627 getCurrentRegionFields: function () { 20628 var currentRegion = this.currentRegion; 20629 return { 20630 isNull: this.values[currentRegion] === undefined, 20631 value: this.values[currentRegion], 20632 offset: currentRegion 20633 }; 20634 }, 20635 20636 renderRegion: function (valuenum, highlight) { 20637 var values = this.values, 20638 options = this.options, 20639 min = this.min, 20640 max = this.max, 20641 range = this.range, 20642 interval = this.interval, 20643 target = this.target, 20644 canvasHeight = this.canvasHeight, 20645 lineHeight = this.lineHeight, 20646 pheight = canvasHeight - lineHeight, 20647 ytop, val, color, x; 20648 20649 val = clipval(values[valuenum], min, max); 20650 x = valuenum * interval; 20651 ytop = Math.round(pheight - pheight * ((val - min) / range)); 20652 color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor'); 20653 if (highlight) { 20654 color = this.calcHighlightColor(color, options); 20655 } 20656 return target.drawLine(x, ytop, x, ytop + lineHeight, color); 20657 } 20658 }); 20659 20660 /** 20661 * Bullet charts 20662 */ 20663 $.fn.sparkline.bullet = bullet = createClass($.fn.sparkline._base, { 20664 type: 'bullet', 20665 20666 init: function (el, values, options, width, height) { 20667 var min, max, vals; 20668 bullet._super.init.call(this, el, values, options, width, height); 20669 20670 // values: target, performance, range1, range2, range3 20671 this.values = values = normalizeValues(values); 20672 // target or performance could be null 20673 vals = values.slice(); 20674 vals[0] = vals[0] === null ? vals[2] : vals[0]; 20675 vals[1] = values[1] === null ? vals[2] : vals[1]; 20676 min = Math.min.apply(Math, values); 20677 max = Math.max.apply(Math, values); 20678 if (options.get('base') === undefined) { 20679 min = min < 0 ? min : 0; 20680 } else { 20681 min = options.get('base'); 20682 } 20683 this.min = min; 20684 this.max = max; 20685 this.range = max - min; 20686 this.shapes = {}; 20687 this.valueShapes = {}; 20688 this.regiondata = {}; 20689 this.width = width = options.get('width') === 'auto' ? '4.0em' : width; 20690 this.target = this.$el.simpledraw(width, height, options.get('composite')); 20691 if (!values.length) { 20692 this.disabled = true; 20693 } 20694 this.initTarget(); 20695 }, 20696 20697 getRegion: function (el, x, y) { 20698 var shapeid = this.target.getShapeAt(el, x, y); 20699 return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined; 20700 }, 20701 20702 getCurrentRegionFields: function () { 20703 var currentRegion = this.currentRegion; 20704 return { 20705 fieldkey: currentRegion.substr(0, 1), 20706 value: this.values[currentRegion.substr(1)], 20707 region: currentRegion 20708 }; 20709 }, 20710 20711 changeHighlight: function (highlight) { 20712 var currentRegion = this.currentRegion, 20713 shapeid = this.valueShapes[currentRegion], 20714 shape; 20715 delete this.shapes[shapeid]; 20716 switch (currentRegion.substr(0, 1)) { 20717 case 'r': 20718 shape = this.renderRange(currentRegion.substr(1), highlight); 20719 break; 20720 case 'p': 20721 shape = this.renderPerformance(highlight); 20722 break; 20723 case 't': 20724 shape = this.renderTarget(highlight); 20725 break; 20726 } 20727 this.valueShapes[currentRegion] = shape.id; 20728 this.shapes[shape.id] = currentRegion; 20729 this.target.replaceWithShape(shapeid, shape); 20730 }, 20731 20732 renderRange: function (rn, highlight) { 20733 var rangeval = this.values[rn], 20734 rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)), 20735 color = this.options.get('rangeColors')[rn - 2]; 20736 if (highlight) { 20737 color = this.calcHighlightColor(color, this.options); 20738 } 20739 return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color); 20740 }, 20741 20742 renderPerformance: function (highlight) { 20743 var perfval = this.values[1], 20744 perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)), 20745 color = this.options.get('performanceColor'); 20746 if (highlight) { 20747 color = this.calcHighlightColor(color, this.options); 20748 } 20749 return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1, 20750 Math.round(this.canvasHeight * 0.4) - 1, color, color); 20751 }, 20752 20753 renderTarget: function (highlight) { 20754 var targetval = this.values[0], 20755 x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)), 20756 targettop = Math.round(this.canvasHeight * 0.10), 20757 targetheight = this.canvasHeight - (targettop * 2), 20758 color = this.options.get('targetColor'); 20759 if (highlight) { 20760 color = this.calcHighlightColor(color, this.options); 20761 } 20762 return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color); 20763 }, 20764 20765 render: function () { 20766 var vlen = this.values.length, 20767 target = this.target, 20768 i, shape; 20769 if (!bullet._super.render.call(this)) { 20770 return; 20771 } 20772 for (i = 2; i < vlen; i++) { 20773 shape = this.renderRange(i).append(); 20774 this.shapes[shape.id] = 'r' + i; 20775 this.valueShapes['r' + i] = shape.id; 20776 } 20777 if (this.values[1] !== null) { 20778 shape = this.renderPerformance().append(); 20779 this.shapes[shape.id] = 'p1'; 20780 this.valueShapes.p1 = shape.id; 20781 } 20782 if (this.values[0] !== null) { 20783 shape = this.renderTarget().append(); 20784 this.shapes[shape.id] = 't0'; 20785 this.valueShapes.t0 = shape.id; 20786 } 20787 target.render(); 20788 } 20789 }); 20790 20791 /** 20792 * Pie charts 20793 */ 20794 $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, { 20795 type: 'pie', 20796 20797 init: function (el, values, options, width, height) { 20798 var total = 0, i; 20799 20800 pie._super.init.call(this, el, values, options, width, height); 20801 20802 this.shapes = {}; // map shape ids to value offsets 20803 this.valueShapes = {}; // maps value offsets to shape ids 20804 this.values = values = $.map(values, Number); 20805 20806 if (options.get('width') === 'auto') { 20807 this.width = this.height; 20808 } 20809 20810 if (values.length > 0) { 20811 for (i = values.length; i--;) { 20812 total += values[i]; 20813 } 20814 } 20815 this.total = total; 20816 this.initTarget(); 20817 this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2); 20818 }, 20819 20820 getRegion: function (el, x, y) { 20821 var shapeid = this.target.getShapeAt(el, x, y); 20822 return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined; 20823 }, 20824 20825 getCurrentRegionFields: function () { 20826 var currentRegion = this.currentRegion; 20827 return { 20828 isNull: this.values[currentRegion] === undefined, 20829 value: this.values[currentRegion], 20830 percent: this.values[currentRegion] / this.total * 100, 20831 color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length], 20832 offset: currentRegion 20833 }; 20834 }, 20835 20836 changeHighlight: function (highlight) { 20837 var currentRegion = this.currentRegion, 20838 newslice = this.renderSlice(currentRegion, highlight), 20839 shapeid = this.valueShapes[currentRegion]; 20840 delete this.shapes[shapeid]; 20841 this.target.replaceWithShape(shapeid, newslice); 20842 this.valueShapes[currentRegion] = newslice.id; 20843 this.shapes[newslice.id] = currentRegion; 20844 }, 20845 20846 renderSlice: function (valuenum, highlight) { 20847 var target = this.target, 20848 options = this.options, 20849 radius = this.radius, 20850 borderWidth = options.get('borderWidth'), 20851 offset = options.get('offset'), 20852 circle = 2 * Math.PI, 20853 values = this.values, 20854 total = this.total, 20855 next = offset ? (2*Math.PI)*(offset/360) : 0, 20856 start, end, i, vlen, color; 20857 20858 vlen = values.length; 20859 for (i = 0; i < vlen; i++) { 20860 start = next; 20861 end = next; 20862 if (total > 0) { // avoid divide by zero 20863 end = next + (circle * (values[i] / total)); 20864 } 20865 if (valuenum === i) { 20866 color = options.get('sliceColors')[i % options.get('sliceColors').length]; 20867 if (highlight) { 20868 color = this.calcHighlightColor(color, options); 20869 } 20870 20871 return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color); 20872 } 20873 next = end; 20874 } 20875 }, 20876 20877 render: function () { 20878 var target = this.target, 20879 values = this.values, 20880 options = this.options, 20881 radius = this.radius, 20882 borderWidth = options.get('borderWidth'), 20883 donutWidth = options.get('donutWidth'), 20884 shape, i; 20885 20886 if (!pie._super.render.call(this)) { 20887 return; 20888 } 20889 if (borderWidth) { 20890 target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)), 20891 options.get('borderColor'), undefined, borderWidth).append(); 20892 } 20893 for (i = values.length; i--;) { 20894 if (values[i]) { // don't render zero values 20895 shape = this.renderSlice(i).append(); 20896 this.valueShapes[i] = shape.id; // store just the shapeid 20897 this.shapes[shape.id] = i; 20898 } 20899 } 20900 if (donutWidth) { 20901 target.drawCircle(radius, radius, radius - donutWidth, options.get('donutColor'), 20902 options.get('donutColor'), 0).append(); 20903 } 20904 target.render(); 20905 } 20906 }); 20907 20908 /** 20909 * Box plots 20910 */ 20911 $.fn.sparkline.box = box = createClass($.fn.sparkline._base, { 20912 type: 'box', 20913 20914 init: function (el, values, options, width, height) { 20915 box._super.init.call(this, el, values, options, width, height); 20916 this.values = $.map(values, Number); 20917 this.width = options.get('width') === 'auto' ? '4.0em' : width; 20918 this.initTarget(); 20919 if (!this.values.length) { 20920 this.disabled = 1; 20921 } 20922 }, 20923 20924 /** 20925 * Simulate a single region 20926 */ 20927 getRegion: function () { 20928 return 1; 20929 }, 20930 20931 getCurrentRegionFields: function () { 20932 var result = [ 20933 { field: 'lq', value: this.quartiles[0] }, 20934 { field: 'med', value: this.quartiles[1] }, 20935 { field: 'uq', value: this.quartiles[2] } 20936 ]; 20937 if (this.loutlier !== undefined) { 20938 result.push({ field: 'lo', value: this.loutlier}); 20939 } 20940 if (this.routlier !== undefined) { 20941 result.push({ field: 'ro', value: this.routlier}); 20942 } 20943 if (this.lwhisker !== undefined) { 20944 result.push({ field: 'lw', value: this.lwhisker}); 20945 } 20946 if (this.rwhisker !== undefined) { 20947 result.push({ field: 'rw', value: this.rwhisker}); 20948 } 20949 return result; 20950 }, 20951 20952 render: function () { 20953 var target = this.target, 20954 values = this.values, 20955 vlen = values.length, 20956 options = this.options, 20957 canvasWidth = this.canvasWidth, 20958 canvasHeight = this.canvasHeight, 20959 minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'), 20960 maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'), 20961 canvasLeft = 0, 20962 lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i, 20963 size, unitSize; 20964 20965 if (!box._super.render.call(this)) { 20966 return; 20967 } 20968 20969 if (options.get('raw')) { 20970 if (options.get('showOutliers') && values.length > 5) { 20971 loutlier = values[0]; 20972 lwhisker = values[1]; 20973 q1 = values[2]; 20974 q2 = values[3]; 20975 q3 = values[4]; 20976 rwhisker = values[5]; 20977 routlier = values[6]; 20978 } else { 20979 lwhisker = values[0]; 20980 q1 = values[1]; 20981 q2 = values[2]; 20982 q3 = values[3]; 20983 rwhisker = values[4]; 20984 } 20985 } else { 20986 values.sort(function (a, b) { return a - b; }); 20987 q1 = quartile(values, 1); 20988 q2 = quartile(values, 2); 20989 q3 = quartile(values, 3); 20990 iqr = q3 - q1; 20991 if (options.get('showOutliers')) { 20992 lwhisker = rwhisker = undefined; 20993 for (i = 0; i < vlen; i++) { 20994 if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) { 20995 lwhisker = values[i]; 20996 } 20997 if (values[i] < q3 + (iqr * options.get('outlierIQR'))) { 20998 rwhisker = values[i]; 20999 } 21000 } 21001 loutlier = values[0]; 21002 routlier = values[vlen - 1]; 21003 } else { 21004 lwhisker = values[0]; 21005 rwhisker = values[vlen - 1]; 21006 } 21007 } 21008 this.quartiles = [q1, q2, q3]; 21009 this.lwhisker = lwhisker; 21010 this.rwhisker = rwhisker; 21011 this.loutlier = loutlier; 21012 this.routlier = routlier; 21013 21014 unitSize = canvasWidth / (maxValue - minValue + 1); 21015 if (options.get('showOutliers')) { 21016 canvasLeft = Math.ceil(options.get('spotRadius')); 21017 canvasWidth -= 2 * Math.ceil(options.get('spotRadius')); 21018 unitSize = canvasWidth / (maxValue - minValue + 1); 21019 if (loutlier < lwhisker) { 21020 target.drawCircle((loutlier - minValue) * unitSize + canvasLeft, 21021 canvasHeight / 2, 21022 options.get('spotRadius'), 21023 options.get('outlierLineColor'), 21024 options.get('outlierFillColor')).append(); 21025 } 21026 if (routlier > rwhisker) { 21027 target.drawCircle((routlier - minValue) * unitSize + canvasLeft, 21028 canvasHeight / 2, 21029 options.get('spotRadius'), 21030 options.get('outlierLineColor'), 21031 options.get('outlierFillColor')).append(); 21032 } 21033 } 21034 21035 // box 21036 target.drawRect( 21037 Math.round((q1 - minValue) * unitSize + canvasLeft), 21038 Math.round(canvasHeight * 0.1), 21039 Math.round((q3 - q1) * unitSize), 21040 Math.round(canvasHeight * 0.8), 21041 options.get('boxLineColor'), 21042 options.get('boxFillColor')).append(); 21043 // left whisker 21044 target.drawLine( 21045 Math.round((lwhisker - minValue) * unitSize + canvasLeft), 21046 Math.round(canvasHeight / 2), 21047 Math.round((q1 - minValue) * unitSize + canvasLeft), 21048 Math.round(canvasHeight / 2), 21049 options.get('lineColor')).append(); 21050 target.drawLine( 21051 Math.round((lwhisker - minValue) * unitSize + canvasLeft), 21052 Math.round(canvasHeight / 4), 21053 Math.round((lwhisker - minValue) * unitSize + canvasLeft), 21054 Math.round(canvasHeight - canvasHeight / 4), 21055 options.get('whiskerColor')).append(); 21056 // right whisker 21057 target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft), 21058 Math.round(canvasHeight / 2), 21059 Math.round((q3 - minValue) * unitSize + canvasLeft), 21060 Math.round(canvasHeight / 2), 21061 options.get('lineColor')).append(); 21062 target.drawLine( 21063 Math.round((rwhisker - minValue) * unitSize + canvasLeft), 21064 Math.round(canvasHeight / 4), 21065 Math.round((rwhisker - minValue) * unitSize + canvasLeft), 21066 Math.round(canvasHeight - canvasHeight / 4), 21067 options.get('whiskerColor')).append(); 21068 // median line 21069 target.drawLine( 21070 Math.round((q2 - minValue) * unitSize + canvasLeft), 21071 Math.round(canvasHeight * 0.1), 21072 Math.round((q2 - minValue) * unitSize + canvasLeft), 21073 Math.round(canvasHeight * 0.9), 21074 options.get('medianColor')).append(); 21075 if (options.get('target')) { 21076 size = Math.ceil(options.get('spotRadius')); 21077 target.drawLine( 21078 Math.round((options.get('target') - minValue) * unitSize + canvasLeft), 21079 Math.round((canvasHeight / 2) - size), 21080 Math.round((options.get('target') - minValue) * unitSize + canvasLeft), 21081 Math.round((canvasHeight / 2) + size), 21082 options.get('targetColor')).append(); 21083 target.drawLine( 21084 Math.round((options.get('target') - minValue) * unitSize + canvasLeft - size), 21085 Math.round(canvasHeight / 2), 21086 Math.round((options.get('target') - minValue) * unitSize + canvasLeft + size), 21087 Math.round(canvasHeight / 2), 21088 options.get('targetColor')).append(); 21089 } 21090 target.render(); 21091 } 21092 }); 21093 21094 // Setup a very simple "virtual canvas" to make drawing the few shapes we need easier 21095 // This is accessible as $(foo).simpledraw() 21096 21097 VShape = createClass({ 21098 init: function (target, id, type, args) { 21099 this.target = target; 21100 this.id = id; 21101 this.type = type; 21102 this.args = args; 21103 }, 21104 append: function () { 21105 this.target.appendShape(this); 21106 return this; 21107 } 21108 }); 21109 21110 VCanvas_base = createClass({ 21111 _pxregex: /(\d+)(px)?\s*$/i, 21112 21113 init: function (width, height, target) { 21114 if (!width) { 21115 return; 21116 } 21117 this.width = width; 21118 this.height = height; 21119 this.target = target; 21120 this.lastShapeId = null; 21121 if (target[0]) { 21122 target = target[0]; 21123 } 21124 $.data(target, '_jqs_vcanvas', this); 21125 }, 21126 21127 drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) { 21128 return this.drawShape([[x1, y1], [x2, y2]], lineColor, lineWidth); 21129 }, 21130 21131 drawShape: function (path, lineColor, fillColor, lineWidth) { 21132 return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]); 21133 }, 21134 21135 drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) { 21136 return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]); 21137 }, 21138 21139 drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) { 21140 return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]); 21141 }, 21142 21143 drawRect: function (x, y, width, height, lineColor, fillColor) { 21144 return this._genShape('Rect', [x, y, width, height, lineColor, fillColor]); 21145 }, 21146 21147 getElement: function () { 21148 return this.canvas; 21149 }, 21150 21151 /** 21152 * Return the most recently inserted shape id 21153 */ 21154 getLastShapeId: function () { 21155 return this.lastShapeId; 21156 }, 21157 21158 /** 21159 * Clear and reset the canvas 21160 */ 21161 reset: function () { 21162 alert('reset not implemented'); 21163 }, 21164 21165 _insert: function (el, target) { 21166 $(target).html(el); 21167 }, 21168 21169 /** 21170 * Calculate the pixel dimensions of the canvas 21171 */ 21172 _calculatePixelDims: function (width, height, canvas) { 21173 // XXX This should probably be a configurable option 21174 var match; 21175 match = this._pxregex.exec(height); 21176 if (match) { 21177 this.pixelHeight = match[1]; 21178 } else { 21179 this.pixelHeight = $(canvas).height(); 21180 } 21181 match = this._pxregex.exec(width); 21182 if (match) { 21183 this.pixelWidth = match[1]; 21184 } else { 21185 this.pixelWidth = $(canvas).width(); 21186 } 21187 }, 21188 21189 /** 21190 * Generate a shape object and id for later rendering 21191 */ 21192 _genShape: function (shapetype, shapeargs) { 21193 var id = shapeCount++; 21194 shapeargs.unshift(id); 21195 return new VShape(this, id, shapetype, shapeargs); 21196 }, 21197 21198 /** 21199 * Add a shape to the end of the render queue 21200 */ 21201 appendShape: function (shape) { 21202 alert('appendShape not implemented'); 21203 }, 21204 21205 /** 21206 * Replace one shape with another 21207 */ 21208 replaceWithShape: function (shapeid, shape) { 21209 alert('replaceWithShape not implemented'); 21210 }, 21211 21212 /** 21213 * Insert one shape after another in the render queue 21214 */ 21215 insertAfterShape: function (shapeid, shape) { 21216 alert('insertAfterShape not implemented'); 21217 }, 21218 21219 /** 21220 * Remove a shape from the queue 21221 */ 21222 removeShapeId: function (shapeid) { 21223 alert('removeShapeId not implemented'); 21224 }, 21225 21226 /** 21227 * Find a shape at the specified x/y co-ordinates 21228 */ 21229 getShapeAt: function (el, x, y) { 21230 alert('getShapeAt not implemented'); 21231 }, 21232 21233 /** 21234 * Render all queued shapes onto the canvas 21235 */ 21236 render: function () { 21237 alert('render not implemented'); 21238 } 21239 }); 21240 21241 VCanvas_canvas = createClass(VCanvas_base, { 21242 init: function (width, height, target, interact) { 21243 VCanvas_canvas._super.init.call(this, width, height, target); 21244 this.canvas = document.createElement('canvas'); 21245 if (target[0]) { 21246 target = target[0]; 21247 } 21248 $.data(target, '_jqs_vcanvas', this); 21249 $(this.canvas).css({ display: 'inline-block', width: width, height: height, verticalAlign: 'top' }); 21250 this._insert(this.canvas, target); 21251 this._calculatePixelDims(width, height, this.canvas); 21252 this.canvas.width = this.pixelWidth; 21253 this.canvas.height = this.pixelHeight; 21254 this.interact = interact; 21255 this.shapes = {}; 21256 this.shapeseq = []; 21257 this.currentTargetShapeId = undefined; 21258 $(this.canvas).css({width: this.pixelWidth, height: this.pixelHeight}); 21259 }, 21260 21261 _getContext: function (lineColor, fillColor, lineWidth) { 21262 var context = this.canvas.getContext('2d'); 21263 if (lineColor !== undefined) { 21264 context.strokeStyle = lineColor; 21265 } 21266 context.lineWidth = lineWidth === undefined ? 1 : lineWidth; 21267 if (fillColor !== undefined) { 21268 context.fillStyle = fillColor; 21269 } 21270 return context; 21271 }, 21272 21273 reset: function () { 21274 var context = this._getContext(); 21275 context.clearRect(0, 0, this.pixelWidth, this.pixelHeight); 21276 this.shapes = {}; 21277 this.shapeseq = []; 21278 this.currentTargetShapeId = undefined; 21279 }, 21280 21281 _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) { 21282 var context = this._getContext(lineColor, fillColor, lineWidth), 21283 i, plen; 21284 context.beginPath(); 21285 context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5); 21286 for (i = 1, plen = path.length; i < plen; i++) { 21287 context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); // the 0.5 offset gives us crisp pixel-width lines 21288 } 21289 if (lineColor !== undefined) { 21290 context.stroke(); 21291 } 21292 if (fillColor !== undefined) { 21293 context.fill(); 21294 } 21295 if (this.targetX !== undefined && this.targetY !== undefined && 21296 context.isPointInPath(this.targetX, this.targetY)) { 21297 this.currentTargetShapeId = shapeid; 21298 } 21299 }, 21300 21301 _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) { 21302 var context = this._getContext(lineColor, fillColor, lineWidth); 21303 context.beginPath(); 21304 context.arc(x, y, radius, 0, 2 * Math.PI, false); 21305 if (this.targetX !== undefined && this.targetY !== undefined && 21306 context.isPointInPath(this.targetX, this.targetY)) { 21307 this.currentTargetShapeId = shapeid; 21308 } 21309 if (lineColor !== undefined) { 21310 context.stroke(); 21311 } 21312 if (fillColor !== undefined) { 21313 context.fill(); 21314 } 21315 }, 21316 21317 _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { 21318 var context = this._getContext(lineColor, fillColor); 21319 context.beginPath(); 21320 context.moveTo(x, y); 21321 context.arc(x, y, radius, startAngle, endAngle, false); 21322 context.lineTo(x, y); 21323 context.closePath(); 21324 if (lineColor !== undefined) { 21325 context.stroke(); 21326 } 21327 if (fillColor) { 21328 context.fill(); 21329 } 21330 if (this.targetX !== undefined && this.targetY !== undefined && 21331 context.isPointInPath(this.targetX, this.targetY)) { 21332 this.currentTargetShapeId = shapeid; 21333 } 21334 }, 21335 21336 _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) { 21337 return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor); 21338 }, 21339 21340 appendShape: function (shape) { 21341 this.shapes[shape.id] = shape; 21342 this.shapeseq.push(shape.id); 21343 this.lastShapeId = shape.id; 21344 return shape.id; 21345 }, 21346 21347 replaceWithShape: function (shapeid, shape) { 21348 var shapeseq = this.shapeseq, 21349 i; 21350 this.shapes[shape.id] = shape; 21351 for (i = shapeseq.length; i--;) { 21352 if (shapeseq[i] == shapeid) { 21353 shapeseq[i] = shape.id; 21354 } 21355 } 21356 delete this.shapes[shapeid]; 21357 }, 21358 21359 replaceWithShapes: function (shapeids, shapes) { 21360 var shapeseq = this.shapeseq, 21361 shapemap = {}, 21362 sid, i, first; 21363 21364 for (i = shapeids.length; i--;) { 21365 shapemap[shapeids[i]] = true; 21366 } 21367 for (i = shapeseq.length; i--;) { 21368 sid = shapeseq[i]; 21369 if (shapemap[sid]) { 21370 shapeseq.splice(i, 1); 21371 delete this.shapes[sid]; 21372 first = i; 21373 } 21374 } 21375 for (i = shapes.length; i--;) { 21376 shapeseq.splice(first, 0, shapes[i].id); 21377 this.shapes[shapes[i].id] = shapes[i]; 21378 } 21379 21380 }, 21381 21382 insertAfterShape: function (shapeid, shape) { 21383 var shapeseq = this.shapeseq, 21384 i; 21385 for (i = shapeseq.length; i--;) { 21386 if (shapeseq[i] === shapeid) { 21387 shapeseq.splice(i + 1, 0, shape.id); 21388 this.shapes[shape.id] = shape; 21389 return; 21390 } 21391 } 21392 }, 21393 21394 removeShapeId: function (shapeid) { 21395 var shapeseq = this.shapeseq, 21396 i; 21397 for (i = shapeseq.length; i--;) { 21398 if (shapeseq[i] === shapeid) { 21399 shapeseq.splice(i, 1); 21400 break; 21401 } 21402 } 21403 delete this.shapes[shapeid]; 21404 }, 21405 21406 getShapeAt: function (el, x, y) { 21407 this.targetX = x; 21408 this.targetY = y; 21409 this.render(); 21410 return this.currentTargetShapeId; 21411 }, 21412 21413 render: function () { 21414 var shapeseq = this.shapeseq, 21415 shapes = this.shapes, 21416 shapeCount = shapeseq.length, 21417 context = this._getContext(), 21418 shapeid, shape, i; 21419 context.clearRect(0, 0, this.pixelWidth, this.pixelHeight); 21420 for (i = 0; i < shapeCount; i++) { 21421 shapeid = shapeseq[i]; 21422 shape = shapes[shapeid]; 21423 this['_draw' + shape.type].apply(this, shape.args); 21424 } 21425 if (!this.interact) { 21426 // not interactive so no need to keep the shapes array 21427 this.shapes = {}; 21428 this.shapeseq = []; 21429 } 21430 } 21431 21432 }); 21433 21434 VCanvas_vml = createClass(VCanvas_base, { 21435 init: function (width, height, target) { 21436 var groupel; 21437 VCanvas_vml._super.init.call(this, width, height, target); 21438 if (target[0]) { 21439 target = target[0]; 21440 } 21441 $.data(target, '_jqs_vcanvas', this); 21442 this.canvas = document.createElement('span'); 21443 $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'}); 21444 this._insert(this.canvas, target); 21445 this._calculatePixelDims(width, height, this.canvas); 21446 this.canvas.width = this.pixelWidth; 21447 this.canvas.height = this.pixelHeight; 21448 groupel = '<v:group coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '"' + 21449 ' style="position:absolute;top:0;left:0;width:' + this.pixelWidth + 'px;height=' + this.pixelHeight + 'px;"></v:group>'; 21450 this.canvas.insertAdjacentHTML('beforeEnd', groupel); 21451 this.group = $(this.canvas).children()[0]; 21452 this.rendered = false; 21453 this.prerender = ''; 21454 }, 21455 21456 _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) { 21457 var vpath = [], 21458 initial, stroke, fill, closed, vel, plen, i; 21459 for (i = 0, plen = path.length; i < plen; i++) { 21460 vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]); 21461 } 21462 initial = vpath.splice(0, 1); 21463 lineWidth = lineWidth === undefined ? 1 : lineWidth; 21464 stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; 21465 fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; 21466 closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : ''; 21467 vel = '<v:shape coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '" ' + 21468 ' id="jqsshape' + shapeid + '" ' + 21469 stroke + 21470 fill + 21471 ' style="position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;" ' + 21472 ' path="m ' + initial + ' l ' + vpath.join(', ') + ' ' + closed + 'e">' + 21473 ' </v:shape>'; 21474 return vel; 21475 }, 21476 21477 _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) { 21478 var stroke, fill, vel; 21479 x -= radius; 21480 y -= radius; 21481 stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; 21482 fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; 21483 vel = '<v:oval ' + 21484 ' id="jqsshape' + shapeid + '" ' + 21485 stroke + 21486 fill + 21487 ' style="position:absolute;top:' + y + 'px; left:' + x + 'px; width:' + (radius * 2) + 'px; height:' + (radius * 2) + 'px"></v:oval>'; 21488 return vel; 21489 21490 }, 21491 21492 _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { 21493 var vpath, startx, starty, endx, endy, stroke, fill, vel; 21494 if (startAngle === endAngle) { 21495 return ''; // VML seems to have problem when start angle equals end angle. 21496 } 21497 if ((endAngle - startAngle) === (2 * Math.PI)) { 21498 startAngle = 0.0; // VML seems to have a problem when drawing a full circle that doesn't start 0 21499 endAngle = (2 * Math.PI); 21500 } 21501 21502 startx = x + Math.round(Math.cos(startAngle) * radius); 21503 starty = y + Math.round(Math.sin(startAngle) * radius); 21504 endx = x + Math.round(Math.cos(endAngle) * radius); 21505 endy = y + Math.round(Math.sin(endAngle) * radius); 21506 21507 if (startx === endx && starty === endy) { 21508 if ((endAngle - startAngle) < Math.PI) { 21509 // Prevent very small slices from being mistaken as a whole pie 21510 return ''; 21511 } 21512 // essentially going to be the entire circle, so ignore startAngle 21513 startx = endx = x + radius; 21514 starty = endy = y; 21515 } 21516 21517 if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) { 21518 return ''; 21519 } 21520 21521 vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy]; 21522 stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" '; 21523 fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; 21524 vel = '<v:shape coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '" ' + 21525 ' id="jqsshape' + shapeid + '" ' + 21526 stroke + 21527 fill + 21528 ' style="position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;" ' + 21529 ' path="m ' + x + ',' + y + ' wa ' + vpath.join(', ') + ' x e">' + 21530 ' </v:shape>'; 21531 return vel; 21532 }, 21533 21534 _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) { 21535 return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor); 21536 }, 21537 21538 reset: function () { 21539 this.group.innerHTML = ''; 21540 }, 21541 21542 appendShape: function (shape) { 21543 var vel = this['_draw' + shape.type].apply(this, shape.args); 21544 if (this.rendered) { 21545 this.group.insertAdjacentHTML('beforeEnd', vel); 21546 } else { 21547 this.prerender += vel; 21548 } 21549 this.lastShapeId = shape.id; 21550 return shape.id; 21551 }, 21552 21553 replaceWithShape: function (shapeid, shape) { 21554 var existing = $('#jqsshape' + shapeid), 21555 vel = this['_draw' + shape.type].apply(this, shape.args); 21556 existing[0].outerHTML = vel; 21557 }, 21558 21559 replaceWithShapes: function (shapeids, shapes) { 21560 // replace the first shapeid with all the new shapes then toast the remaining old shapes 21561 var existing = $('#jqsshape' + shapeids[0]), 21562 replace = '', 21563 slen = shapes.length, 21564 i; 21565 for (i = 0; i < slen; i++) { 21566 replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args); 21567 } 21568 existing[0].outerHTML = replace; 21569 for (i = 1; i < shapeids.length; i++) { 21570 $('#jqsshape' + shapeids[i]).remove(); 21571 } 21572 }, 21573 21574 insertAfterShape: function (shapeid, shape) { 21575 var existing = $('#jqsshape' + shapeid), 21576 vel = this['_draw' + shape.type].apply(this, shape.args); 21577 existing[0].insertAdjacentHTML('afterEnd', vel); 21578 }, 21579 21580 removeShapeId: function (shapeid) { 21581 var existing = $('#jqsshape' + shapeid); 21582 this.group.removeChild(existing[0]); 21583 }, 21584 21585 getShapeAt: function (el, x, y) { 21586 var shapeid = el.id.substr(8); 21587 return shapeid; 21588 }, 21589 21590 render: function () { 21591 if (!this.rendered) { 21592 // batch the intial render into a single repaint 21593 this.group.innerHTML = this.prerender; 21594 this.rendered = true; 21595 } 21596 } 21597 }); 21598 21599}))}(document, Math));
vendor: 1,088 bytes, lines 21600-21611
21600 21601;/*! 21602 * Chart.js 21603 * http://chartjs.org/ 21604 * Version: 2.7.2 21605 * 21606 * Copyright 2018 Chart.js Contributors 21607 * Released under the MIT license 21608 * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md 21609 */ 21610(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){ 21611/* MIT license */
vendor: 17,840 bytes, lines 21612-22359
21612var colorNames = require(5); 21613 21614module.exports = { 21615 getRgba: getRgba, 21616 getHsla: getHsla, 21617 getRgb: getRgb, 21618 getHsl: getHsl, 21619 getHwb: getHwb, 21620 getAlpha: getAlpha, 21621 21622 hexString: hexString, 21623 rgbString: rgbString, 21624 rgbaString: rgbaString, 21625 percentString: percentString, 21626 percentaString: percentaString, 21627 hslString: hslString, 21628 hslaString: hslaString, 21629 hwbString: hwbString, 21630 keyword: keyword 21631} 21632 21633function getRgba(string) { 21634 if (!string) { 21635 return; 21636 } 21637 var abbr = /^#([a-fA-F0-9]{3})$/i, 21638 hex = /^#([a-fA-F0-9]{6})$/i, 21639 rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, 21640 per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, 21641 keyword = /(\w+)/; 21642 21643 var rgb = [0, 0, 0], 21644 a = 1, 21645 match = string.match(abbr); 21646 if (match) { 21647 match = match[1]; 21648 for (var i = 0; i < rgb.length; i++) { 21649 rgb[i] = parseInt(match[i] + match[i], 16); 21650 } 21651 } 21652 else if (match = string.match(hex)) { 21653 match = match[1]; 21654 for (var i = 0; i < rgb.length; i++) { 21655 rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16); 21656 } 21657 } 21658 else if (match = string.match(rgba)) { 21659 for (var i = 0; i < rgb.length; i++) { 21660 rgb[i] = parseInt(match[i + 1]); 21661 } 21662 a = parseFloat(match[4]); 21663 } 21664 else if (match = string.match(per)) { 21665 for (var i = 0; i < rgb.length; i++) { 21666 rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55); 21667 } 21668 a = parseFloat(match[4]); 21669 } 21670 else if (match = string.match(keyword)) { 21671 if (match[1] == "transparent") { 21672 return [0, 0, 0, 0]; 21673 } 21674 rgb = colorNames[match[1]]; 21675 if (!rgb) { 21676 return; 21677 } 21678 } 21679 21680 for (var i = 0; i < rgb.length; i++) { 21681 rgb[i] = scale(rgb[i], 0, 255); 21682 } 21683 if (!a && a != 0) { 21684 a = 1; 21685 } 21686 else { 21687 a = scale(a, 0, 1); 21688 } 21689 rgb[3] = a; 21690 return rgb; 21691} 21692 21693function getHsla(string) { 21694 if (!string) { 21695 return; 21696 } 21697 var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; 21698 var match = string.match(hsl); 21699 if (match) { 21700 var alpha = parseFloat(match[4]); 21701 var h = scale(parseInt(match[1]), 0, 360), 21702 s = scale(parseFloat(match[2]), 0, 100), 21703 l = scale(parseFloat(match[3]), 0, 100), 21704 a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); 21705 return [h, s, l, a]; 21706 } 21707} 21708 21709function getHwb(string) { 21710 if (!string) { 21711 return; 21712 } 21713 var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; 21714 var match = string.match(hwb); 21715 if (match) { 21716 var alpha = parseFloat(match[4]); 21717 var h = scale(parseInt(match[1]), 0, 360), 21718 w = scale(parseFloat(match[2]), 0, 100), 21719 b = scale(parseFloat(match[3]), 0, 100), 21720 a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); 21721 return [h, w, b, a]; 21722 } 21723} 21724 21725function getRgb(string) { 21726 var rgba = getRgba(string); 21727 return rgba && rgba.slice(0, 3); 21728} 21729 21730function getHsl(string) { 21731 var hsla = getHsla(string); 21732 return hsla && hsla.slice(0, 3); 21733} 21734 21735function getAlpha(string) { 21736 var vals = getRgba(string); 21737 if (vals) { 21738 return vals[3]; 21739 } 21740 else if (vals = getHsla(string)) { 21741 return vals[3]; 21742 } 21743 else if (vals = getHwb(string)) { 21744 return vals[3]; 21745 } 21746} 21747 21748// generators 21749function hexString(rgb) { 21750 return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1]) 21751 + hexDouble(rgb[2]); 21752} 21753 21754function rgbString(rgba, alpha) { 21755 if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { 21756 return rgbaString(rgba, alpha); 21757 } 21758 return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")"; 21759} 21760 21761function rgbaString(rgba, alpha) { 21762 if (alpha === undefined) { 21763 alpha = (rgba[3] !== undefined ? rgba[3] : 1); 21764 } 21765 return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] 21766 + ", " + alpha + ")"; 21767} 21768 21769function percentString(rgba, alpha) { 21770 if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { 21771 return percentaString(rgba, alpha); 21772 } 21773 var r = Math.round(rgba[0]/255 * 100), 21774 g = Math.round(rgba[1]/255 * 100), 21775 b = Math.round(rgba[2]/255 * 100); 21776 21777 return "rgb(" + r + "%, " + g + "%, " + b + "%)"; 21778} 21779 21780function percentaString(rgba, alpha) { 21781 var r = Math.round(rgba[0]/255 * 100), 21782 g = Math.round(rgba[1]/255 * 100), 21783 b = Math.round(rgba[2]/255 * 100); 21784 return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")"; 21785} 21786 21787function hslString(hsla, alpha) { 21788 if (alpha < 1 || (hsla[3] && hsla[3] < 1)) { 21789 return hslaString(hsla, alpha); 21790 } 21791 return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)"; 21792} 21793 21794function hslaString(hsla, alpha) { 21795 if (alpha === undefined) { 21796 alpha = (hsla[3] !== undefined ? hsla[3] : 1); 21797 } 21798 return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " 21799 + alpha + ")"; 21800} 21801 21802// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax 21803// (hwb have alpha optional & 1 is default value) 21804function hwbString(hwb, alpha) { 21805 if (alpha === undefined) { 21806 alpha = (hwb[3] !== undefined ? hwb[3] : 1); 21807 } 21808 return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%" 21809 + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")"; 21810} 21811 21812function keyword(rgb) { 21813 return reverseNames[rgb.slice(0, 3)]; 21814} 21815 21816// helpers 21817function scale(num, min, max) { 21818 return Math.min(Math.max(min, num), max); 21819} 21820 21821function hexDouble(num) { 21822 var str = num.toString(16).toUpperCase(); 21823 return (str.length < 2) ? "0" + str : str; 21824} 21825 21826 21827//create a list of reverse color names 21828var reverseNames = {}; 21829for (var name in colorNames) { 21830 reverseNames[colorNames[name]] = name; 21831} 21832 21833},{"5":5}],2:[function(require,module,exports){ 21834/* MIT license */ 21835var convert = require(4); 21836var string = require(1); 21837 21838var Color = function (obj) { 21839 if (obj instanceof Color) { 21840 return obj; 21841 } 21842 if (!(this instanceof Color)) { 21843 return new Color(obj); 21844 } 21845 21846 this.valid = false; 21847 this.values = { 21848 rgb: [0, 0, 0], 21849 hsl: [0, 0, 0], 21850 hsv: [0, 0, 0], 21851 hwb: [0, 0, 0], 21852 cmyk: [0, 0, 0, 0], 21853 alpha: 1 21854 }; 21855 21856 // parse Color() argument 21857 var vals; 21858 if (typeof obj === 'string') { 21859 vals = string.getRgba(obj); 21860 if (vals) { 21861 this.setValues('rgb', vals); 21862 } else if (vals = string.getHsla(obj)) { 21863 this.setValues('hsl', vals); 21864 } else if (vals = string.getHwb(obj)) { 21865 this.setValues('hwb', vals); 21866 } 21867 } else if (typeof obj === 'object') { 21868 vals = obj; 21869 if (vals.r !== undefined || vals.red !== undefined) { 21870 this.setValues('rgb', vals); 21871 } else if (vals.l !== undefined || vals.lightness !== undefined) { 21872 this.setValues('hsl', vals); 21873 } else if (vals.v !== undefined || vals.value !== undefined) { 21874 this.setValues('hsv', vals); 21875 } else if (vals.w !== undefined || vals.whiteness !== undefined) { 21876 this.setValues('hwb', vals); 21877 } else if (vals.c !== undefined || vals.cyan !== undefined) { 21878 this.setValues('cmyk', vals); 21879 } 21880 } 21881}; 21882 21883Color.prototype = { 21884 isValid: function () { 21885 return this.valid; 21886 }, 21887 rgb: function () { 21888 return this.setSpace('rgb', arguments); 21889 }, 21890 hsl: function () { 21891 return this.setSpace('hsl', arguments); 21892 }, 21893 hsv: function () { 21894 return this.setSpace('hsv', arguments); 21895 }, 21896 hwb: function () { 21897 return this.setSpace('hwb', arguments); 21898 }, 21899 cmyk: function () { 21900 return this.setSpace('cmyk', arguments); 21901 }, 21902 21903 rgbArray: function () { 21904 return this.values.rgb; 21905 }, 21906 hslArray: function () { 21907 return this.values.hsl; 21908 }, 21909 hsvArray: function () { 21910 return this.values.hsv; 21911 }, 21912 hwbArray: function () { 21913 var values = this.values; 21914 if (values.alpha !== 1) { 21915 return values.hwb.concat([values.alpha]); 21916 } 21917 return values.hwb; 21918 }, 21919 cmykArray: function () { 21920 return this.values.cmyk; 21921 }, 21922 rgbaArray: function () { 21923 var values = this.values; 21924 return values.rgb.concat([values.alpha]); 21925 }, 21926 hslaArray: function () { 21927 var values = this.values; 21928 return values.hsl.concat([values.alpha]); 21929 }, 21930 alpha: function (val) { 21931 if (val === undefined) { 21932 return this.values.alpha; 21933 } 21934 this.setValues('alpha', val); 21935 return this; 21936 }, 21937 21938 red: function (val) { 21939 return this.setChannel('rgb', 0, val); 21940 }, 21941 green: function (val) { 21942 return this.setChannel('rgb', 1, val); 21943 }, 21944 blue: function (val) { 21945 return this.setChannel('rgb', 2, val); 21946 }, 21947 hue: function (val) { 21948 if (val) { 21949 val %= 360; 21950 val = val < 0 ? 360 + val : val; 21951 } 21952 return this.setChannel('hsl', 0, val); 21953 }, 21954 saturation: function (val) { 21955 return this.setChannel('hsl', 1, val); 21956 }, 21957 lightness: function (val) { 21958 return this.setChannel('hsl', 2, val); 21959 }, 21960 saturationv: function (val) { 21961 return this.setChannel('hsv', 1, val); 21962 }, 21963 whiteness: function (val) { 21964 return this.setChannel('hwb', 1, val); 21965 }, 21966 blackness: function (val) { 21967 return this.setChannel('hwb', 2, val); 21968 }, 21969 value: function (val) { 21970 return this.setChannel('hsv', 2, val); 21971 }, 21972 cyan: function (val) { 21973 return this.setChannel('cmyk', 0, val); 21974 }, 21975 magenta: function (val) { 21976 return this.setChannel('cmyk', 1, val); 21977 }, 21978 yellow: function (val) { 21979 return this.setChannel('cmyk', 2, val); 21980 }, 21981 black: function (val) { 21982 return this.setChannel('cmyk', 3, val); 21983 }, 21984 21985 hexString: function () { 21986 return string.hexString(this.values.rgb); 21987 }, 21988 rgbString: function () { 21989 return string.rgbString(this.values.rgb, this.values.alpha); 21990 }, 21991 rgbaString: function () { 21992 return string.rgbaString(this.values.rgb, this.values.alpha); 21993 }, 21994 percentString: function () { 21995 return string.percentString(this.values.rgb, this.values.alpha); 21996 }, 21997 hslString: function () { 21998 return string.hslString(this.values.hsl, this.values.alpha); 21999 }, 22000 hslaString: function () { 22001 return string.hslaString(this.values.hsl, this.values.alpha); 22002 }, 22003 hwbString: function () { 22004 return string.hwbString(this.values.hwb, this.values.alpha); 22005 }, 22006 keyword: function () { 22007 return string.keyword(this.values.rgb, this.values.alpha); 22008 }, 22009 22010 rgbNumber: function () { 22011 var rgb = this.values.rgb; 22012 return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; 22013 }, 22014 22015 luminosity: function () { 22016 // http://www.w3.org/TR/WCAG20/#relativeluminancedef 22017 var rgb = this.values.rgb; 22018 var lum = []; 22019 for (var i = 0; i < rgb.length; i++) { 22020 var chan = rgb[i] / 255; 22021 lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); 22022 } 22023 return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; 22024 }, 22025 22026 contrast: function (color2) { 22027 // http://www.w3.org/TR/WCAG20/#contrast-ratiodef 22028 var lum1 = this.luminosity(); 22029 var lum2 = color2.luminosity(); 22030 if (lum1 > lum2) { 22031 return (lum1 + 0.05) / (lum2 + 0.05); 22032 } 22033 return (lum2 + 0.05) / (lum1 + 0.05); 22034 }, 22035 22036 level: function (color2) { 22037 var contrastRatio = this.contrast(color2); 22038 if (contrastRatio >= 7.1) { 22039 return 'AAA'; 22040 } 22041 22042 return (contrastRatio >= 4.5) ? 'AA' : ''; 22043 }, 22044 22045 dark: function () { 22046 // YIQ equation from http://24ways.org/2010/calculating-color-contrast 22047 var rgb = this.values.rgb; 22048 var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; 22049 return yiq < 128; 22050 }, 22051 22052 light: function () { 22053 return !this.dark(); 22054 }, 22055 22056 negate: function () { 22057 var rgb = []; 22058 for (var i = 0; i < 3; i++) { 22059 rgb[i] = 255 - this.values.rgb[i]; 22060 } 22061 this.setValues('rgb', rgb); 22062 return this; 22063 }, 22064 22065 lighten: function (ratio) { 22066 var hsl = this.values.hsl; 22067 hsl[2] += hsl[2] * ratio; 22068 this.setValues('hsl', hsl); 22069 return this; 22070 }, 22071 22072 darken: function (ratio) { 22073 var hsl = this.values.hsl; 22074 hsl[2] -= hsl[2] * ratio; 22075 this.setValues('hsl', hsl); 22076 return this; 22077 }, 22078 22079 saturate: function (ratio) { 22080 var hsl = this.values.hsl; 22081 hsl[1] += hsl[1] * ratio; 22082 this.setValues('hsl', hsl); 22083 return this; 22084 }, 22085 22086 desaturate: function (ratio) { 22087 var hsl = this.values.hsl; 22088 hsl[1] -= hsl[1] * ratio; 22089 this.setValues('hsl', hsl); 22090 return this; 22091 }, 22092 22093 whiten: function (ratio) { 22094 var hwb = this.values.hwb; 22095 hwb[1] += hwb[1] * ratio; 22096 this.setValues('hwb', hwb); 22097 return this; 22098 }, 22099 22100 blacken: function (ratio) { 22101 var hwb = this.values.hwb; 22102 hwb[2] += hwb[2] * ratio; 22103 this.setValues('hwb', hwb); 22104 return this; 22105 }, 22106 22107 greyscale: function () { 22108 var rgb = this.values.rgb; 22109 // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale 22110 var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; 22111 this.setValues('rgb', [val, val, val]); 22112 return this; 22113 }, 22114 22115 clearer: function (ratio) { 22116 var alpha = this.values.alpha; 22117 this.setValues('alpha', alpha - (alpha * ratio)); 22118 return this; 22119 }, 22120 22121 opaquer: function (ratio) { 22122 var alpha = this.values.alpha; 22123 this.setValues('alpha', alpha + (alpha * ratio)); 22124 return this; 22125 }, 22126 22127 rotate: function (degrees) { 22128 var hsl = this.values.hsl; 22129 var hue = (hsl[0] + degrees) % 360; 22130 hsl[0] = hue < 0 ? 360 + hue : hue; 22131 this.setValues('hsl', hsl); 22132 return this; 22133 }, 22134 22135 /** 22136 * Ported from sass implementation in C 22137 * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 22138 */ 22139 mix: function (mixinColor, weight) { 22140 var color1 = this; 22141 var color2 = mixinColor; 22142 var p = weight === undefined ? 0.5 : weight; 22143 22144 var w = 2 * p - 1; 22145 var a = color1.alpha() - color2.alpha(); 22146 22147 var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; 22148 var w2 = 1 - w1; 22149 22150 return this 22151 .rgb( 22152 w1 * color1.red() + w2 * color2.red(), 22153 w1 * color1.green() + w2 * color2.green(), 22154 w1 * color1.blue() + w2 * color2.blue() 22155 ) 22156 .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); 22157 }, 22158 22159 toJSON: function () { 22160 return this.rgb(); 22161 }, 22162 22163 clone: function () { 22164 // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, 22165 // making the final build way to big to embed in Chart.js. So let's do it manually, 22166 // assuming that values to clone are 1 dimension arrays containing only numbers, 22167 // except 'alpha' which is a number. 22168 var result = new Color(); 22169 var source = this.values; 22170 var target = result.values; 22171 var value, type; 22172 22173 for (var prop in source) { 22174 if (source.hasOwnProperty(prop)) { 22175 value = source[prop]; 22176 type = ({}).toString.call(value); 22177 if (type === '[object Array]') { 22178 target[prop] = value.slice(0); 22179 } else if (type === '[object Number]') { 22180 target[prop] = value; 22181 } else { 22182 console.error('unexpected color value:', value); 22183 } 22184 } 22185 } 22186 22187 return result; 22188 } 22189}; 22190 22191Color.prototype.spaces = { 22192 rgb: ['red', 'green', 'blue'], 22193 hsl: ['hue', 'saturation', 'lightness'], 22194 hsv: ['hue', 'saturation', 'value'], 22195 hwb: ['hue', 'whiteness', 'blackness'], 22196 cmyk: ['cyan', 'magenta', 'yellow', 'black'] 22197}; 22198 22199Color.prototype.maxes = { 22200 rgb: [255, 255, 255], 22201 hsl: [360, 100, 100], 22202 hsv: [360, 100, 100], 22203 hwb: [360, 100, 100], 22204 cmyk: [100, 100, 100, 100] 22205}; 22206 22207Color.prototype.getValues = function (space) { 22208 var values = this.values; 22209 var vals = {}; 22210 22211 for (var i = 0; i < space.length; i++) { 22212 vals[space.charAt(i)] = values[space][i]; 22213 } 22214 22215 if (values.alpha !== 1) { 22216 vals.a = values.alpha; 22217 } 22218 22219 // {r: 255, g: 255, b: 255, a: 0.4} 22220 return vals; 22221}; 22222 22223Color.prototype.setValues = function (space, vals) { 22224 var values = this.values; 22225 var spaces = this.spaces; 22226 var maxes = this.maxes; 22227 var alpha = 1; 22228 var i; 22229 22230 this.valid = true; 22231 22232 if (space === 'alpha') { 22233 alpha = vals; 22234 } else if (vals.length) { 22235 // [10, 10, 10] 22236 values[space] = vals.slice(0, space.length); 22237 alpha = vals[space.length]; 22238 } else if (vals[space.charAt(0)] !== undefined) { 22239 // {r: 10, g: 10, b: 10} 22240 for (i = 0; i < space.length; i++) { 22241 values[space][i] = vals[space.charAt(i)]; 22242 } 22243 22244 alpha = vals.a; 22245 } else if (vals[spaces[space][0]] !== undefined) { 22246 // {red: 10, green: 10, blue: 10} 22247 var chans = spaces[space]; 22248 22249 for (i = 0; i < space.length; i++) { 22250 values[space][i] = vals[chans[i]]; 22251 } 22252 22253 alpha = vals.alpha; 22254 } 22255 22256 values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); 22257 22258 if (space === 'alpha') { 22259 return false; 22260 } 22261 22262 var capped; 22263 22264 // cap values of the space prior converting all values 22265 for (i = 0; i < space.length; i++) { 22266 capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); 22267 values[space][i] = Math.round(capped); 22268 } 22269 22270 // convert to all the other color spaces 22271 for (var sname in spaces) { 22272 if (sname !== space) { 22273 values[sname] = convert[space][sname](values[space]); 22274 } 22275 } 22276 22277 return true; 22278}; 22279 22280Color.prototype.setSpace = function (space, args) { 22281 var vals = args[0]; 22282 22283 if (vals === undefined) { 22284 // color.rgb() 22285 return this.getValues(space); 22286 } 22287 22288 // color.rgb(10, 10, 10) 22289 if (typeof vals === 'number') { 22290 vals = Array.prototype.slice.call(args); 22291 } 22292 22293 this.setValues(space, vals); 22294 return this; 22295}; 22296 22297Color.prototype.setChannel = function (space, index, val) { 22298 var svalues = this.values[space]; 22299 if (val === undefined) { 22300 // color.red() 22301 return svalues[index]; 22302 } else if (val === svalues[index]) { 22303 // color.red(color.red()) 22304 return this; 22305 } 22306 22307 // color.red(100) 22308 svalues[index] = val; 22309 this.setValues(space, svalues); 22310 22311 return this; 22312}; 22313 22314if (typeof window !== 'undefined') { 22315 window.Color = Color; 22316} 22317 22318module.exports = Color; 22319 22320},{"1":1,"4":4}],3:[function(require,module,exports){ 22321/* MIT license */ 22322 22323module.exports = { 22324 rgb2hsl: rgb2hsl, 22325 rgb2hsv: rgb2hsv, 22326 rgb2hwb: rgb2hwb, 22327 rgb2cmyk: rgb2cmyk, 22328 rgb2keyword: rgb2keyword, 22329 rgb2xyz: rgb2xyz, 22330 rgb2lab: rgb2lab, 22331 rgb2lch: rgb2lch, 22332 22333 hsl2rgb: hsl2rgb, 22334 hsl2hsv: hsl2hsv, 22335 hsl2hwb: hsl2hwb, 22336 hsl2cmyk: hsl2cmyk, 22337 hsl2keyword: hsl2keyword, 22338 22339 hsv2rgb: hsv2rgb, 22340 hsv2hsl: hsv2hsl, 22341 hsv2hwb: hsv2hwb, 22342 hsv2cmyk: hsv2cmyk, 22343 hsv2keyword: hsv2keyword, 22344 22345 hwb2rgb: hwb2rgb, 22346 hwb2hsl: hwb2hsl, 22347 hwb2hsv: hwb2hsv, 22348 hwb2cmyk: hwb2cmyk, 22349 hwb2keyword: hwb2keyword, 22350 22351 cmyk2rgb: cmyk2rgb, 22352 cmyk2hsl: cmyk2hsl, 22353 cmyk2hsv: cmyk2hsv, 22354 cmyk2hwb: cmyk2hwb, 22355 cmyk2keyword: cmyk2keyword, 22356 22357 keyword2rgb: keyword2rgb, 22358 keyword2hsl: keyword2hsl, 22359 keyword2hsv: keyword2hsv,
22360 keyword2hwb: keyword2hwb, 22361 keyword2cmyk: keyword2cmyk, 22362 keyword2lab: keyword2lab, 22363 keyword2xyz: keyword2xyz, 22364 22365 xyz2rgb: xyz2rgb, 22366 xyz2lab: xyz2lab, 22367 xyz2lch: xyz2lch, 22368 22369 lab2xyz: lab2xyz, 22370 lab2rgb: lab2rgb, 22371 lab2lch: lab2lch, 22372 22373 lch2lab: lch2lab, 22374 lch2xyz: lch2xyz, 22375 lch2rgb: lch2rgb 22376} 22377 22378 22379function rgb2hsl(rgb) { 22380 var r = rgb[0]/255, 22381 g = rgb[1]/255, 22382 b = rgb[2]/255, 22383 min = Math.min(r, g, b), 22384 max = Math.max(r, g, b), 22385 delta = max - min, 22386 h, s, l; 22387 22388 if (max == min) 22389 h = 0; 22390 else if (r == max) 22391 h = (g - b) / delta; 22392 else if (g == max) 22393 h = 2 + (b - r) / delta; 22394 else if (b == max) 22395 h = 4 + (r - g)/ delta; 22396 22397 h = Math.min(h * 60, 360); 22398 22399 if (h < 0) 22400 h += 360; 22401 22402 l = (min + max) / 2; 22403 22404 if (max == min) 22405 s = 0; 22406 else if (l <= 0.5) 22407 s = delta / (max + min); 22408 else 22409 s = delta / (2 - max - min); 22410 22411 return [h, s * 100, l * 100]; 22412} 22413 22414function rgb2hsv(rgb) { 22415 var r = rgb[0], 22416 g = rgb[1], 22417 b = rgb[2], 22418 min = Math.min(r, g, b), 22419 max = Math.max(r, g, b), 22420 delta = max - min, 22421 h, s, v; 22422 22423 if (max == 0) 22424 s = 0; 22425 else 22426 s = (delta/max * 1000)/10; 22427 22428 if (max == min) 22429 h = 0; 22430 else if (r == max) 22431 h = (g - b) / delta; 22432 else if (g == max) 22433 h = 2 + (b - r) / delta; 22434 else if (b == max) 22435 h = 4 + (r - g) / delta; 22436 22437 h = Math.min(h * 60, 360); 22438 22439 if (h < 0) 22440 h += 360; 22441 22442 v = ((max / 255) * 1000) / 10; 22443 22444 return [h, s, v]; 22445} 22446 22447function rgb2hwb(rgb) { 22448 var r = rgb[0], 22449 g = rgb[1], 22450 b = rgb[2], 22451 h = rgb2hsl(rgb)[0], 22452 w = 1/255 * Math.min(r, Math.min(g, b)), 22453 b = 1 - 1/255 * Math.max(r, Math.max(g, b)); 22454 22455 return [h, w * 100, b * 100]; 22456} 22457 22458function rgb2cmyk(rgb) { 22459 var r = rgb[0] / 255, 22460 g = rgb[1] / 255, 22461 b = rgb[2] / 255, 22462 c, m, y, k; 22463 22464 k = Math.min(1 - r, 1 - g, 1 - b); 22465 c = (1 - r - k) / (1 - k) || 0; 22466 m = (1 - g - k) / (1 - k) || 0; 22467 y = (1 - b - k) / (1 - k) || 0; 22468 return [c * 100, m * 100, y * 100, k * 100]; 22469} 22470 22471function rgb2keyword(rgb) { 22472 return reverseKeywords[JSON.stringify(rgb)]; 22473} 22474 22475function rgb2xyz(rgb) { 22476 var r = rgb[0] / 255, 22477 g = rgb[1] / 255, 22478 b = rgb[2] / 255; 22479 22480 // assume sRGB 22481 r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); 22482 g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); 22483 b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); 22484 22485 var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); 22486 var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); 22487 var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); 22488 22489 return [x * 100, y *100, z * 100]; 22490} 22491 22492function rgb2lab(rgb) { 22493 var xyz = rgb2xyz(rgb), 22494 x = xyz[0], 22495 y = xyz[1], 22496 z = xyz[2], 22497 l, a, b; 22498 22499 x /= 95.047; 22500 y /= 100; 22501 z /= 108.883; 22502 22503 x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); 22504 y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); 22505 z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); 22506 22507 l = (116 * y) - 16; 22508 a = 500 * (x - y); 22509 b = 200 * (y - z); 22510 22511 return [l, a, b]; 22512} 22513 22514function rgb2lch(args) { 22515 return lab2lch(rgb2lab(args)); 22516} 22517 22518function hsl2rgb(hsl) { 22519 var h = hsl[0] / 360, 22520 s = hsl[1] / 100, 22521 l = hsl[2] / 100, 22522 t1, t2, t3, rgb, val; 22523 22524 if (s == 0) { 22525 val = l * 255; 22526 return [val, val, val]; 22527 } 22528 22529 if (l < 0.5) 22530 t2 = l * (1 + s); 22531 else 22532 t2 = l + s - l * s; 22533 t1 = 2 * l - t2; 22534 22535 rgb = [0, 0, 0]; 22536 for (var i = 0; i < 3; i++) { 22537 t3 = h + 1 / 3 * - (i - 1); 22538 t3 < 0 && t3++; 22539 t3 > 1 && t3--; 22540 22541 if (6 * t3 < 1) 22542 val = t1 + (t2 - t1) * 6 * t3; 22543 else if (2 * t3 < 1) 22544 val = t2; 22545 else if (3 * t3 < 2) 22546 val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; 22547 else 22548 val = t1; 22549 22550 rgb[i] = val * 255; 22551 } 22552 22553 return rgb; 22554} 22555 22556function hsl2hsv(hsl) { 22557 var h = hsl[0], 22558 s = hsl[1] / 100, 22559 l = hsl[2] / 100, 22560 sv, v; 22561 22562 if(l === 0) { 22563 // no need to do calc on black 22564 // also avoids divide by 0 error 22565 return [0, 0, 0]; 22566 } 22567 22568 l *= 2; 22569 s *= (l <= 1) ? l : 2 - l; 22570 v = (l + s) / 2; 22571 sv = (2 * s) / (l + s); 22572 return [h, sv * 100, v * 100]; 22573} 22574 22575function hsl2hwb(args) { 22576 return rgb2hwb(hsl2rgb(args)); 22577} 22578 22579function hsl2cmyk(args) { 22580 return rgb2cmyk(hsl2rgb(args)); 22581} 22582 22583function hsl2keyword(args) { 22584 return rgb2keyword(hsl2rgb(args)); 22585} 22586 22587 22588function hsv2rgb(hsv) {
22589 var h = hsv[0] / 60, 22590 s = hsv[1] / 100, 22591 v = hsv[2] / 100, 22592 hi = Math.floor(h) % 6; 22593 22594 var f = h - Math.floor(h), 22595 p = 255 * v * (1 - s), 22596 q = 255 * v * (1 - (s * f)), 22597 t = 255 * v * (1 - (s * (1 - f))), 22598 v = 255 * v; 22599 22600 switch(hi) { 22601 case 0: 22602 return [v, t, p]; 22603 case 1: 22604 return [q, v, p]; 22605 case 2: 22606 return [p, v, t]; 22607 case 3: 22608 return [p, q, v]; 22609 case 4: 22610 return [t, p, v]; 22611 case 5: 22612 return [v, p, q]; 22613 } 22614} 22615 22616function hsv2hsl(hsv) { 22617 var h = hsv[0], 22618 s = hsv[1] / 100, 22619 v = hsv[2] / 100, 22620 sl, l; 22621 22622 l = (2 - s) * v; 22623 sl = s * v; 22624 sl /= (l <= 1) ? l : 2 - l; 22625 sl = sl || 0; 22626 l /= 2; 22627 return [h, sl * 100, l * 100]; 22628} 22629 22630function hsv2hwb(args) { 22631 return rgb2hwb(hsv2rgb(args)) 22632} 22633 22634function hsv2cmyk(args) { 22635 return rgb2cmyk(hsv2rgb(args)); 22636} 22637 22638function hsv2keyword(args) { 22639 return rgb2keyword(hsv2rgb(args)); 22640} 22641 22642// http://dev.w3.org/csswg/css-color/#hwb-to-rgb 22643function hwb2rgb(hwb) { 22644 var h = hwb[0] / 360, 22645 wh = hwb[1] / 100, 22646 bl = hwb[2] / 100, 22647 ratio = wh + bl, 22648 i, v, f, n; 22649 22650 // wh + bl cant be > 1 22651 if (ratio > 1) { 22652 wh /= ratio; 22653 bl /= ratio; 22654 } 22655 22656 i = Math.floor(6 * h); 22657 v = 1 - bl; 22658 f = 6 * h - i; 22659 if ((i & 0x01) != 0) { 22660 f = 1 - f; 22661 } 22662 n = wh + f * (v - wh); // linear interpolation 22663 22664 switch (i) { 22665 default: 22666 case 6: 22667 case 0: r = v; g = n; b = wh; break; 22668 case 1: r = n; g = v; b = wh; break; 22669 case 2: r = wh; g = v; b = n; break; 22670 case 3: r = wh; g = n; b = v; break; 22671 case 4: r = n; g = wh; b = v; break; 22672 case 5: r = v; g = wh; b = n; break; 22673 } 22674 22675 return [r * 255, g * 255, b * 255]; 22676} 22677 22678function hwb2hsl(args) { 22679 return rgb2hsl(hwb2rgb(args)); 22680} 22681 22682function hwb2hsv(args) { 22683 return rgb2hsv(hwb2rgb(args)); 22684} 22685 22686function hwb2cmyk(args) { 22687 return rgb2cmyk(hwb2rgb(args)); 22688} 22689 22690function hwb2keyword(args) { 22691 return rgb2keyword(hwb2rgb(args)); 22692} 22693 22694function cmyk2rgb(cmyk) { 22695 var c = cmyk[0] / 100, 22696 m = cmyk[1] / 100, 22697 y = cmyk[2] / 100, 22698 k = cmyk[3] / 100, 22699 r, g, b; 22700 22701 r = 1 - Math.min(1, c * (1 - k) + k); 22702 g = 1 - Math.min(1, m * (1 - k) + k); 22703 b = 1 - Math.min(1, y * (1 - k) + k); 22704 return [r * 255, g * 255, b * 255]; 22705} 22706 22707function cmyk2hsl(args) { 22708 return rgb2hsl(cmyk2rgb(args)); 22709} 22710 22711function cmyk2hsv(args) { 22712 return rgb2hsv(cmyk2rgb(args)); 22713} 22714 22715function cmyk2hwb(args) { 22716 return rgb2hwb(cmyk2rgb(args)); 22717} 22718 22719function cmyk2keyword(args) { 22720 return rgb2keyword(cmyk2rgb(args)); 22721} 22722 22723 22724function xyz2rgb(xyz) { 22725 var x = xyz[0] / 100, 22726 y = xyz[1] / 100, 22727 z = xyz[2] / 100, 22728 r, g, b; 22729 22730 r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); 22731 g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); 22732 b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); 22733 22734 // assume sRGB 22735 r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) 22736 : r = (r * 12.92); 22737 22738 g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) 22739 : g = (g * 12.92); 22740 22741 b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) 22742 : b = (b * 12.92); 22743 22744 r = Math.min(Math.max(0, r), 1); 22745 g = Math.min(Math.max(0, g), 1); 22746 b = Math.min(Math.max(0, b), 1); 22747 22748 return [r * 255, g * 255, b * 255]; 22749} 22750 22751function xyz2lab(xyz) { 22752 var x = xyz[0], 22753 y = xyz[1], 22754 z = xyz[2], 22755 l, a, b; 22756 22757 x /= 95.047; 22758 y /= 100; 22759 z /= 108.883; 22760 22761 x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); 22762 y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); 22763 z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); 22764 22765 l = (116 * y) - 16; 22766 a = 500 * (x - y); 22767 b = 200 * (y - z); 22768 22769 return [l, a, b]; 22770} 22771 22772function xyz2lch(args) { 22773 return lab2lch(xyz2lab(args)); 22774} 22775 22776function lab2xyz(lab) { 22777 var l = lab[0], 22778 a = lab[1], 22779 b = lab[2], 22780 x, y, z, y2; 22781 22782 if (l <= 8) { 22783 y = (l * 100) / 903.3; 22784 y2 = (7.787 * (y / 100)) + (16 / 116); 22785 } else { 22786 y = 100 * Math.pow((l + 16) / 116, 3); 22787 y2 = Math.pow(y / 100, 1/3); 22788 } 22789 22790 x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3); 22791 22792 z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3); 22793 22794 return [x, y, z]; 22795} 22796 22797function lab2lch(lab) { 22798 var l = lab[0], 22799 a = lab[1], 22800 b = lab[2], 22801 hr, h, c; 22802 22803 hr = Math.atan2(b, a);
22804 h = hr * 360 / 2 / Math.PI; 22805 if (h < 0) { 22806 h += 360; 22807 } 22808 c = Math.sqrt(a * a + b * b); 22809 return [l, c, h]; 22810} 22811 22812function lab2rgb(args) { 22813 return xyz2rgb(lab2xyz(args)); 22814} 22815 22816function lch2lab(lch) { 22817 var l = lch[0], 22818 c = lch[1], 22819 h = lch[2], 22820 a, b, hr; 22821 22822 hr = h / 360 * 2 * Math.PI; 22823 a = c * Math.cos(hr); 22824 b = c * Math.sin(hr); 22825 return [l, a, b]; 22826} 22827 22828function lch2xyz(args) { 22829 return lab2xyz(lch2lab(args)); 22830} 22831 22832function lch2rgb(args) { 22833 return lab2rgb(lch2lab(args)); 22834} 22835 22836function keyword2rgb(keyword) { 22837 return cssKeywords[keyword]; 22838} 22839 22840function keyword2hsl(args) { 22841 return rgb2hsl(keyword2rgb(args)); 22842} 22843 22844function keyword2hsv(args) { 22845 return rgb2hsv(keyword2rgb(args)); 22846} 22847 22848function keyword2hwb(args) { 22849 return rgb2hwb(keyword2rgb(args)); 22850} 22851 22852function keyword2cmyk(args) { 22853 return rgb2cmyk(keyword2rgb(args)); 22854} 22855 22856function keyword2lab(args) { 22857 return rgb2lab(keyword2rgb(args)); 22858} 22859 22860function keyword2xyz(args) { 22861 return rgb2xyz(keyword2rgb(args)); 22862} 22863 22864var cssKeywords = { 22865 aliceblue: [240,248,255], 22866 antiquewhite: [250,235,215], 22867 aqua: [0,255,255], 22868 aquamarine: [127,255,212], 22869 azure: [240,255,255], 22870 beige: [245,245,220], 22871 bisque: [255,228,196], 22872 black: [0,0,0], 22873 blanchedalmond: [255,235,205], 22874 blue: [0,0,255], 22875 blueviolet: [138,43,226], 22876 brown: [165,42,42], 22877 burlywood: [222,184,135], 22878 cadetblue: [95,158,160], 22879 chartreuse: [127,255,0], 22880 chocolate: [210,105,30], 22881 coral: [255,127,80], 22882 cornflowerblue: [100,149,237], 22883 cornsilk: [255,248,220], 22884 crimson: [220,20,60], 22885 cyan: [0,255,255], 22886 darkblue: [0,0,139], 22887 darkcyan: [0,139,139], 22888 darkgoldenrod: [184,134,11], 22889 darkgray: [169,169,169], 22890 darkgreen: [0,100,0], 22891 darkgrey: [169,169,169], 22892 darkkhaki: [189,183,107], 22893 darkmagenta: [139,0,139], 22894 darkolivegreen: [85,107,47], 22895 darkorange: [255,140,0], 22896 darkorchid: [153,50,204], 22897 darkred: [139,0,0], 22898 darksalmon: [233,150,122], 22899 darkseagreen: [143,188,143], 22900 darkslateblue: [72,61,139], 22901 darkslategray: [47,79,79], 22902 darkslategrey: [47,79,79], 22903 darkturquoise: [0,206,209], 22904 darkviolet: [148,0,211], 22905 deeppink: [255,20,147], 22906 deepskyblue: [0,191,255], 22907 dimgray: [105,105,105], 22908 dimgrey: [105,105,105], 22909 dodgerblue: [30,144,255], 22910 firebrick: [178,34,34], 22911 floralwhite: [255,250,240], 22912 forestgreen: [34,139,34], 22913 fuchsia: [255,0,255], 22914 gainsboro: [220,220,220], 22915 ghostwhite: [248,248,255], 22916 gold: [255,215,0], 22917 goldenrod: [218,165,32], 22918 gray: [128,128,128], 22919 green: [0,128,0], 22920 greenyellow: [173,255,47], 22921 grey: [128,128,128], 22922 honeydew: [240,255,240], 22923 hotpink: [255,105,180], 22924 indianred: [205,92,92], 22925 indigo: [75,0,130], 22926 ivory: [255,255,240], 22927 khaki: [240,230,140], 22928 lavender: [230,230,250], 22929 lavenderblush: [255,240,245], 22930 lawngreen: [124,252,0], 22931 lemonchiffon: [255,250,205], 22932 lightblue: [173,216,230], 22933 lightcoral: [240,128,128], 22934 lightcyan: [224,255,255], 22935 lightgoldenrodyellow: [250,250,210], 22936 lightgray: [211,211,211], 22937 lightgreen: [144,238,144], 22938 lightgrey: [211,211,211], 22939 lightpink: [255,182,193], 22940 lightsalmon: [255,160,122], 22941 lightseagreen: [32,178,170], 22942 lightskyblue: [135,206,250], 22943 lightslategray: [119,136,153], 22944 lightslategrey: [119,136,153], 22945 lightsteelblue: [176,196,222], 22946 lightyellow: [255,255,224], 22947 lime: [0,255,0], 22948 limegreen: [50,205,50], 22949 linen: [250,240,230], 22950 magenta: [255,0,255], 22951 maroon: [128,0,0], 22952 mediumaquamarine: [102,205,170], 22953 mediumblue: [0,0,205], 22954 mediumorchid: [186,85,211], 22955 mediumpurple: [147,112,219], 22956 mediumseagreen: [60,179,113], 22957 mediumslateblue: [123,104,238], 22958 mediumspringgreen: [0,250,154], 22959 mediumturquoise: [72,209,204], 22960 mediumvioletred: [199,21,133], 22961 midnightblue: [25,25,112], 22962 mintcream: [245,255,250], 22963 mistyrose: [255,228,225], 22964 moccasin: [255,228,181], 22965 navajowhite: [255,222,173], 22966 navy: [0,0,128], 22967 oldlace: [253,245,230], 22968 olive: [128,128,0], 22969 olivedrab: [107,142,35], 22970 orange: [255,165,0], 22971 orangered: [255,69,0], 22972 orchid: [218,112,214], 22973 palegoldenrod: [238,232,170], 22974 palegreen: [152,251,152], 22975 paleturquoise: [175,238,238], 22976 palevioletred: [219,112,147], 22977 papayawhip: [255,239,213], 22978 peachpuff: [255,218,185], 22979 peru: [205,133,63], 22980 pink: [255,192,203], 22981 plum: [221,160,221], 22982 powderblue: [176,224,230], 22983 purple: [128,0,128], 22984 rebeccapurple: [102, 51, 153], 22985 red: [255,0,0], 22986 rosybrown: [188,143,143], 22987 royalblue: [65,105,225], 22988 saddlebrown: [139,69,19], 22989 salmon: [250,128,114], 22990 sandybrown: [244,164,96],
22991 seagreen: [46,139,87], 22992 seashell: [255,245,238], 22993 sienna: [160,82,45], 22994 silver: [192,192,192], 22995 skyblue: [135,206,235], 22996 slateblue: [106,90,205], 22997 slategray: [112,128,144], 22998 slategrey: [112,128,144], 22999 snow: [255,250,250], 23000 springgreen: [0,255,127], 23001 steelblue: [70,130,180], 23002 tan: [210,180,140], 23003 teal: [0,128,128], 23004 thistle: [216,191,216], 23005 tomato: [255,99,71], 23006 turquoise: [64,224,208], 23007 violet: [238,130,238], 23008 wheat: [245,222,179], 23009 white: [255,255,255], 23010 whitesmoke: [245,245,245], 23011 yellow: [255,255,0], 23012 yellowgreen: [154,205,50] 23013}; 23014 23015var reverseKeywords = {}; 23016for (var key in cssKeywords) { 23017 reverseKeywords[JSON.stringify(cssKeywords[key])] = key; 23018} 23019 23020},{}],4:[function(require,module,exports){ 23021var conversions = require(3); 23022 23023var convert = function() { 23024 return new Converter(); 23025} 23026 23027for (var func in conversions) { 23028 // export Raw versions 23029 convert[func + "Raw"] = (function(func) { 23030 // accept array or plain args 23031 return function(arg) { 23032 if (typeof arg == "number") 23033 arg = Array.prototype.slice.call(arguments); 23034 return conversions[func](arg); 23035 } 23036 })(func); 23037 23038 var pair = /(\w+)2(\w+)/.exec(func), 23039 from = pair[1], 23040 to = pair[2]; 23041 23042 // export rgb2hsl and ["rgb"]["hsl"] 23043 convert[from] = convert[from] || {}; 23044 23045 convert[from][to] = convert[func] = (function(func) { 23046 return function(arg) { 23047 if (typeof arg == "number") 23048 arg = Array.prototype.slice.call(arguments); 23049 23050 var val = conversions[func](arg); 23051 if (typeof val == "string" || val === undefined) 23052 return val; // keyword 23053 23054 for (var i = 0; i < val.length; i++) 23055 val[i] = Math.round(val[i]); 23056 return val; 23057 } 23058 })(func); 23059} 23060 23061 23062/* Converter does lazy conversion and caching */ 23063var Converter = function() { 23064 this.convs = {}; 23065}; 23066 23067/* Either get the values for a space or 23068 set the values for a space, depending on args */ 23069Converter.prototype.routeSpace = function(space, args) { 23070 var values = args[0]; 23071 if (values === undefined) { 23072 // color.rgb() 23073 return this.getValues(space); 23074 } 23075 // color.rgb(10, 10, 10) 23076 if (typeof values == "number") { 23077 values = Array.prototype.slice.call(args); 23078 } 23079 23080 return this.setValues(space, values); 23081}; 23082 23083/* Set the values for a space, invalidating cache */ 23084Converter.prototype.setValues = function(space, values) { 23085 this.space = space; 23086 this.convs = {}; 23087 this.convs[space] = values; 23088 return this; 23089}; 23090 23091/* Get the values for a space. If there's already 23092 a conversion for the space, fetch it, otherwise 23093 compute it */ 23094Converter.prototype.getValues = function(space) { 23095 var vals = this.convs[space]; 23096 if (!vals) { 23097 var fspace = this.space, 23098 from = this.convs[fspace]; 23099 vals = convert[fspace][space](from); 23100 23101 this.convs[space] = vals; 23102 } 23103 return vals; 23104}; 23105 23106["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) { 23107 Converter.prototype[space] = function(vals) { 23108 return this.routeSpace(space, arguments); 23109 } 23110}); 23111 23112module.exports = convert; 23113},{"3":3}],5:[function(require,module,exports){ 23114'use strict' 23115 23116module.exports = { 23117 "aliceblue": [240, 248, 255], 23118 "antiquewhite": [250, 235, 215], 23119 "aqua": [0, 255, 255], 23120 "aquamarine": [127, 255, 212], 23121 "azure": [240, 255, 255], 23122 "beige": [245, 245, 220], 23123 "bisque": [255, 228, 196], 23124 "black": [0, 0, 0], 23125 "blanchedalmond": [255, 235, 205], 23126 "blue": [0, 0, 255], 23127 "blueviolet": [138, 43, 226], 23128 "brown": [165, 42, 42], 23129 "burlywood": [222, 184, 135], 23130 "cadetblue": [95, 158, 160], 23131 "chartreuse": [127, 255, 0], 23132 "chocolate": [210, 105, 30], 23133 "coral": [255, 127, 80], 23134 "cornflowerblue": [100, 149, 237], 23135 "cornsilk": [255, 248, 220], 23136 "crimson": [220, 20, 60], 23137 "cyan": [0, 255, 255], 23138 "darkblue": [0, 0, 139], 23139 "darkcyan": [0, 139, 139], 23140 "darkgoldenrod": [184, 134, 11], 23141 "darkgray": [169, 169, 169], 23142 "darkgreen": [0, 100, 0], 23143 "darkgrey": [169, 169, 169], 23144 "darkkhaki": [189, 183, 107], 23145 "darkmagenta": [139, 0, 139], 23146 "darkolivegreen": [85, 107, 47], 23147 "darkorange": [255, 140, 0], 23148 "darkorchid": [153, 50, 204], 23149 "darkred": [139, 0, 0], 23150 "darksalmon": [233, 150, 122], 23151 "darkseagreen": [143, 188, 143], 23152 "darkslateblue": [72, 61, 139], 23153 "darkslategray": [47, 79, 79], 23154 "darkslategrey": [47, 79, 79],
23155 "darkturquoise": [0, 206, 209], 23156 "darkviolet": [148, 0, 211], 23157 "deeppink": [255, 20, 147], 23158 "deepskyblue": [0, 191, 255], 23159 "dimgray": [105, 105, 105], 23160 "dimgrey": [105, 105, 105], 23161 "dodgerblue": [30, 144, 255], 23162 "firebrick": [178, 34, 34], 23163 "floralwhite": [255, 250, 240], 23164 "forestgreen": [34, 139, 34], 23165 "fuchsia": [255, 0, 255], 23166 "gainsboro": [220, 220, 220], 23167 "ghostwhite": [248, 248, 255], 23168 "gold": [255, 215, 0], 23169 "goldenrod": [218, 165, 32], 23170 "gray": [128, 128, 128], 23171 "green": [0, 128, 0], 23172 "greenyellow": [173, 255, 47], 23173 "grey": [128, 128, 128], 23174 "honeydew": [240, 255, 240], 23175 "hotpink": [255, 105, 180], 23176 "indianred": [205, 92, 92], 23177 "indigo": [75, 0, 130], 23178 "ivory": [255, 255, 240], 23179 "khaki": [240, 230, 140], 23180 "lavender": [230, 230, 250], 23181 "lavenderblush": [255, 240, 245], 23182 "lawngreen": [124, 252, 0], 23183 "lemonchiffon": [255, 250, 205], 23184 "lightblue": [173, 216, 230], 23185 "lightcoral": [240, 128, 128], 23186 "lightcyan": [224, 255, 255], 23187 "lightgoldenrodyellow": [250, 250, 210], 23188 "lightgray": [211, 211, 211], 23189 "lightgreen": [144, 238, 144], 23190 "lightgrey": [211, 211, 211], 23191 "lightpink": [255, 182, 193], 23192 "lightsalmon": [255, 160, 122], 23193 "lightseagreen": [32, 178, 170], 23194 "lightskyblue": [135, 206, 250], 23195 "lightslategray": [119, 136, 153], 23196 "lightslategrey": [119, 136, 153], 23197 "lightsteelblue": [176, 196, 222], 23198 "lightyellow": [255, 255, 224], 23199 "lime": [0, 255, 0], 23200 "limegreen": [50, 205, 50], 23201 "linen": [250, 240, 230], 23202 "magenta": [255, 0, 255], 23203 "maroon": [128, 0, 0], 23204 "mediumaquamarine": [102, 205, 170], 23205 "mediumblue": [0, 0, 205], 23206 "mediumorchid": [186, 85, 211], 23207 "mediumpurple": [147, 112, 219], 23208 "mediumseagreen": [60, 179, 113], 23209 "mediumslateblue": [123, 104, 238], 23210 "mediumspringgreen": [0, 250, 154], 23211 "mediumturquoise": [72, 209, 204], 23212 "mediumvioletred": [199, 21, 133], 23213 "midnightblue": [25, 25, 112], 23214 "mintcream": [245, 255, 250], 23215 "mistyrose": [255, 228, 225], 23216 "moccasin": [255, 228, 181], 23217 "navajowhite": [255, 222, 173], 23218 "navy": [0, 0, 128], 23219 "oldlace": [253, 245, 230], 23220 "olive": [128, 128, 0], 23221 "olivedrab": [107, 142, 35], 23222 "orange": [255, 165, 0], 23223 "orangered": [255, 69, 0], 23224 "orchid": [218, 112, 214], 23225 "palegoldenrod": [238, 232, 170], 23226 "palegreen": [152, 251, 152], 23227 "paleturquoise": [175, 238, 238], 23228 "palevioletred": [219, 112, 147], 23229 "papayawhip": [255, 239, 213], 23230 "peachpuff": [255, 218, 185], 23231 "peru": [205, 133, 63], 23232 "pink": [255, 192, 203], 23233 "plum": [221, 160, 221], 23234 "powderblue": [176, 224, 230], 23235 "purple": [128, 0, 128], 23236 "rebeccapurple": [102, 51, 153], 23237 "red": [255, 0, 0], 23238 "rosybrown": [188, 143, 143], 23239 "royalblue": [65, 105, 225], 23240 "saddlebrown": [139, 69, 19], 23241 "salmon": [250, 128, 114], 23242 "sandybrown": [244, 164, 96], 23243 "seagreen": [46, 139, 87], 23244 "seashell": [255, 245, 238], 23245 "sienna": [160, 82, 45], 23246 "silver": [192, 192, 192], 23247 "skyblue": [135, 206, 235], 23248 "slateblue": [106, 90, 205], 23249 "slategray": [112, 128, 144], 23250 "slategrey": [112, 128, 144], 23251 "snow": [255, 250, 250], 23252 "springgreen": [0, 255, 127], 23253 "steelblue": [70, 130, 180], 23254 "tan": [210, 180, 140], 23255 "teal": [0, 128, 128], 23256 "thistle": [216, 191, 216], 23257 "tomato": [255, 99, 71], 23258 "turquoise": [64, 224, 208], 23259 "violet": [238, 130, 238], 23260 "wheat": [245, 222, 179], 23261 "white": [255, 255, 255], 23262 "whitesmoke": [245, 245, 245], 23263 "yellow": [255, 255, 0], 23264 "yellowgreen": [154, 205, 50] 23265}; 23266 23267},{}],6:[function(require,module,exports){ 23268//! moment.js 23269//! version : 2.20.1 23270//! authors : Tim Wood, Iskren Chernev, Moment.js contributors 23271//! license : MIT 23272//! momentjs.com 23273 23274;(function (global, factory) { 23275 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 23276 typeof define === 'function' && define.amd ? define(factory) : 23277 global.moment = factory() 23278}(this, (function () { 'use strict'; 23279 23280var hookCallback; 23281 23282function hooks () { 23283 return hookCallback.apply(null, arguments); 23284} 23285 23286// This is done to register the method called with moment() 23287// without creating circular dependencies. 23288function setHookCallback (callback) { 23289 hookCallback = callback; 23290} 23291 23292function isArray(input) { 23293 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; 23294} 23295 23296function isObject(input) { 23297 // IE8 will treat undefined and null as object if it wasn't for 23298 // input != null 23299 return input != null && Object.prototype.toString.call(input) === '[object Object]'; 23300} 23301 23302function isObjectEmpty(obj) { 23303 if (Object.getOwnPropertyNames) { 23304 return (Object.getOwnPropertyNames(obj).length === 0); 23305 } else { 23306 var k; 23307 for (k in obj) { 23308 if (obj.hasOwnProperty(k)) { 23309 return false;
vendor: 22,951 bytes, lines 23310-24187
23310 } 23311 } 23312 return true; 23313 } 23314} 23315 23316function isUndefined(input) { 23317 return input === void 0; 23318} 23319 23320function isNumber(input) { 23321 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; 23322} 23323 23324function isDate(input) { 23325 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; 23326} 23327 23328function map(arr, fn) { 23329 var res = [], i; 23330 for (i = 0; i < arr.length; ++i) { 23331 res.push(fn(arr[i], i)); 23332 } 23333 return res; 23334} 23335 23336function hasOwnProp(a, b) { 23337 return Object.prototype.hasOwnProperty.call(a, b); 23338} 23339 23340function extend(a, b) { 23341 for (var i in b) { 23342 if (hasOwnProp(b, i)) { 23343 a[i] = b[i]; 23344 } 23345 } 23346 23347 if (hasOwnProp(b, 'toString')) { 23348 a.toString = b.toString; 23349 } 23350 23351 if (hasOwnProp(b, 'valueOf')) { 23352 a.valueOf = b.valueOf; 23353 } 23354 23355 return a; 23356} 23357 23358function createUTC (input, format, locale, strict) { 23359 return createLocalOrUTC(input, format, locale, strict, true).utc(); 23360} 23361 23362function defaultParsingFlags() { 23363 // We need to deep clone this object. 23364 return { 23365 empty : false, 23366 unusedTokens : [], 23367 unusedInput : [], 23368 overflow : -2, 23369 charsLeftOver : 0, 23370 nullInput : false, 23371 invalidMonth : null, 23372 invalidFormat : false, 23373 userInvalidated : false, 23374 iso : false, 23375 parsedDateParts : [], 23376 meridiem : null, 23377 rfc2822 : false, 23378 weekdayMismatch : false 23379 }; 23380} 23381 23382function getParsingFlags(m) { 23383 if (m._pf == null) { 23384 m._pf = defaultParsingFlags(); 23385 } 23386 return m._pf; 23387} 23388 23389var some; 23390if (Array.prototype.some) { 23391 some = Array.prototype.some; 23392} else { 23393 some = function (fun) { 23394 var t = Object(this); 23395 var len = t.length >>> 0; 23396 23397 for (var i = 0; i < len; i++) { 23398 if (i in t && fun.call(this, t[i], i, t)) { 23399 return true; 23400 } 23401 } 23402 23403 return false; 23404 }; 23405} 23406 23407function isValid(m) { 23408 if (m._isValid == null) { 23409 var flags = getParsingFlags(m); 23410 var parsedParts = some.call(flags.parsedDateParts, function (i) { 23411 return i != null; 23412 }); 23413 var isNowValid = !isNaN(m._d.getTime()) && 23414 flags.overflow < 0 && 23415 !flags.empty && 23416 !flags.invalidMonth && 23417 !flags.invalidWeekday && 23418 !flags.weekdayMismatch && 23419 !flags.nullInput && 23420 !flags.invalidFormat && 23421 !flags.userInvalidated && 23422 (!flags.meridiem || (flags.meridiem && parsedParts)); 23423 23424 if (m._strict) { 23425 isNowValid = isNowValid && 23426 flags.charsLeftOver === 0 && 23427 flags.unusedTokens.length === 0 && 23428 flags.bigHour === undefined; 23429 } 23430 23431 if (Object.isFrozen == null || !Object.isFrozen(m)) { 23432 m._isValid = isNowValid; 23433 } 23434 else { 23435 return isNowValid; 23436 } 23437 } 23438 return m._isValid; 23439} 23440 23441function createInvalid (flags) { 23442 var m = createUTC(NaN); 23443 if (flags != null) { 23444 extend(getParsingFlags(m), flags); 23445 } 23446 else { 23447 getParsingFlags(m).userInvalidated = true; 23448 } 23449 23450 return m; 23451} 23452 23453// Plugins that add properties should also add the key here (null value), 23454// so we can properly clone ourselves. 23455var momentProperties = hooks.momentProperties = []; 23456 23457function copyConfig(to, from) { 23458 var i, prop, val; 23459 23460 if (!isUndefined(from._isAMomentObject)) { 23461 to._isAMomentObject = from._isAMomentObject; 23462 } 23463 if (!isUndefined(from._i)) { 23464 to._i = from._i; 23465 } 23466 if (!isUndefined(from._f)) { 23467 to._f = from._f; 23468 } 23469 if (!isUndefined(from._l)) { 23470 to._l = from._l; 23471 } 23472 if (!isUndefined(from._strict)) { 23473 to._strict = from._strict; 23474 } 23475 if (!isUndefined(from._tzm)) { 23476 to._tzm = from._tzm; 23477 } 23478 if (!isUndefined(from._isUTC)) { 23479 to._isUTC = from._isUTC; 23480 } 23481 if (!isUndefined(from._offset)) { 23482 to._offset = from._offset; 23483 } 23484 if (!isUndefined(from._pf)) { 23485 to._pf = getParsingFlags(from); 23486 } 23487 if (!isUndefined(from._locale)) { 23488 to._locale = from._locale; 23489 } 23490 23491 if (momentProperties.length > 0) { 23492 for (i = 0; i < momentProperties.length; i++) { 23493 prop = momentProperties[i]; 23494 val = from[prop]; 23495 if (!isUndefined(val)) { 23496 to[prop] = val; 23497 } 23498 } 23499 } 23500 23501 return to; 23502} 23503 23504var updateInProgress = false; 23505 23506// Moment prototype object 23507function Moment(config) { 23508 copyConfig(this, config); 23509 this._d = new Date(config._d != null ? config._d.getTime() : NaN); 23510 if (!this.isValid()) { 23511 this._d = new Date(NaN); 23512 } 23513 // Prevent infinite loop in case updateOffset creates new moment 23514 // objects. 23515 if (updateInProgress === false) { 23516 updateInProgress = true; 23517 hooks.updateOffset(this); 23518 updateInProgress = false; 23519 } 23520} 23521 23522function isMoment (obj) { 23523 return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); 23524} 23525 23526function absFloor (number) { 23527 if (number < 0) { 23528 // -0 -> 0 23529 return Math.ceil(number) || 0; 23530 } else { 23531 return Math.floor(number); 23532 } 23533} 23534 23535function toInt(argumentForCoercion) { 23536 var coercedNumber = +argumentForCoercion, 23537 value = 0; 23538 23539 if (coercedNumber !== 0 && isFinite(coercedNumber)) { 23540 value = absFloor(coercedNumber); 23541 } 23542 23543 return value; 23544} 23545 23546// compare two arrays, return the number of differences 23547function compareArrays(array1, array2, dontConvert) { 23548 var len = Math.min(array1.length, array2.length), 23549 lengthDiff = Math.abs(array1.length - array2.length), 23550 diffs = 0, 23551 i; 23552 for (i = 0; i < len; i++) { 23553 if ((dontConvert && array1[i] !== array2[i]) || 23554 (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { 23555 diffs++; 23556 } 23557 } 23558 return diffs + lengthDiff; 23559} 23560 23561function warn(msg) { 23562 if (hooks.suppressDeprecationWarnings === false && 23563 (typeof console !== 'undefined') && console.warn) { 23564 console.warn('Deprecation warning: ' + msg); 23565 } 23566} 23567 23568function deprecate(msg, fn) { 23569 var firstTime = true; 23570 23571 return extend(function () { 23572 if (hooks.deprecationHandler != null) { 23573 hooks.deprecationHandler(null, msg); 23574 } 23575 if (firstTime) { 23576 var args = []; 23577 var arg; 23578 for (var i = 0; i < arguments.length; i++) { 23579 arg = ''; 23580 if (typeof arguments[i] === 'object') { 23581 arg += '\n[' + i + '] '; 23582 for (var key in arguments[0]) { 23583 arg += key + ': ' + arguments[0][key] + ', '; 23584 } 23585 arg = arg.slice(0, -2); // Remove trailing comma and space 23586 } else { 23587 arg = arguments[i]; 23588 } 23589 args.push(arg); 23590 } 23591 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); 23592 firstTime = false; 23593 } 23594 return fn.apply(this, arguments); 23595 }, fn); 23596} 23597 23598var deprecations = {}; 23599 23600function deprecateSimple(name, msg) { 23601 if (hooks.deprecationHandler != null) { 23602 hooks.deprecationHandler(name, msg); 23603 } 23604 if (!deprecations[name]) { 23605 warn(msg); 23606 deprecations[name] = true; 23607 } 23608} 23609 23610hooks.suppressDeprecationWarnings = false; 23611hooks.deprecationHandler = null; 23612 23613function isFunction(input) { 23614 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; 23615} 23616 23617function set (config) { 23618 var prop, i; 23619 for (i in config) { 23620 prop = config[i]; 23621 if (isFunction(prop)) { 23622 this[i] = prop; 23623 } else { 23624 this['_' + i] = prop; 23625 } 23626 } 23627 this._config = config; 23628 // Lenient ordinal parsing accepts just a number in addition to 23629 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. 23630 // TODO: Remove "ordinalParse" fallback in next major release. 23631 this._dayOfMonthOrdinalParseLenient = new RegExp( 23632 (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + 23633 '|' + (/\d{1,2}/).source); 23634} 23635 23636function mergeConfigs(parentConfig, childConfig) { 23637 var res = extend({}, parentConfig), prop; 23638 for (prop in childConfig) { 23639 if (hasOwnProp(childConfig, prop)) { 23640 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { 23641 res[prop] = {}; 23642 extend(res[prop], parentConfig[prop]); 23643 extend(res[prop], childConfig[prop]); 23644 } else if (childConfig[prop] != null) { 23645 res[prop] = childConfig[prop]; 23646 } else { 23647 delete res[prop]; 23648 } 23649 } 23650 } 23651 for (prop in parentConfig) { 23652 if (hasOwnProp(parentConfig, prop) && 23653 !hasOwnProp(childConfig, prop) && 23654 isObject(parentConfig[prop])) { 23655 // make sure changes to properties don't modify parent config 23656 res[prop] = extend({}, res[prop]); 23657 } 23658 } 23659 return res; 23660} 23661 23662function Locale(config) { 23663 if (config != null) { 23664 this.set(config); 23665 } 23666} 23667 23668var keys; 23669 23670if (Object.keys) { 23671 keys = Object.keys; 23672} else { 23673 keys = function (obj) { 23674 var i, res = []; 23675 for (i in obj) { 23676 if (hasOwnProp(obj, i)) { 23677 res.push(i); 23678 } 23679 } 23680 return res; 23681 }; 23682} 23683 23684var defaultCalendar = { 23685 sameDay : '[Today at] LT', 23686 nextDay : '[Tomorrow at] LT', 23687 nextWeek : 'dddd [at] LT', 23688 lastDay : '[Yesterday at] LT', 23689 lastWeek : '[Last] dddd [at] LT', 23690 sameElse : 'L' 23691}; 23692 23693function calendar (key, mom, now) { 23694 var output = this._calendar[key] || this._calendar['sameElse']; 23695 return isFunction(output) ? output.call(mom, now) : output; 23696} 23697 23698var defaultLongDateFormat = { 23699 LTS : 'h:mm:ss A', 23700 LT : 'h:mm A', 23701 L : 'MM/DD/YYYY', 23702 LL : 'MMMM D, YYYY', 23703 LLL : 'MMMM D, YYYY h:mm A', 23704 LLLL : 'dddd, MMMM D, YYYY h:mm A' 23705}; 23706 23707function longDateFormat (key) { 23708 var format = this._longDateFormat[key], 23709 formatUpper = this._longDateFormat[key.toUpperCase()]; 23710 23711 if (format || !formatUpper) { 23712 return format; 23713 } 23714 23715 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { 23716 return val.slice(1); 23717 }); 23718 23719 return this._longDateFormat[key]; 23720} 23721 23722var defaultInvalidDate = 'Invalid date'; 23723 23724function invalidDate () { 23725 return this._invalidDate; 23726} 23727 23728var defaultOrdinal = '%d'; 23729var defaultDayOfMonthOrdinalParse = /\d{1,2}/; 23730 23731function ordinal (number) { 23732 return this._ordinal.replace('%d', number); 23733} 23734 23735var defaultRelativeTime = { 23736 future : 'in %s', 23737 past : '%s ago', 23738 s : 'a few seconds', 23739 ss : '%d seconds', 23740 m : 'a minute', 23741 mm : '%d minutes', 23742 h : 'an hour', 23743 hh : '%d hours', 23744 d : 'a day', 23745 dd : '%d days', 23746 M : 'a month', 23747 MM : '%d months', 23748 y : 'a year', 23749 yy : '%d years' 23750}; 23751 23752function relativeTime (number, withoutSuffix, string, isFuture) { 23753 var output = this._relativeTime[string]; 23754 return (isFunction(output)) ? 23755 output(number, withoutSuffix, string, isFuture) : 23756 output.replace(/%d/i, number); 23757} 23758 23759function pastFuture (diff, output) { 23760 var format = this._relativeTime[diff > 0 ? 'future' : 'past']; 23761 return isFunction(format) ? format(output) : format.replace(/%s/i, output); 23762} 23763 23764var aliases = {}; 23765 23766function addUnitAlias (unit, shorthand) { 23767 var lowerCase = unit.toLowerCase(); 23768 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; 23769} 23770 23771function normalizeUnits(units) { 23772 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; 23773} 23774 23775function normalizeObjectUnits(inputObject) { 23776 var normalizedInput = {}, 23777 normalizedProp, 23778 prop; 23779 23780 for (prop in inputObject) { 23781 if (hasOwnProp(inputObject, prop)) { 23782 normalizedProp = normalizeUnits(prop); 23783 if (normalizedProp) { 23784 normalizedInput[normalizedProp] = inputObject[prop]; 23785 } 23786 } 23787 } 23788 23789 return normalizedInput; 23790} 23791 23792var priorities = {}; 23793 23794function addUnitPriority(unit, priority) { 23795 priorities[unit] = priority; 23796} 23797 23798function getPrioritizedUnits(unitsObj) { 23799 var units = []; 23800 for (var u in unitsObj) { 23801 units.push({unit: u, priority: priorities[u]}); 23802 } 23803 units.sort(function (a, b) { 23804 return a.priority - b.priority; 23805 }); 23806 return units; 23807} 23808 23809function zeroFill(number, targetLength, forceSign) { 23810 var absNumber = '' + Math.abs(number), 23811 zerosToFill = targetLength - absNumber.length, 23812 sign = number >= 0; 23813 return (sign ? (forceSign ? '+' : '') : '-') + 23814 Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; 23815} 23816 23817var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; 23818 23819var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; 23820 23821var formatFunctions = {}; 23822 23823var formatTokenFunctions = {}; 23824 23825// token: 'M' 23826// padded: ['MM', 2] 23827// ordinal: 'Mo' 23828// callback: function () { this.month() + 1 } 23829function addFormatToken (token, padded, ordinal, callback) { 23830 var func = callback; 23831 if (typeof callback === 'string') { 23832 func = function () { 23833 return this[callback](); 23834 }; 23835 } 23836 if (token) { 23837 formatTokenFunctions[token] = func; 23838 } 23839 if (padded) { 23840 formatTokenFunctions[padded[0]] = function () { 23841 return zeroFill(func.apply(this, arguments), padded[1], padded[2]); 23842 }; 23843 } 23844 if (ordinal) { 23845 formatTokenFunctions[ordinal] = function () { 23846 return this.localeData().ordinal(func.apply(this, arguments), token); 23847 }; 23848 } 23849} 23850 23851function removeFormattingTokens(input) { 23852 if (input.match(/\[[\s\S]/)) { 23853 return input.replace(/^\[|\]$/g, ''); 23854 } 23855 return input.replace(/\\/g, ''); 23856} 23857 23858function makeFormatFunction(format) { 23859 var array = format.match(formattingTokens), i, length; 23860 23861 for (i = 0, length = array.length; i < length; i++) { 23862 if (formatTokenFunctions[array[i]]) { 23863 array[i] = formatTokenFunctions[array[i]]; 23864 } else { 23865 array[i] = removeFormattingTokens(array[i]); 23866 } 23867 } 23868 23869 return function (mom) { 23870 var output = '', i; 23871 for (i = 0; i < length; i++) { 23872 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; 23873 } 23874 return output; 23875 }; 23876} 23877 23878// format date using native date object 23879function formatMoment(m, format) { 23880 if (!m.isValid()) { 23881 return m.localeData().invalidDate(); 23882 } 23883 23884 format = expandFormat(format, m.localeData()); 23885 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); 23886 23887 return formatFunctions[format](m); 23888} 23889 23890function expandFormat(format, locale) { 23891 var i = 5; 23892 23893 function replaceLongDateFormatTokens(input) { 23894 return locale.longDateFormat(input) || input; 23895 } 23896 23897 localFormattingTokens.lastIndex = 0; 23898 while (i >= 0 && localFormattingTokens.test(format)) { 23899 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); 23900 localFormattingTokens.lastIndex = 0; 23901 i -= 1; 23902 } 23903 23904 return format; 23905} 23906 23907var match1 = /\d/; // 0 - 9 23908var match2 = /\d\d/; // 00 - 99 23909var match3 = /\d{3}/; // 000 - 999 23910var match4 = /\d{4}/; // 0000 - 9999 23911var match6 = /[+-]?\d{6}/; // -999999 - 999999 23912var match1to2 = /\d\d?/; // 0 - 99 23913var match3to4 = /\d\d\d\d?/; // 999 - 9999 23914var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 23915var match1to3 = /\d{1,3}/; // 0 - 999 23916var match1to4 = /\d{1,4}/; // 0 - 9999 23917var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 23918 23919var matchUnsigned = /\d+/; // 0 - inf 23920var matchSigned = /[+-]?\d+/; // -inf - inf 23921 23922var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z 23923var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z 23924 23925var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 23926 23927// any word (or two) characters or numbers including two/three word month in arabic. 23928// includes scottish gaelic two word and hyphenated months 23929var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; 23930 23931 23932var regexes = {}; 23933 23934function addRegexToken (token, regex, strictRegex) { 23935 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { 23936 return (isStrict && strictRegex) ? strictRegex : regex; 23937 }; 23938} 23939 23940function getParseRegexForToken (token, config) { 23941 if (!hasOwnProp(regexes, token)) { 23942 return new RegExp(unescapeFormat(token)); 23943 } 23944 23945 return regexes[token](config._strict, config._locale); 23946} 23947 23948// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript 23949function unescapeFormat(s) { 23950 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { 23951 return p1 || p2 || p3 || p4; 23952 })); 23953} 23954 23955function regexEscape(s) { 23956 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); 23957} 23958 23959var tokens = {}; 23960 23961function addParseToken (token, callback) { 23962 var i, func = callback; 23963 if (typeof token === 'string') { 23964 token = [token]; 23965 } 23966 if (isNumber(callback)) { 23967 func = function (input, array) { 23968 array[callback] = toInt(input); 23969 }; 23970 } 23971 for (i = 0; i < token.length; i++) { 23972 tokens[token[i]] = func; 23973 } 23974} 23975 23976function addWeekParseToken (token, callback) { 23977 addParseToken(token, function (input, array, config, token) { 23978 config._w = config._w || {}; 23979 callback(input, config._w, config, token); 23980 }); 23981} 23982 23983function addTimeToArrayFromToken(token, input, config) { 23984 if (input != null && hasOwnProp(tokens, token)) { 23985 tokens[token](input, config._a, config, token); 23986 } 23987} 23988 23989var YEAR = 0; 23990var MONTH = 1; 23991var DATE = 2; 23992var HOUR = 3; 23993var MINUTE = 4; 23994var SECOND = 5; 23995var MILLISECOND = 6; 23996var WEEK = 7; 23997var WEEKDAY = 8; 23998 23999// FORMATTING 24000 24001addFormatToken('Y', 0, 0, function () { 24002 var y = this.year(); 24003 return y <= 9999 ? '' + y : '+' + y; 24004}); 24005 24006addFormatToken(0, ['YY', 2], 0, function () { 24007 return this.year() % 100; 24008}); 24009 24010addFormatToken(0, ['YYYY', 4], 0, 'year'); 24011addFormatToken(0, ['YYYYY', 5], 0, 'year'); 24012addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); 24013 24014// ALIASES 24015 24016addUnitAlias('year', 'y'); 24017 24018// PRIORITIES 24019 24020addUnitPriority('year', 1); 24021 24022// PARSING 24023 24024addRegexToken('Y', matchSigned); 24025addRegexToken('YY', match1to2, match2); 24026addRegexToken('YYYY', match1to4, match4); 24027addRegexToken('YYYYY', match1to6, match6); 24028addRegexToken('YYYYYY', match1to6, match6); 24029 24030addParseToken(['YYYYY', 'YYYYYY'], YEAR); 24031addParseToken('YYYY', function (input, array) { 24032 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); 24033}); 24034addParseToken('YY', function (input, array) { 24035 array[YEAR] = hooks.parseTwoDigitYear(input); 24036}); 24037addParseToken('Y', function (input, array) { 24038 array[YEAR] = parseInt(input, 10); 24039}); 24040 24041// HELPERS 24042 24043function daysInYear(year) { 24044 return isLeapYear(year) ? 366 : 365; 24045} 24046 24047function isLeapYear(year) { 24048 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; 24049} 24050 24051// HOOKS 24052 24053hooks.parseTwoDigitYear = function (input) { 24054 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); 24055}; 24056 24057// MOMENTS 24058 24059var getSetYear = makeGetSet('FullYear', true); 24060 24061function getIsLeapYear () { 24062 return isLeapYear(this.year()); 24063} 24064 24065function makeGetSet (unit, keepTime) { 24066 return function (value) { 24067 if (value != null) { 24068 set$1(this, unit, value); 24069 hooks.updateOffset(this, keepTime); 24070 return this; 24071 } else { 24072 return get(this, unit); 24073 } 24074 }; 24075} 24076 24077function get (mom, unit) { 24078 return mom.isValid() ? 24079 mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; 24080} 24081 24082function set$1 (mom, unit, value) { 24083 if (mom.isValid() && !isNaN(value)) { 24084 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { 24085 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); 24086 } 24087 else { 24088 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); 24089 } 24090 } 24091} 24092 24093// MOMENTS 24094 24095function stringGet (units) { 24096 units = normalizeUnits(units); 24097 if (isFunction(this[units])) { 24098 return this[units](); 24099 } 24100 return this; 24101} 24102 24103 24104function stringSet (units, value) { 24105 if (typeof units === 'object') { 24106 units = normalizeObjectUnits(units); 24107 var prioritized = getPrioritizedUnits(units); 24108 for (var i = 0; i < prioritized.length; i++) { 24109 this[prioritized[i].unit](units[prioritized[i].unit]); 24110 } 24111 } else { 24112 units = normalizeUnits(units); 24113 if (isFunction(this[units])) { 24114 return this[units](value); 24115 } 24116 } 24117 return this; 24118} 24119 24120function mod(n, x) { 24121 return ((n % x) + x) % x; 24122} 24123 24124var indexOf; 24125 24126if (Array.prototype.indexOf) { 24127 indexOf = Array.prototype.indexOf; 24128} else { 24129 indexOf = function (o) { 24130 // I know 24131 var i; 24132 for (i = 0; i < this.length; ++i) { 24133 if (this[i] === o) { 24134 return i; 24135 } 24136 } 24137 return -1; 24138 }; 24139} 24140 24141function daysInMonth(year, month) { 24142 if (isNaN(year) || isNaN(month)) { 24143 return NaN; 24144 } 24145 var modMonth = mod(month, 12); 24146 year += (month - modMonth) / 12; 24147 return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); 24148} 24149 24150// FORMATTING 24151 24152addFormatToken('M', ['MM', 2], 'Mo', function () { 24153 return this.month() + 1; 24154}); 24155 24156addFormatToken('MMM', 0, 0, function (format) { 24157 return this.localeData().monthsShort(this, format); 24158}); 24159 24160addFormatToken('MMMM', 0, 0, function (format) { 24161 return this.localeData().months(this, format); 24162}); 24163 24164// ALIASES 24165 24166addUnitAlias('month', 'M'); 24167 24168// PRIORITY 24169 24170addUnitPriority('month', 8); 24171 24172// PARSING 24173 24174addRegexToken('M', match1to2); 24175addRegexToken('MM', match1to2, match2); 24176addRegexToken('MMM', function (isStrict, locale) { 24177 return locale.monthsShortRegex(isStrict); 24178}); 24179addRegexToken('MMMM', function (isStrict, locale) { 24180 return locale.monthsRegex(isStrict); 24181}); 24182 24183addParseToken(['M', 'MM'], function (input, array) { 24184 array[MONTH] = toInt(input) - 1; 24185}); 24186 24187addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
vendor: 24,092 bytes, lines 24188-24972
24188 var month = config._locale.monthsParse(input, token, config._strict); 24189 // if we didn't find a month name, mark the date as invalid. 24190 if (month != null) { 24191 array[MONTH] = month; 24192 } else { 24193 getParsingFlags(config).invalidMonth = input; 24194 } 24195}); 24196 24197// LOCALES 24198 24199var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; 24200var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); 24201function localeMonths (m, format) { 24202 if (!m) { 24203 return isArray(this._months) ? this._months : 24204 this._months['standalone']; 24205 } 24206 return isArray(this._months) ? this._months[m.month()] : 24207 this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; 24208} 24209 24210var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); 24211function localeMonthsShort (m, format) { 24212 if (!m) { 24213 return isArray(this._monthsShort) ? this._monthsShort : 24214 this._monthsShort['standalone']; 24215 } 24216 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : 24217 this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; 24218} 24219 24220function handleStrictParse(monthName, format, strict) { 24221 var i, ii, mom, llc = monthName.toLocaleLowerCase(); 24222 if (!this._monthsParse) { 24223 // this is not used 24224 this._monthsParse = []; 24225 this._longMonthsParse = []; 24226 this._shortMonthsParse = []; 24227 for (i = 0; i < 12; ++i) { 24228 mom = createUTC([2000, i]); 24229 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); 24230 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); 24231 } 24232 } 24233 24234 if (strict) { 24235 if (format === 'MMM') { 24236 ii = indexOf.call(this._shortMonthsParse, llc); 24237 return ii !== -1 ? ii : null; 24238 } else { 24239 ii = indexOf.call(this._longMonthsParse, llc); 24240 return ii !== -1 ? ii : null; 24241 } 24242 } else { 24243 if (format === 'MMM') { 24244 ii = indexOf.call(this._shortMonthsParse, llc); 24245 if (ii !== -1) { 24246 return ii; 24247 } 24248 ii = indexOf.call(this._longMonthsParse, llc); 24249 return ii !== -1 ? ii : null; 24250 } else { 24251 ii = indexOf.call(this._longMonthsParse, llc); 24252 if (ii !== -1) { 24253 return ii; 24254 } 24255 ii = indexOf.call(this._shortMonthsParse, llc); 24256 return ii !== -1 ? ii : null; 24257 } 24258 } 24259} 24260 24261function localeMonthsParse (monthName, format, strict) { 24262 var i, mom, regex; 24263 24264 if (this._monthsParseExact) { 24265 return handleStrictParse.call(this, monthName, format, strict); 24266 } 24267 24268 if (!this._monthsParse) { 24269 this._monthsParse = []; 24270 this._longMonthsParse = []; 24271 this._shortMonthsParse = []; 24272 } 24273 24274 // TODO: add sorting 24275 // Sorting makes sure if one month (or abbr) is a prefix of another 24276 // see sorting in computeMonthsParse 24277 for (i = 0; i < 12; i++) { 24278 // make the regex if we don't have it already 24279 mom = createUTC([2000, i]); 24280 if (strict && !this._longMonthsParse[i]) { 24281 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); 24282 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); 24283 } 24284 if (!strict && !this._monthsParse[i]) { 24285 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); 24286 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); 24287 } 24288 // test the regex 24289 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { 24290 return i; 24291 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { 24292 return i; 24293 } else if (!strict && this._monthsParse[i].test(monthName)) { 24294 return i; 24295 } 24296 } 24297} 24298 24299// MOMENTS 24300 24301function setMonth (mom, value) { 24302 var dayOfMonth; 24303 24304 if (!mom.isValid()) { 24305 // No op 24306 return mom; 24307 } 24308 24309 if (typeof value === 'string') { 24310 if (/^\d+$/.test(value)) { 24311 value = toInt(value); 24312 } else { 24313 value = mom.localeData().monthsParse(value); 24314 // TODO: Another silent failure? 24315 if (!isNumber(value)) { 24316 return mom; 24317 } 24318 } 24319 } 24320 24321 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); 24322 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); 24323 return mom; 24324} 24325 24326function getSetMonth (value) { 24327 if (value != null) { 24328 setMonth(this, value); 24329 hooks.updateOffset(this, true); 24330 return this; 24331 } else { 24332 return get(this, 'Month'); 24333 } 24334} 24335 24336function getDaysInMonth () { 24337 return daysInMonth(this.year(), this.month()); 24338} 24339 24340var defaultMonthsShortRegex = matchWord; 24341function monthsShortRegex (isStrict) { 24342 if (this._monthsParseExact) { 24343 if (!hasOwnProp(this, '_monthsRegex')) { 24344 computeMonthsParse.call(this); 24345 } 24346 if (isStrict) { 24347 return this._monthsShortStrictRegex; 24348 } else { 24349 return this._monthsShortRegex; 24350 } 24351 } else { 24352 if (!hasOwnProp(this, '_monthsShortRegex')) { 24353 this._monthsShortRegex = defaultMonthsShortRegex; 24354 } 24355 return this._monthsShortStrictRegex && isStrict ? 24356 this._monthsShortStrictRegex : this._monthsShortRegex; 24357 } 24358} 24359 24360var defaultMonthsRegex = matchWord; 24361function monthsRegex (isStrict) { 24362 if (this._monthsParseExact) { 24363 if (!hasOwnProp(this, '_monthsRegex')) { 24364 computeMonthsParse.call(this); 24365 } 24366 if (isStrict) { 24367 return this._monthsStrictRegex; 24368 } else { 24369 return this._monthsRegex; 24370 } 24371 } else { 24372 if (!hasOwnProp(this, '_monthsRegex')) { 24373 this._monthsRegex = defaultMonthsRegex; 24374 } 24375 return this._monthsStrictRegex && isStrict ? 24376 this._monthsStrictRegex : this._monthsRegex; 24377 } 24378} 24379 24380function computeMonthsParse () { 24381 function cmpLenRev(a, b) { 24382 return b.length - a.length; 24383 } 24384 24385 var shortPieces = [], longPieces = [], mixedPieces = [], 24386 i, mom; 24387 for (i = 0; i < 12; i++) { 24388 // make the regex if we don't have it already 24389 mom = createUTC([2000, i]); 24390 shortPieces.push(this.monthsShort(mom, '')); 24391 longPieces.push(this.months(mom, '')); 24392 mixedPieces.push(this.months(mom, '')); 24393 mixedPieces.push(this.monthsShort(mom, '')); 24394 } 24395 // Sorting makes sure if one month (or abbr) is a prefix of another it 24396 // will match the longer piece. 24397 shortPieces.sort(cmpLenRev); 24398 longPieces.sort(cmpLenRev); 24399 mixedPieces.sort(cmpLenRev); 24400 for (i = 0; i < 12; i++) { 24401 shortPieces[i] = regexEscape(shortPieces[i]); 24402 longPieces[i] = regexEscape(longPieces[i]); 24403 } 24404 for (i = 0; i < 24; i++) { 24405 mixedPieces[i] = regexEscape(mixedPieces[i]); 24406 } 24407 24408 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); 24409 this._monthsShortRegex = this._monthsRegex; 24410 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); 24411 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); 24412} 24413 24414function createDate (y, m, d, h, M, s, ms) { 24415 // can't just apply() to create a date: 24416 // https://stackoverflow.com/q/181348 24417 var date = new Date(y, m, d, h, M, s, ms); 24418 24419 // the date constructor remaps years 0-99 to 1900-1999 24420 if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { 24421 date.setFullYear(y); 24422 } 24423 return date; 24424} 24425 24426function createUTCDate (y) { 24427 var date = new Date(Date.UTC.apply(null, arguments)); 24428 24429 // the Date.UTC function remaps years 0-99 to 1900-1999 24430 if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { 24431 date.setUTCFullYear(y); 24432 } 24433 return date; 24434} 24435 24436// start-of-first-week - start-of-year 24437function firstWeekOffset(year, dow, doy) { 24438 var // first-week day -- which january is always in the first week (4 for iso, 1 for other) 24439 fwd = 7 + dow - doy, 24440 // first-week day local weekday -- which local weekday is fwd 24441 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; 24442 24443 return -fwdlw + fwd - 1; 24444} 24445 24446// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday 24447function dayOfYearFromWeeks(year, week, weekday, dow, doy) { 24448 var localWeekday = (7 + weekday - dow) % 7, 24449 weekOffset = firstWeekOffset(year, dow, doy), 24450 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, 24451 resYear, resDayOfYear; 24452 24453 if (dayOfYear <= 0) { 24454 resYear = year - 1; 24455 resDayOfYear = daysInYear(resYear) + dayOfYear; 24456 } else if (dayOfYear > daysInYear(year)) { 24457 resYear = year + 1; 24458 resDayOfYear = dayOfYear - daysInYear(year); 24459 } else { 24460 resYear = year; 24461 resDayOfYear = dayOfYear; 24462 } 24463 24464 return { 24465 year: resYear, 24466 dayOfYear: resDayOfYear 24467 }; 24468} 24469 24470function weekOfYear(mom, dow, doy) { 24471 var weekOffset = firstWeekOffset(mom.year(), dow, doy), 24472 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, 24473 resWeek, resYear; 24474 24475 if (week < 1) { 24476 resYear = mom.year() - 1; 24477 resWeek = week + weeksInYear(resYear, dow, doy); 24478 } else if (week > weeksInYear(mom.year(), dow, doy)) { 24479 resWeek = week - weeksInYear(mom.year(), dow, doy); 24480 resYear = mom.year() + 1; 24481 } else { 24482 resYear = mom.year(); 24483 resWeek = week; 24484 } 24485 24486 return { 24487 week: resWeek, 24488 year: resYear 24489 }; 24490} 24491 24492function weeksInYear(year, dow, doy) { 24493 var weekOffset = firstWeekOffset(year, dow, doy), 24494 weekOffsetNext = firstWeekOffset(year + 1, dow, doy); 24495 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; 24496} 24497 24498// FORMATTING 24499 24500addFormatToken('w', ['ww', 2], 'wo', 'week'); 24501addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); 24502 24503// ALIASES 24504 24505addUnitAlias('week', 'w'); 24506addUnitAlias('isoWeek', 'W'); 24507 24508// PRIORITIES 24509 24510addUnitPriority('week', 5); 24511addUnitPriority('isoWeek', 5); 24512 24513// PARSING 24514 24515addRegexToken('w', match1to2); 24516addRegexToken('ww', match1to2, match2); 24517addRegexToken('W', match1to2); 24518addRegexToken('WW', match1to2, match2); 24519 24520addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { 24521 week[token.substr(0, 1)] = toInt(input); 24522}); 24523 24524// HELPERS 24525 24526// LOCALES 24527 24528function localeWeek (mom) { 24529 return weekOfYear(mom, this._week.dow, this._week.doy).week; 24530} 24531 24532var defaultLocaleWeek = { 24533 dow : 0, // Sunday is the first day of the week. 24534 doy : 6 // The week that contains Jan 1st is the first week of the year. 24535}; 24536 24537function localeFirstDayOfWeek () { 24538 return this._week.dow; 24539} 24540 24541function localeFirstDayOfYear () { 24542 return this._week.doy; 24543} 24544 24545// MOMENTS 24546 24547function getSetWeek (input) { 24548 var week = this.localeData().week(this); 24549 return input == null ? week : this.add((input - week) * 7, 'd'); 24550} 24551 24552function getSetISOWeek (input) { 24553 var week = weekOfYear(this, 1, 4).week; 24554 return input == null ? week : this.add((input - week) * 7, 'd'); 24555} 24556 24557// FORMATTING 24558 24559addFormatToken('d', 0, 'do', 'day'); 24560 24561addFormatToken('dd', 0, 0, function (format) { 24562 return this.localeData().weekdaysMin(this, format); 24563}); 24564 24565addFormatToken('ddd', 0, 0, function (format) { 24566 return this.localeData().weekdaysShort(this, format); 24567}); 24568 24569addFormatToken('dddd', 0, 0, function (format) { 24570 return this.localeData().weekdays(this, format); 24571}); 24572 24573addFormatToken('e', 0, 0, 'weekday'); 24574addFormatToken('E', 0, 0, 'isoWeekday'); 24575 24576// ALIASES 24577 24578addUnitAlias('day', 'd'); 24579addUnitAlias('weekday', 'e'); 24580addUnitAlias('isoWeekday', 'E'); 24581 24582// PRIORITY 24583addUnitPriority('day', 11); 24584addUnitPriority('weekday', 11); 24585addUnitPriority('isoWeekday', 11); 24586 24587// PARSING 24588 24589addRegexToken('d', match1to2); 24590addRegexToken('e', match1to2); 24591addRegexToken('E', match1to2); 24592addRegexToken('dd', function (isStrict, locale) { 24593 return locale.weekdaysMinRegex(isStrict); 24594}); 24595addRegexToken('ddd', function (isStrict, locale) { 24596 return locale.weekdaysShortRegex(isStrict); 24597}); 24598addRegexToken('dddd', function (isStrict, locale) { 24599 return locale.weekdaysRegex(isStrict); 24600}); 24601 24602addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { 24603 var weekday = config._locale.weekdaysParse(input, token, config._strict); 24604 // if we didn't get a weekday name, mark the date as invalid 24605 if (weekday != null) { 24606 week.d = weekday; 24607 } else { 24608 getParsingFlags(config).invalidWeekday = input; 24609 } 24610}); 24611 24612addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { 24613 week[token] = toInt(input); 24614}); 24615 24616// HELPERS 24617 24618function parseWeekday(input, locale) { 24619 if (typeof input !== 'string') { 24620 return input; 24621 } 24622 24623 if (!isNaN(input)) { 24624 return parseInt(input, 10); 24625 } 24626 24627 input = locale.weekdaysParse(input); 24628 if (typeof input === 'number') { 24629 return input; 24630 } 24631 24632 return null; 24633} 24634 24635function parseIsoWeekday(input, locale) { 24636 if (typeof input === 'string') { 24637 return locale.weekdaysParse(input) % 7 || 7; 24638 } 24639 return isNaN(input) ? null : input; 24640} 24641 24642// LOCALES 24643 24644var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); 24645function localeWeekdays (m, format) { 24646 if (!m) { 24647 return isArray(this._weekdays) ? this._weekdays : 24648 this._weekdays['standalone']; 24649 } 24650 return isArray(this._weekdays) ? this._weekdays[m.day()] : 24651 this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; 24652} 24653 24654var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); 24655function localeWeekdaysShort (m) { 24656 return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; 24657} 24658 24659var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); 24660function localeWeekdaysMin (m) { 24661 return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; 24662} 24663 24664function handleStrictParse$1(weekdayName, format, strict) { 24665 var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); 24666 if (!this._weekdaysParse) { 24667 this._weekdaysParse = []; 24668 this._shortWeekdaysParse = []; 24669 this._minWeekdaysParse = []; 24670 24671 for (i = 0; i < 7; ++i) { 24672 mom = createUTC([2000, 1]).day(i); 24673 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); 24674 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); 24675 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); 24676 } 24677 } 24678 24679 if (strict) { 24680 if (format === 'dddd') { 24681 ii = indexOf.call(this._weekdaysParse, llc); 24682 return ii !== -1 ? ii : null; 24683 } else if (format === 'ddd') { 24684 ii = indexOf.call(this._shortWeekdaysParse, llc); 24685 return ii !== -1 ? ii : null; 24686 } else { 24687 ii = indexOf.call(this._minWeekdaysParse, llc); 24688 return ii !== -1 ? ii : null; 24689 } 24690 } else { 24691 if (format === 'dddd') { 24692 ii = indexOf.call(this._weekdaysParse, llc); 24693 if (ii !== -1) { 24694 return ii; 24695 } 24696 ii = indexOf.call(this._shortWeekdaysParse, llc); 24697 if (ii !== -1) { 24698 return ii; 24699 } 24700 ii = indexOf.call(this._minWeekdaysParse, llc); 24701 return ii !== -1 ? ii : null; 24702 } else if (format === 'ddd') { 24703 ii = indexOf.call(this._shortWeekdaysParse, llc); 24704 if (ii !== -1) { 24705 return ii; 24706 } 24707 ii = indexOf.call(this._weekdaysParse, llc); 24708 if (ii !== -1) { 24709 return ii; 24710 } 24711 ii = indexOf.call(this._minWeekdaysParse, llc); 24712 return ii !== -1 ? ii : null; 24713 } else { 24714 ii = indexOf.call(this._minWeekdaysParse, llc); 24715 if (ii !== -1) { 24716 return ii; 24717 } 24718 ii = indexOf.call(this._weekdaysParse, llc); 24719 if (ii !== -1) { 24720 return ii; 24721 } 24722 ii = indexOf.call(this._shortWeekdaysParse, llc); 24723 return ii !== -1 ? ii : null; 24724 } 24725 } 24726} 24727 24728function localeWeekdaysParse (weekdayName, format, strict) { 24729 var i, mom, regex; 24730 24731 if (this._weekdaysParseExact) { 24732 return handleStrictParse$1.call(this, weekdayName, format, strict); 24733 } 24734 24735 if (!this._weekdaysParse) { 24736 this._weekdaysParse = []; 24737 this._minWeekdaysParse = []; 24738 this._shortWeekdaysParse = []; 24739 this._fullWeekdaysParse = []; 24740 } 24741 24742 for (i = 0; i < 7; i++) { 24743 // make the regex if we don't have it already 24744 24745 mom = createUTC([2000, 1]).day(i); 24746 if (strict && !this._fullWeekdaysParse[i]) { 24747 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i'); 24748 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i'); 24749 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i'); 24750 } 24751 if (!this._weekdaysParse[i]) { 24752 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); 24753 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); 24754 } 24755 // test the regex 24756 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { 24757 return i; 24758 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { 24759 return i; 24760 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { 24761 return i; 24762 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { 24763 return i; 24764 } 24765 } 24766} 24767 24768// MOMENTS 24769 24770function getSetDayOfWeek (input) { 24771 if (!this.isValid()) { 24772 return input != null ? this : NaN; 24773 } 24774 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); 24775 if (input != null) { 24776 input = parseWeekday(input, this.localeData()); 24777 return this.add(input - day, 'd'); 24778 } else { 24779 return day; 24780 } 24781} 24782 24783function getSetLocaleDayOfWeek (input) { 24784 if (!this.isValid()) { 24785 return input != null ? this : NaN; 24786 } 24787 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; 24788 return input == null ? weekday : this.add(input - weekday, 'd'); 24789} 24790 24791function getSetISODayOfWeek (input) { 24792 if (!this.isValid()) { 24793 return input != null ? this : NaN; 24794 } 24795 24796 // behaves the same as moment#day except 24797 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) 24798 // as a setter, sunday should belong to the previous week. 24799 24800 if (input != null) { 24801 var weekday = parseIsoWeekday(input, this.localeData()); 24802 return this.day(this.day() % 7 ? weekday : weekday - 7); 24803 } else { 24804 return this.day() || 7; 24805 } 24806} 24807 24808var defaultWeekdaysRegex = matchWord; 24809function weekdaysRegex (isStrict) { 24810 if (this._weekdaysParseExact) { 24811 if (!hasOwnProp(this, '_weekdaysRegex')) { 24812 computeWeekdaysParse.call(this); 24813 } 24814 if (isStrict) { 24815 return this._weekdaysStrictRegex; 24816 } else { 24817 return this._weekdaysRegex; 24818 } 24819 } else { 24820 if (!hasOwnProp(this, '_weekdaysRegex')) { 24821 this._weekdaysRegex = defaultWeekdaysRegex; 24822 } 24823 return this._weekdaysStrictRegex && isStrict ? 24824 this._weekdaysStrictRegex : this._weekdaysRegex; 24825 } 24826} 24827 24828var defaultWeekdaysShortRegex = matchWord; 24829function weekdaysShortRegex (isStrict) { 24830 if (this._weekdaysParseExact) { 24831 if (!hasOwnProp(this, '_weekdaysRegex')) { 24832 computeWeekdaysParse.call(this); 24833 } 24834 if (isStrict) { 24835 return this._weekdaysShortStrictRegex; 24836 } else { 24837 return this._weekdaysShortRegex; 24838 } 24839 } else { 24840 if (!hasOwnProp(this, '_weekdaysShortRegex')) { 24841 this._weekdaysShortRegex = defaultWeekdaysShortRegex; 24842 } 24843 return this._weekdaysShortStrictRegex && isStrict ? 24844 this._weekdaysShortStrictRegex : this._weekdaysShortRegex; 24845 } 24846} 24847 24848var defaultWeekdaysMinRegex = matchWord; 24849function weekdaysMinRegex (isStrict) { 24850 if (this._weekdaysParseExact) { 24851 if (!hasOwnProp(this, '_weekdaysRegex')) { 24852 computeWeekdaysParse.call(this); 24853 } 24854 if (isStrict) { 24855 return this._weekdaysMinStrictRegex; 24856 } else { 24857 return this._weekdaysMinRegex; 24858 } 24859 } else { 24860 if (!hasOwnProp(this, '_weekdaysMinRegex')) { 24861 this._weekdaysMinRegex = defaultWeekdaysMinRegex; 24862 } 24863 return this._weekdaysMinStrictRegex && isStrict ? 24864 this._weekdaysMinStrictRegex : this._weekdaysMinRegex; 24865 } 24866} 24867 24868 24869function computeWeekdaysParse () { 24870 function cmpLenRev(a, b) { 24871 return b.length - a.length; 24872 } 24873 24874 var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], 24875 i, mom, minp, shortp, longp; 24876 for (i = 0; i < 7; i++) { 24877 // make the regex if we don't have it already 24878 mom = createUTC([2000, 1]).day(i); 24879 minp = this.weekdaysMin(mom, ''); 24880 shortp = this.weekdaysShort(mom, ''); 24881 longp = this.weekdays(mom, ''); 24882 minPieces.push(minp); 24883 shortPieces.push(shortp); 24884 longPieces.push(longp); 24885 mixedPieces.push(minp); 24886 mixedPieces.push(shortp); 24887 mixedPieces.push(longp); 24888 } 24889 // Sorting makes sure if one weekday (or abbr) is a prefix of another it 24890 // will match the longer piece. 24891 minPieces.sort(cmpLenRev); 24892 shortPieces.sort(cmpLenRev); 24893 longPieces.sort(cmpLenRev); 24894 mixedPieces.sort(cmpLenRev); 24895 for (i = 0; i < 7; i++) { 24896 shortPieces[i] = regexEscape(shortPieces[i]); 24897 longPieces[i] = regexEscape(longPieces[i]); 24898 mixedPieces[i] = regexEscape(mixedPieces[i]); 24899 } 24900 24901 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); 24902 this._weekdaysShortRegex = this._weekdaysRegex; 24903 this._weekdaysMinRegex = this._weekdaysRegex; 24904 24905 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); 24906 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); 24907 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); 24908} 24909 24910// FORMATTING 24911 24912function hFormat() { 24913 return this.hours() % 12 || 12; 24914} 24915 24916function kFormat() { 24917 return this.hours() || 24; 24918} 24919 24920addFormatToken('H', ['HH', 2], 0, 'hour'); 24921addFormatToken('h', ['hh', 2], 0, hFormat); 24922addFormatToken('k', ['kk', 2], 0, kFormat); 24923 24924addFormatToken('hmm', 0, 0, function () { 24925 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); 24926}); 24927 24928addFormatToken('hmmss', 0, 0, function () { 24929 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + 24930 zeroFill(this.seconds(), 2); 24931}); 24932 24933addFormatToken('Hmm', 0, 0, function () { 24934 return '' + this.hours() + zeroFill(this.minutes(), 2); 24935}); 24936 24937addFormatToken('Hmmss', 0, 0, function () { 24938 return '' + this.hours() + zeroFill(this.minutes(), 2) + 24939 zeroFill(this.seconds(), 2); 24940}); 24941 24942function meridiem (token, lowercase) { 24943 addFormatToken(token, 0, 0, function () { 24944 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); 24945 }); 24946} 24947 24948meridiem('a', true); 24949meridiem('A', false); 24950 24951// ALIASES 24952 24953addUnitAlias('hour', 'h'); 24954 24955// PRIORITY 24956addUnitPriority('hour', 13); 24957 24958// PARSING 24959 24960function matchMeridiem (isStrict, locale) { 24961 return locale._meridiemParse; 24962} 24963 24964addRegexToken('a', matchMeridiem); 24965addRegexToken('A', matchMeridiem); 24966addRegexToken('H', match1to2); 24967addRegexToken('h', match1to2); 24968addRegexToken('k', match1to2); 24969addRegexToken('HH', match1to2, match2); 24970addRegexToken('hh', match1to2, match2); 24971addRegexToken('kk', match1to2, match2); 24972
vendor: 18,399 bytes, lines 24973-25545
24973addRegexToken('hmm', match3to4); 24974addRegexToken('hmmss', match5to6); 24975addRegexToken('Hmm', match3to4); 24976addRegexToken('Hmmss', match5to6); 24977 24978addParseToken(['H', 'HH'], HOUR); 24979addParseToken(['k', 'kk'], function (input, array, config) { 24980 var kInput = toInt(input); 24981 array[HOUR] = kInput === 24 ? 0 : kInput; 24982}); 24983addParseToken(['a', 'A'], function (input, array, config) { 24984 config._isPm = config._locale.isPM(input); 24985 config._meridiem = input; 24986}); 24987addParseToken(['h', 'hh'], function (input, array, config) { 24988 array[HOUR] = toInt(input); 24989 getParsingFlags(config).bigHour = true; 24990}); 24991addParseToken('hmm', function (input, array, config) { 24992 var pos = input.length - 2; 24993 array[HOUR] = toInt(input.substr(0, pos)); 24994 array[MINUTE] = toInt(input.substr(pos)); 24995 getParsingFlags(config).bigHour = true; 24996}); 24997addParseToken('hmmss', function (input, array, config) { 24998 var pos1 = input.length - 4; 24999 var pos2 = input.length - 2; 25000 array[HOUR] = toInt(input.substr(0, pos1)); 25001 array[MINUTE] = toInt(input.substr(pos1, 2)); 25002 array[SECOND] = toInt(input.substr(pos2)); 25003 getParsingFlags(config).bigHour = true; 25004}); 25005addParseToken('Hmm', function (input, array, config) { 25006 var pos = input.length - 2; 25007 array[HOUR] = toInt(input.substr(0, pos)); 25008 array[MINUTE] = toInt(input.substr(pos)); 25009}); 25010addParseToken('Hmmss', function (input, array, config) { 25011 var pos1 = input.length - 4; 25012 var pos2 = input.length - 2; 25013 array[HOUR] = toInt(input.substr(0, pos1)); 25014 array[MINUTE] = toInt(input.substr(pos1, 2)); 25015 array[SECOND] = toInt(input.substr(pos2)); 25016}); 25017 25018// LOCALES 25019 25020function localeIsPM (input) { 25021 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays 25022 // Using charAt should be more compatible. 25023 return ((input + '').toLowerCase().charAt(0) === 'p'); 25024} 25025 25026var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; 25027function localeMeridiem (hours, minutes, isLower) { 25028 if (hours > 11) { 25029 return isLower ? 'pm' : 'PM'; 25030 } else { 25031 return isLower ? 'am' : 'AM'; 25032 } 25033} 25034 25035 25036// MOMENTS 25037 25038// Setting the hour should keep the time, because the user explicitly 25039// specified which hour he wants. So trying to maintain the same hour (in 25040// a new timezone) makes sense. Adding/subtracting hours does not follow 25041// this rule. 25042var getSetHour = makeGetSet('Hours', true); 25043 25044// months 25045// week 25046// weekdays 25047// meridiem 25048var baseConfig = { 25049 calendar: defaultCalendar, 25050 longDateFormat: defaultLongDateFormat, 25051 invalidDate: defaultInvalidDate, 25052 ordinal: defaultOrdinal, 25053 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, 25054 relativeTime: defaultRelativeTime, 25055 25056 months: defaultLocaleMonths, 25057 monthsShort: defaultLocaleMonthsShort, 25058 25059 week: defaultLocaleWeek, 25060 25061 weekdays: defaultLocaleWeekdays, 25062 weekdaysMin: defaultLocaleWeekdaysMin, 25063 weekdaysShort: defaultLocaleWeekdaysShort, 25064 25065 meridiemParse: defaultLocaleMeridiemParse 25066}; 25067 25068// internal storage for locale config files 25069var locales = {}; 25070var localeFamilies = {}; 25071var globalLocale; 25072 25073function normalizeLocale(key) { 25074 return key ? key.toLowerCase().replace('_', '-') : key; 25075} 25076 25077// pick the locale from the array 25078// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each 25079// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root 25080function chooseLocale(names) { 25081 var i = 0, j, next, locale, split; 25082 25083 while (i < names.length) { 25084 split = normalizeLocale(names[i]).split('-'); 25085 j = split.length; 25086 next = normalizeLocale(names[i + 1]); 25087 next = next ? next.split('-') : null; 25088 while (j > 0) { 25089 locale = loadLocale(split.slice(0, j).join('-')); 25090 if (locale) { 25091 return locale; 25092 } 25093 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { 25094 //the next array item is better than a shallower substring of this one 25095 break; 25096 } 25097 j--; 25098 } 25099 i++; 25100 } 25101 return null; 25102} 25103 25104function loadLocale(name) { 25105 var oldLocale = null; 25106 // TODO: Find a better way to register and load all the locales in Node 25107 if (!locales[name] && (typeof module !== 'undefined') && 25108 module && module.exports) { 25109 try { 25110 oldLocale = globalLocale._abbr; 25111 var aliasedRequire = require; 25112 aliasedRequire('./locale/' + name); 25113 getSetGlobalLocale(oldLocale); 25114 } catch (e) {} 25115 } 25116 return locales[name]; 25117} 25118 25119// This function will load locale and then set the global locale. If 25120// no arguments are passed in, it will simply return the current global 25121// locale key. 25122function getSetGlobalLocale (key, values) { 25123 var data; 25124 if (key) { 25125 if (isUndefined(values)) { 25126 data = getLocale(key); 25127 } 25128 else { 25129 data = defineLocale(key, values); 25130 } 25131 25132 if (data) { 25133 // moment.duration._locale = moment._locale = data; 25134 globalLocale = data; 25135 } 25136 } 25137 25138 return globalLocale._abbr; 25139} 25140 25141function defineLocale (name, config) { 25142 if (config !== null) { 25143 var parentConfig = baseConfig; 25144 config.abbr = name; 25145 if (locales[name] != null) { 25146 deprecateSimple('defineLocaleOverride', 25147 'use moment.updateLocale(localeName, config) to change ' + 25148 'an existing locale. moment.defineLocale(localeName, ' + 25149 'config) should only be used for creating a new locale ' + 25150 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); 25151 parentConfig = locales[name]._config; 25152 } else if (config.parentLocale != null) { 25153 if (locales[config.parentLocale] != null) { 25154 parentConfig = locales[config.parentLocale]._config; 25155 } else { 25156 if (!localeFamilies[config.parentLocale]) { 25157 localeFamilies[config.parentLocale] = []; 25158 } 25159 localeFamilies[config.parentLocale].push({ 25160 name: name, 25161 config: config 25162 }); 25163 return null; 25164 } 25165 } 25166 locales[name] = new Locale(mergeConfigs(parentConfig, config)); 25167 25168 if (localeFamilies[name]) { 25169 localeFamilies[name].forEach(function (x) { 25170 defineLocale(x.name, x.config); 25171 }); 25172 } 25173 25174 // backwards compat for now: also set the locale 25175 // make sure we set the locale AFTER all child locales have been 25176 // created, so we won't end up with the child locale set. 25177 getSetGlobalLocale(name); 25178 25179 25180 return locales[name]; 25181 } else { 25182 // useful for testing 25183 delete locales[name]; 25184 return null; 25185 } 25186} 25187 25188function updateLocale(name, config) { 25189 if (config != null) { 25190 var locale, tmpLocale, parentConfig = baseConfig; 25191 // MERGE 25192 tmpLocale = loadLocale(name); 25193 if (tmpLocale != null) { 25194 parentConfig = tmpLocale._config; 25195 } 25196 config = mergeConfigs(parentConfig, config); 25197 locale = new Locale(config); 25198 locale.parentLocale = locales[name]; 25199 locales[name] = locale; 25200 25201 // backwards compat for now: also set the locale 25202 getSetGlobalLocale(name); 25203 } else { 25204 // pass null for config to unupdate, useful for tests 25205 if (locales[name] != null) { 25206 if (locales[name].parentLocale != null) { 25207 locales[name] = locales[name].parentLocale; 25208 } else if (locales[name] != null) { 25209 delete locales[name]; 25210 } 25211 } 25212 } 25213 return locales[name]; 25214} 25215 25216// returns locale data 25217function getLocale (key) { 25218 var locale; 25219 25220 if (key && key._locale && key._locale._abbr) { 25221 key = key._locale._abbr; 25222 } 25223 25224 if (!key) { 25225 return globalLocale; 25226 } 25227 25228 if (!isArray(key)) { 25229 //short-circuit everything else 25230 locale = loadLocale(key); 25231 if (locale) { 25232 return locale; 25233 } 25234 key = [key]; 25235 } 25236 25237 return chooseLocale(key); 25238} 25239 25240function listLocales() { 25241 return keys(locales); 25242} 25243 25244function checkOverflow (m) { 25245 var overflow; 25246 var a = m._a; 25247 25248 if (a && getParsingFlags(m).overflow === -2) { 25249 overflow = 25250 a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : 25251 a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : 25252 a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : 25253 a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : 25254 a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : 25255 a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : 25256 -1; 25257 25258 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { 25259 overflow = DATE; 25260 } 25261 if (getParsingFlags(m)._overflowWeeks && overflow === -1) { 25262 overflow = WEEK; 25263 } 25264 if (getParsingFlags(m)._overflowWeekday && overflow === -1) { 25265 overflow = WEEKDAY; 25266 } 25267 25268 getParsingFlags(m).overflow = overflow; 25269 } 25270 25271 return m; 25272} 25273 25274// Pick the first defined of two or three arguments. 25275function defaults(a, b, c) { 25276 if (a != null) { 25277 return a; 25278 } 25279 if (b != null) { 25280 return b; 25281 } 25282 return c; 25283} 25284 25285function currentDateArray(config) { 25286 // hooks is actually the exported moment object 25287 var nowValue = new Date(hooks.now()); 25288 if (config._useUTC) { 25289 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; 25290 } 25291 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; 25292} 25293 25294// convert an array to a date. 25295// the array should mirror the parameters below 25296// note: all values past the year are optional and will default to the lowest possible value. 25297// [year, month, day , hour, minute, second, millisecond] 25298function configFromArray (config) { 25299 var i, date, input = [], currentDate, expectedWeekday, yearToUse; 25300 25301 if (config._d) { 25302 return; 25303 } 25304 25305 currentDate = currentDateArray(config); 25306 25307 //compute day of the year from weeks and weekdays 25308 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { 25309 dayOfYearFromWeekInfo(config); 25310 } 25311 25312 //if the day of the year is set, figure out what it is 25313 if (config._dayOfYear != null) { 25314 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); 25315 25316 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { 25317 getParsingFlags(config)._overflowDayOfYear = true; 25318 } 25319 25320 date = createUTCDate(yearToUse, 0, config._dayOfYear); 25321 config._a[MONTH] = date.getUTCMonth(); 25322 config._a[DATE] = date.getUTCDate(); 25323 } 25324 25325 // Default to current date. 25326 // * if no year, month, day of month are given, default to today 25327 // * if day of month is given, default month and year 25328 // * if month is given, default only year 25329 // * if year is given, don't default anything 25330 for (i = 0; i < 3 && config._a[i] == null; ++i) { 25331 config._a[i] = input[i] = currentDate[i]; 25332 } 25333 25334 // Zero out whatever was not defaulted, including time 25335 for (; i < 7; i++) { 25336 config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; 25337 } 25338 25339 // Check for 24:00:00.000 25340 if (config._a[HOUR] === 24 && 25341 config._a[MINUTE] === 0 && 25342 config._a[SECOND] === 0 && 25343 config._a[MILLISECOND] === 0) { 25344 config._nextDay = true; 25345 config._a[HOUR] = 0; 25346 } 25347 25348 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); 25349 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); 25350 25351 // Apply timezone offset from input. The actual utcOffset can be changed 25352 // with parseZone. 25353 if (config._tzm != null) { 25354 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); 25355 } 25356 25357 if (config._nextDay) { 25358 config._a[HOUR] = 24; 25359 } 25360 25361 // check for mismatching day of week 25362 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { 25363 getParsingFlags(config).weekdayMismatch = true; 25364 } 25365} 25366 25367function dayOfYearFromWeekInfo(config) { 25368 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; 25369 25370 w = config._w; 25371 if (w.GG != null || w.W != null || w.E != null) { 25372 dow = 1; 25373 doy = 4; 25374 25375 // TODO: We need to take the current isoWeekYear, but that depends on 25376 // how we interpret now (local, utc, fixed offset). So create 25377 // a now version of current config (take local/utc/offset flags, and 25378 // create now). 25379 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); 25380 week = defaults(w.W, 1); 25381 weekday = defaults(w.E, 1); 25382 if (weekday < 1 || weekday > 7) { 25383 weekdayOverflow = true; 25384 } 25385 } else { 25386 dow = config._locale._week.dow; 25387 doy = config._locale._week.doy; 25388 25389 var curWeek = weekOfYear(createLocal(), dow, doy); 25390 25391 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); 25392 25393 // Default to current week. 25394 week = defaults(w.w, curWeek.week); 25395 25396 if (w.d != null) { 25397 // weekday -- low day numbers are considered next week 25398 weekday = w.d; 25399 if (weekday < 0 || weekday > 6) { 25400 weekdayOverflow = true; 25401 } 25402 } else if (w.e != null) { 25403 // local weekday -- counting starts from begining of week 25404 weekday = w.e + dow; 25405 if (w.e < 0 || w.e > 6) { 25406 weekdayOverflow = true; 25407 } 25408 } else { 25409 // default to begining of week 25410 weekday = dow; 25411 } 25412 } 25413 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { 25414 getParsingFlags(config)._overflowWeeks = true; 25415 } else if (weekdayOverflow != null) { 25416 getParsingFlags(config)._overflowWeekday = true; 25417 } else { 25418 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); 25419 config._a[YEAR] = temp.year; 25420 config._dayOfYear = temp.dayOfYear; 25421 } 25422} 25423 25424// iso 8601 regex 25425// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) 25426var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; 25427var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; 25428 25429var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; 25430 25431var isoDates = [ 25432 ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], 25433 ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], 25434 ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], 25435 ['GGGG-[W]WW', /\d{4}-W\d\d/, false], 25436 ['YYYY-DDD', /\d{4}-\d{3}/], 25437 ['YYYY-MM', /\d{4}-\d\d/, false], 25438 ['YYYYYYMMDD', /[+-]\d{10}/], 25439 ['YYYYMMDD', /\d{8}/], 25440 // YYYYMM is NOT allowed by the standard 25441 ['GGGG[W]WWE', /\d{4}W\d{3}/], 25442 ['GGGG[W]WW', /\d{4}W\d{2}/, false], 25443 ['YYYYDDD', /\d{7}/] 25444]; 25445 25446// iso time formats and regexes 25447var isoTimes = [ 25448 ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], 25449 ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], 25450 ['HH:mm:ss', /\d\d:\d\d:\d\d/], 25451 ['HH:mm', /\d\d:\d\d/], 25452 ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], 25453 ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], 25454 ['HHmmss', /\d\d\d\d\d\d/], 25455 ['HHmm', /\d\d\d\d/], 25456 ['HH', /\d\d/] 25457]; 25458 25459var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; 25460 25461// date from iso format 25462function configFromISO(config) { 25463 var i, l, 25464 string = config._i, 25465 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), 25466 allowTime, dateFormat, timeFormat, tzFormat; 25467 25468 if (match) { 25469 getParsingFlags(config).iso = true; 25470 25471 for (i = 0, l = isoDates.length; i < l; i++) { 25472 if (isoDates[i][1].exec(match[1])) { 25473 dateFormat = isoDates[i][0]; 25474 allowTime = isoDates[i][2] !== false; 25475 break; 25476 } 25477 } 25478 if (dateFormat == null) { 25479 config._isValid = false; 25480 return; 25481 } 25482 if (match[3]) { 25483 for (i = 0, l = isoTimes.length; i < l; i++) { 25484 if (isoTimes[i][1].exec(match[3])) { 25485 // match[2] should be 'T' or space 25486 timeFormat = (match[2] || ' ') + isoTimes[i][0]; 25487 break; 25488 } 25489 } 25490 if (timeFormat == null) { 25491 config._isValid = false; 25492 return; 25493 } 25494 } 25495 if (!allowTime && timeFormat != null) { 25496 config._isValid = false; 25497 return; 25498 } 25499 if (match[4]) { 25500 if (tzRegex.exec(match[4])) { 25501 tzFormat = 'Z'; 25502 } else { 25503 config._isValid = false; 25504 return; 25505 } 25506 } 25507 config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); 25508 configFromStringAndFormat(config); 25509 } else { 25510 config._isValid = false; 25511 } 25512} 25513 25514// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 25515var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; 25516 25517function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { 25518 var result = [ 25519 untruncateYear(yearStr), 25520 defaultLocaleMonthsShort.indexOf(monthStr), 25521 parseInt(dayStr, 10), 25522 parseInt(hourStr, 10), 25523 parseInt(minuteStr, 10) 25524 ]; 25525 25526 if (secondStr) { 25527 result.push(parseInt(secondStr, 10)); 25528 } 25529 25530 return result; 25531} 25532 25533function untruncateYear(yearStr) { 25534 var year = parseInt(yearStr, 10); 25535 if (year <= 49) { 25536 return 2000 + year; 25537 } else if (year <= 999) { 25538 return 1900 + year; 25539 } 25540 return year; 25541} 25542 25543function preprocessRFC2822(s) { 25544 // Remove comments and folding whitespace and replace multiple-spaces with a single space 25545 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim(
vendor: 6,917 bytes, lines 25545-25774
25545); 25546} 25547 25548function checkWeekday(weekdayStr, parsedInput, config) { 25549 if (weekdayStr) { 25550 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. 25551 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), 25552 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); 25553 if (weekdayProvided !== weekdayActual) { 25554 getParsingFlags(config).weekdayMismatch = true; 25555 config._isValid = false; 25556 return false; 25557 } 25558 } 25559 return true; 25560} 25561 25562var obsOffsets = { 25563 UT: 0, 25564 GMT: 0, 25565 EDT: -4 * 60, 25566 EST: -5 * 60, 25567 CDT: -5 * 60, 25568 CST: -6 * 60, 25569 MDT: -6 * 60, 25570 MST: -7 * 60, 25571 PDT: -7 * 60, 25572 PST: -8 * 60 25573}; 25574 25575function calculateOffset(obsOffset, militaryOffset, numOffset) { 25576 if (obsOffset) { 25577 return obsOffsets[obsOffset]; 25578 } else if (militaryOffset) { 25579 // the only allowed military tz is Z 25580 return 0; 25581 } else { 25582 var hm = parseInt(numOffset, 10); 25583 var m = hm % 100, h = (hm - m) / 100; 25584 return h * 60 + m; 25585 } 25586} 25587 25588// date and time from ref 2822 format 25589function configFromRFC2822(config) { 25590 var match = rfc2822.exec(preprocessRFC2822(config._i)); 25591 if (match) { 25592 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); 25593 if (!checkWeekday(match[1], parsedArray, config)) { 25594 return; 25595 } 25596 25597 config._a = parsedArray; 25598 config._tzm = calculateOffset(match[8], match[9], match[10]); 25599 25600 config._d = createUTCDate.apply(null, config._a); 25601 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); 25602 25603 getParsingFlags(config).rfc2822 = true; 25604 } else { 25605 config._isValid = false; 25606 } 25607} 25608 25609// date from iso format or fallback 25610function configFromString(config) { 25611 var matched = aspNetJsonRegex.exec(config._i); 25612 25613 if (matched !== null) { 25614 config._d = new Date(+matched[1]); 25615 return; 25616 } 25617 25618 configFromISO(config); 25619 if (config._isValid === false) { 25620 delete config._isValid; 25621 } else { 25622 return; 25623 } 25624 25625 configFromRFC2822(config); 25626 if (config._isValid === false) { 25627 delete config._isValid; 25628 } else { 25629 return; 25630 } 25631 25632 // Final attempt, use Input Fallback 25633 hooks.createFromInputFallback(config); 25634} 25635 25636hooks.createFromInputFallback = deprecate( 25637 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + 25638 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + 25639 'discouraged and will be removed in an upcoming major release. Please refer to ' + 25640 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', 25641 function (config) { 25642 config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); 25643 } 25644); 25645 25646// constant that refers to the ISO standard 25647hooks.ISO_8601 = function () {}; 25648 25649// constant that refers to the RFC 2822 form 25650hooks.RFC_2822 = function () {}; 25651 25652// date from string and format string 25653function configFromStringAndFormat(config) { 25654 // TODO: Move this to another part of the creation flow to prevent circular deps 25655 if (config._f === hooks.ISO_8601) { 25656 configFromISO(config); 25657 return; 25658 } 25659 if (config._f === hooks.RFC_2822) { 25660 configFromRFC2822(config); 25661 return; 25662 } 25663 config._a = []; 25664 getParsingFlags(config).empty = true; 25665 25666 // This array is used to make a Date, either with `new Date` or `Date.UTC` 25667 var string = '' + config._i, 25668 i, parsedInput, tokens, token, skipped, 25669 stringLength = string.length, 25670 totalParsedInputLength = 0; 25671 25672 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; 25673 25674 for (i = 0; i < tokens.length; i++) { 25675 token = tokens[i]; 25676 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; 25677 // console.log('token', token, 'parsedInput', parsedInput, 25678 // 'regex', getParseRegexForToken(token, config)); 25679 if (parsedInput) { 25680 skipped = string.substr(0, string.indexOf(parsedInput)); 25681 if (skipped.length > 0) { 25682 getParsingFlags(config).unusedInput.push(skipped); 25683 } 25684 string = string.slice(string.indexOf(parsedInput) + parsedInput.length); 25685 totalParsedInputLength += parsedInput.length; 25686 } 25687 // don't parse if it's not a known token 25688 if (formatTokenFunctions[token]) { 25689 if (parsedInput) { 25690 getParsingFlags(config).empty = false; 25691 } 25692 else { 25693 getParsingFlags(config).unusedTokens.push(token); 25694 } 25695 addTimeToArrayFromToken(token, parsedInput, config); 25696 } 25697 else if (config._strict && !parsedInput) { 25698 getParsingFlags(config).unusedTokens.push(token); 25699 } 25700 } 25701 25702 // add remaining unparsed input length to the string 25703 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; 25704 if (string.length > 0) { 25705 getParsingFlags(config).unusedInput.push(string); 25706 } 25707 25708 // clear _12h flag if hour is <= 12 25709 if (config._a[HOUR] <= 12 && 25710 getParsingFlags(config).bigHour === true && 25711 config._a[HOUR] > 0) { 25712 getParsingFlags(config).bigHour = undefined; 25713 } 25714 25715 getParsingFlags(config).parsedDateParts = config._a.slice(0); 25716 getParsingFlags(config).meridiem = config._meridiem; 25717 // handle meridiem 25718 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); 25719 25720 configFromArray(config); 25721 checkOverflow(config); 25722} 25723 25724 25725function meridiemFixWrap (locale, hour, meridiem) { 25726 var isPm; 25727 25728 if (meridiem == null) { 25729 // nothing to do 25730 return hour; 25731 } 25732 if (locale.meridiemHour != null) { 25733 return locale.meridiemHour(hour, meridiem); 25734 } else if (locale.isPM != null) { 25735 // Fallback 25736 isPm = locale.isPM(meridiem); 25737 if (isPm && hour < 12) { 25738 hour += 12; 25739 } 25740 if (!isPm && hour === 12) { 25741 hour = 0; 25742 } 25743 return hour; 25744 } else { 25745 // this is not supposed to happen 25746 return hour; 25747 } 25748} 25749 25750// date from string and array of format strings 25751function configFromStringAndArray(config) { 25752 var tempConfig, 25753 bestMoment, 25754 25755 scoreToBeat, 25756 i, 25757 currentScore; 25758 25759 if (config._f.length === 0) { 25760 getParsingFlags(config).invalidFormat = true; 25761 config._d = new Date(NaN); 25762 return; 25763 } 25764 25765 for (i = 0; i < config._f.length; i++) { 25766 currentScore = 0; 25767 tempConfig = copyConfig({}, config); 25768 if (config._useUTC != null) { 25769 tempConfig._useUTC = config._useUTC; 25770 } 25771 tempConfig._f = config._f[i]; 25772 configFromStringAndFormat(tempConfig); 25773 25774 if (!isValid
vendor: 9,914 bytes, lines 25774-26130
25774(tempConfig)) { 25775 continue; 25776 } 25777 25778 // if there is any input that was not parsed add a penalty for that format 25779 currentScore += getParsingFlags(tempConfig).charsLeftOver; 25780 25781 //or tokens 25782 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; 25783 25784 getParsingFlags(tempConfig).score = currentScore; 25785 25786 if (scoreToBeat == null || currentScore < scoreToBeat) { 25787 scoreToBeat = currentScore; 25788 bestMoment = tempConfig; 25789 } 25790 } 25791 25792 extend(config, bestMoment || tempConfig); 25793} 25794 25795function configFromObject(config) { 25796 if (config._d) { 25797 return; 25798 } 25799 25800 var i = normalizeObjectUnits(config._i); 25801 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { 25802 return obj && parseInt(obj, 10); 25803 }); 25804 25805 configFromArray(config); 25806} 25807 25808function createFromConfig (config) { 25809 var res = new Moment(checkOverflow(prepareConfig(config))); 25810 if (res._nextDay) { 25811 // Adding is smart enough around DST 25812 res.add(1, 'd'); 25813 res._nextDay = undefined; 25814 } 25815 25816 return res; 25817} 25818 25819function prepareConfig (config) { 25820 var input = config._i, 25821 format = config._f; 25822 25823 config._locale = config._locale || getLocale(config._l); 25824 25825 if (input === null || (format === undefined && input === '')) { 25826 return createInvalid({nullInput: true}); 25827 } 25828 25829 if (typeof input === 'string') { 25830 config._i = input = config._locale.preparse(input); 25831 } 25832 25833 if (isMoment(input)) { 25834 return new Moment(checkOverflow(input)); 25835 } else if (isDate(input)) { 25836 config._d = input; 25837 } else if (isArray(format)) { 25838 configFromStringAndArray(config); 25839 } else if (format) { 25840 configFromStringAndFormat(config); 25841 } else { 25842 configFromInput(config); 25843 } 25844 25845 if (!isValid(config)) { 25846 config._d = null; 25847 } 25848 25849 return config; 25850} 25851 25852function configFromInput(config) { 25853 var input = config._i; 25854 if (isUndefined(input)) { 25855 config._d = new Date(hooks.now()); 25856 } else if (isDate(input)) { 25857 config._d = new Date(input.valueOf()); 25858 } else if (typeof input === 'string') { 25859 configFromString(config); 25860 } else if (isArray(input)) { 25861 config._a = map(input.slice(0), function (obj) { 25862 return parseInt(obj, 10); 25863 }); 25864 configFromArray(config); 25865 } else if (isObject(input)) { 25866 configFromObject(config); 25867 } else if (isNumber(input)) { 25868 // from milliseconds 25869 config._d = new Date(input); 25870 } else { 25871 hooks.createFromInputFallback(config); 25872 } 25873} 25874 25875function createLocalOrUTC (input, format, locale, strict, isUTC) { 25876 var c = {}; 25877 25878 if (locale === true || locale === false) { 25879 strict = locale; 25880 locale = undefined; 25881 } 25882 25883 if ((isObject(input) && isObjectEmpty(input)) || 25884 (isArray(input) && input.length === 0)) { 25885 input = undefined; 25886 } 25887 // object construction must be done this way. 25888 // https://github.com/moment/moment/issues/1423 25889 c._isAMomentObject = true; 25890 c._useUTC = c._isUTC = isUTC; 25891 c._l = locale; 25892 c._i = input; 25893 c._f = format; 25894 c._strict = strict; 25895 25896 return createFromConfig(c); 25897} 25898 25899function createLocal (input, format, locale, strict) { 25900 return createLocalOrUTC(input, format, locale, strict, false); 25901} 25902 25903var prototypeMin = deprecate( 25904 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', 25905 function () { 25906 var other = createLocal.apply(null, arguments); 25907 if (this.isValid() && other.isValid()) { 25908 return other < this ? this : other; 25909 } else { 25910 return createInvalid(); 25911 } 25912 } 25913); 25914 25915var prototypeMax = deprecate( 25916 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', 25917 function () { 25918 var other = createLocal.apply(null, arguments); 25919 if (this.isValid() && other.isValid()) { 25920 return other > this ? this : other; 25921 } else { 25922 return createInvalid(); 25923 } 25924 } 25925); 25926 25927// Pick a moment m from moments so that m[fn](other) is true for all 25928// other. This relies on the function fn to be transitive. 25929// 25930// moments should either be an array of moment objects or an array, whose 25931// first element is an array of moment objects. 25932function pickBy(fn, moments) { 25933 var res, i; 25934 if (moments.length === 1 && isArray(moments[0])) { 25935 moments = moments[0]; 25936 } 25937 if (!moments.length) { 25938 return createLocal(); 25939 } 25940 res = moments[0]; 25941 for (i = 1; i < moments.length; ++i) { 25942 if (!moments[i].isValid() || moments[i][fn](res)) { 25943 res = moments[i]; 25944 } 25945 } 25946 return res; 25947} 25948 25949// TODO: Use [].sort instead? 25950function min () { 25951 var args = [].slice.call(arguments, 0); 25952 25953 return pickBy('isBefore', args); 25954} 25955 25956function max () { 25957 var args = [].slice.call(arguments, 0); 25958 25959 return pickBy('isAfter', args); 25960} 25961 25962var now = function () { 25963 return Date.now ? Date.now() : +(new Date()); 25964}; 25965 25966var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; 25967 25968function isDurationValid(m) { 25969 for (var key in m) { 25970 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { 25971 return false; 25972 } 25973 } 25974 25975 var unitHasDecimal = false; 25976 for (var i = 0; i < ordering.length; ++i) { 25977 if (m[ordering[i]]) { 25978 if (unitHasDecimal) { 25979 return false; // only allow non-integers for smallest unit 25980 } 25981 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { 25982 unitHasDecimal = true; 25983 } 25984 } 25985 } 25986 25987 return true; 25988} 25989 25990function isValid$1() { 25991 return this._isValid; 25992} 25993 25994function createInvalid$1() { 25995 return createDuration(NaN); 25996} 25997 25998function Duration (duration) { 25999 var normalizedInput = normalizeObjectUnits(duration), 26000 years = normalizedInput.year || 0, 26001 quarters = normalizedInput.quarter || 0, 26002 months = normalizedInput.month || 0, 26003 weeks = normalizedInput.week || 0, 26004 days = normalizedInput.day || 0, 26005 hours = normalizedInput.hour || 0, 26006 minutes = normalizedInput.minute || 0, 26007 seconds = normalizedInput.second || 0, 26008 milliseconds = normalizedInput.millisecond || 0; 26009 26010 this._isValid = isDurationValid(normalizedInput); 26011 26012 // representation for dateAddRemove 26013 this._milliseconds = +milliseconds + 26014 seconds * 1e3 + // 1000 26015 minutes * 6e4 + // 1000 * 60 26016 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 26017 // Because of dateAddRemove treats 24 hours as different from a 26018 // day when working around DST, we need to store them separately 26019 this._days = +days + 26020 weeks * 7; 26021 // It is impossible to translate months into days without knowing 26022 // which months you are are talking about, so we have to store 26023 // it separately. 26024 this._months = +months + 26025 quarters * 3 + 26026 years * 12; 26027 26028 this._data = {}; 26029 26030 this._locale = getLocale(); 26031 26032 this._bubble(); 26033} 26034 26035function isDuration (obj) { 26036 return obj instanceof Duration; 26037} 26038 26039function absRound (number) { 26040 if (number < 0) { 26041 return Math.round(-1 * number) * -1; 26042 } else { 26043 return Math.round(number); 26044 } 26045} 26046 26047// FORMATTING 26048 26049function offset (token, separator) { 26050 addFormatToken(token, 0, 0, function () { 26051 var offset = this.utcOffset(); 26052 var sign = '+'; 26053 if (offset < 0) { 26054 offset = -offset; 26055 sign = '-'; 26056 } 26057 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); 26058 }); 26059} 26060 26061offset('Z', ':'); 26062offset('ZZ', ''); 26063 26064// PARSING 26065 26066addRegexToken('Z', matchShortOffset); 26067addRegexToken('ZZ', matchShortOffset); 26068addParseToken(['Z', 'ZZ'], function (input, array, config) { 26069 config._useUTC = true; 26070 config._tzm = offsetFromString(matchShortOffset, input); 26071}); 26072 26073// HELPERS 26074 26075// timezone chunker 26076// '+10:00' > ['10', '00'] 26077// '-1530' > ['-15', '30'] 26078var chunkOffset = /([\+\-]|\d\d)/gi; 26079 26080function offsetFromString(matcher, string) { 26081 var matches = (string || '').match(matcher); 26082 26083 if (matches === null) { 26084 return null; 26085 } 26086 26087 var chunk = matches[matches.length - 1] || []; 26088 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; 26089 var minutes = +(parts[1] * 60) + toInt(parts[2]); 26090 26091 return minutes === 0 ? 26092 0 : 26093 parts[0] === '+' ? minutes : -minutes; 26094} 26095 26096// Return a moment from input, that is local/utc/zone equivalent to model. 26097function cloneWithOffset(input, model) { 26098 var res, diff; 26099 if (model._isUTC) { 26100 res = model.clone(); 26101 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); 26102 // Use low-level api, because this fn is low-level api. 26103 res._d.setTime(res._d.valueOf() + diff); 26104 hooks.updateOffset(res, false); 26105 return res; 26106 } else { 26107 return createLocal(input).local(); 26108 } 26109} 26110 26111function getDateOffset (m) { 26112 // On Firefox.24 Date#getTimezoneOffset returns a floating point. 26113 // https://github.com/moment/moment/pull/1871 26114 return -Math.round(m._d.getTimezoneOffset() / 15) * 15; 26115} 26116 26117// HOOKS 26118 26119// This function will be called whenever a moment is mutated. 26120// It is intended to keep the offset in sync with the timezone. 26121hooks.updateOffset = function () {}; 26122 26123// MOMENTS 26124 26125// keepLocalTime = true means only change the timezone, without 26126// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> 26127// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset 26128// +0200, so we adjust the time as needed, to be valid. 26129// 26130// Keeping the time actually adds/subtracts (one hour)
vendor: 19,497 bytes, lines 26131-26782
26131// from the actual represented time. That is why we call updateOffset 26132// a second time. In case it wants us to change the offset again 26133// _changeInProgress == true case, then we have to adjust, because 26134// there is no such time in the given timezone. 26135function getSetOffset (input, keepLocalTime, keepMinutes) { 26136 var offset = this._offset || 0, 26137 localAdjust; 26138 if (!this.isValid()) { 26139 return input != null ? this : NaN; 26140 } 26141 if (input != null) { 26142 if (typeof input === 'string') { 26143 input = offsetFromString(matchShortOffset, input); 26144 if (input === null) { 26145 return this; 26146 } 26147 } else if (Math.abs(input) < 16 && !keepMinutes) { 26148 input = input * 60; 26149 } 26150 if (!this._isUTC && keepLocalTime) { 26151 localAdjust = getDateOffset(this); 26152 } 26153 this._offset = input; 26154 this._isUTC = true; 26155 if (localAdjust != null) { 26156 this.add(localAdjust, 'm'); 26157 } 26158 if (offset !== input) { 26159 if (!keepLocalTime || this._changeInProgress) { 26160 addSubtract(this, createDuration(input - offset, 'm'), 1, false); 26161 } else if (!this._changeInProgress) { 26162 this._changeInProgress = true; 26163 hooks.updateOffset(this, true); 26164 this._changeInProgress = null; 26165 } 26166 } 26167 return this; 26168 } else { 26169 return this._isUTC ? offset : getDateOffset(this); 26170 } 26171} 26172 26173function getSetZone (input, keepLocalTime) { 26174 if (input != null) { 26175 if (typeof input !== 'string') { 26176 input = -input; 26177 } 26178 26179 this.utcOffset(input, keepLocalTime); 26180 26181 return this; 26182 } else { 26183 return -this.utcOffset(); 26184 } 26185} 26186 26187function setOffsetToUTC (keepLocalTime) { 26188 return this.utcOffset(0, keepLocalTime); 26189} 26190 26191function setOffsetToLocal (keepLocalTime) { 26192 if (this._isUTC) { 26193 this.utcOffset(0, keepLocalTime); 26194 this._isUTC = false; 26195 26196 if (keepLocalTime) { 26197 this.subtract(getDateOffset(this), 'm'); 26198 } 26199 } 26200 return this; 26201} 26202 26203function setOffsetToParsedOffset () { 26204 if (this._tzm != null) { 26205 this.utcOffset(this._tzm, false, true); 26206 } else if (typeof this._i === 'string') { 26207 var tZone = offsetFromString(matchOffset, this._i); 26208 if (tZone != null) { 26209 this.utcOffset(tZone); 26210 } 26211 else { 26212 this.utcOffset(0, true); 26213 } 26214 } 26215 return this; 26216} 26217 26218function hasAlignedHourOffset (input) { 26219 if (!this.isValid()) { 26220 return false; 26221 } 26222 input = input ? createLocal(input).utcOffset() : 0; 26223 26224 return (this.utcOffset() - input) % 60 === 0; 26225} 26226 26227function isDaylightSavingTime () { 26228 return ( 26229 this.utcOffset() > this.clone().month(0).utcOffset() || 26230 this.utcOffset() > this.clone().month(5).utcOffset() 26231 ); 26232} 26233 26234function isDaylightSavingTimeShifted () { 26235 if (!isUndefined(this._isDSTShifted)) { 26236 return this._isDSTShifted; 26237 } 26238 26239 var c = {}; 26240 26241 copyConfig(c, this); 26242 c = prepareConfig(c); 26243 26244 if (c._a) { 26245 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); 26246 this._isDSTShifted = this.isValid() && 26247 compareArrays(c._a, other.toArray()) > 0; 26248 } else { 26249 this._isDSTShifted = false; 26250 } 26251 26252 return this._isDSTShifted; 26253} 26254 26255function isLocal () { 26256 return this.isValid() ? !this._isUTC : false; 26257} 26258 26259function isUtcOffset () { 26260 return this.isValid() ? this._isUTC : false; 26261} 26262 26263function isUtc () { 26264 return this.isValid() ? this._isUTC && this._offset === 0 : false; 26265} 26266 26267// ASP.NET json date format regex 26268var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; 26269 26270// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html 26271// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere 26272// and further modified to allow for strings containing both week and day 26273var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; 26274 26275function createDuration (input, key) { 26276 var duration = input, 26277 // matching against regexp is expensive, do it on demand 26278 match = null, 26279 sign, 26280 ret, 26281 diffRes; 26282 26283 if (isDuration(input)) { 26284 duration = { 26285 ms : input._milliseconds, 26286 d : input._days, 26287 M : input._months 26288 }; 26289 } else if (isNumber(input)) { 26290 duration = {}; 26291 if (key) { 26292 duration[key] = input; 26293 } else { 26294 duration.milliseconds = input; 26295 } 26296 } else if (!!(match = aspNetRegex.exec(input))) { 26297 sign = (match[1] === '-') ? -1 : 1; 26298 duration = { 26299 y : 0, 26300 d : toInt(match[DATE]) * sign, 26301 h : toInt(match[HOUR]) * sign, 26302 m : toInt(match[MINUTE]) * sign, 26303 s : toInt(match[SECOND]) * sign, 26304 ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match 26305 }; 26306 } else if (!!(match = isoRegex.exec(input))) { 26307 sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1; 26308 duration = { 26309 y : parseIso(match[2], sign), 26310 M : parseIso(match[3], sign), 26311 w : parseIso(match[4], sign), 26312 d : parseIso(match[5], sign), 26313 h : parseIso(match[6], sign), 26314 m : parseIso(match[7], sign), 26315 s : parseIso(match[8], sign) 26316 }; 26317 } else if (duration == null) {// checks for null or undefined 26318 duration = {}; 26319 } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { 26320 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); 26321 26322 duration = {}; 26323 duration.ms = diffRes.milliseconds; 26324 duration.M = diffRes.months; 26325 } 26326 26327 ret = new Duration(duration); 26328 26329 if (isDuration(input) && hasOwnProp(input, '_locale')) { 26330 ret._locale = input._locale; 26331 } 26332 26333 return ret; 26334} 26335 26336createDuration.fn = Duration.prototype; 26337createDuration.invalid = createInvalid$1; 26338 26339function parseIso (inp, sign) { 26340 // We'd normally use ~~inp for this, but unfortunately it also 26341 // converts floats to ints. 26342 // inp may be undefined, so careful calling replace on it. 26343 var res = inp && parseFloat(inp.replace(',', '.')); 26344 // apply sign while we're at it 26345 return (isNaN(res) ? 0 : res) * sign; 26346} 26347 26348function positiveMomentsDifference(base, other) { 26349 var res = {milliseconds: 0, months: 0}; 26350 26351 res.months = other.month() - base.month() + 26352 (other.year() - base.year()) * 12; 26353 if (base.clone().add(res.months, 'M').isAfter(other)) { 26354 --res.months; 26355 } 26356 26357 res.milliseconds = +other - +(base.clone().add(res.months, 'M')); 26358 26359 return res; 26360} 26361 26362function momentsDifference(base, other) { 26363 var res; 26364 if (!(base.isValid() && other.isValid())) { 26365 return {milliseconds: 0, months: 0}; 26366 } 26367 26368 other = cloneWithOffset(other, base); 26369 if (base.isBefore(other)) { 26370 res = positiveMomentsDifference(base, other); 26371 } else { 26372 res = positiveMomentsDifference(other, base); 26373 res.milliseconds = -res.milliseconds; 26374 res.months = -res.months; 26375 } 26376 26377 return res; 26378} 26379 26380// TODO: remove 'name' arg after deprecation is removed 26381function createAdder(direction, name) { 26382 return function (val, period) { 26383 var dur, tmp; 26384 //invert the arguments, but complain about it 26385 if (period !== null && !isNaN(+period)) { 26386 deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + 26387 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); 26388 tmp = val; val = period; period = tmp; 26389 } 26390 26391 val = typeof val === 'string' ? +val : val; 26392 dur = createDuration(val, period); 26393 addSubtract(this, dur, direction); 26394 return this; 26395 }; 26396} 26397 26398function addSubtract (mom, duration, isAdding, updateOffset) { 26399 var milliseconds = duration._milliseconds, 26400 days = absRound(duration._days), 26401 months = absRound(duration._months); 26402 26403 if (!mom.isValid()) { 26404 // No op 26405 return; 26406 } 26407 26408 updateOffset = updateOffset == null ? true : updateOffset; 26409 26410 if (months) { 26411 setMonth(mom, get(mom, 'Month') + months * isAdding); 26412 } 26413 if (days) { 26414 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); 26415 } 26416 if (milliseconds) { 26417 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); 26418 } 26419 if (updateOffset) { 26420 hooks.updateOffset(mom, days || months); 26421 } 26422} 26423 26424var add = createAdder(1, 'add'); 26425var subtract = createAdder(-1, 'subtract'); 26426 26427function getCalendarFormat(myMoment, now) { 26428 var diff = myMoment.diff(now, 'days', true); 26429 return diff < -6 ? 'sameElse' : 26430 diff < -1 ? 'lastWeek' : 26431 diff < 0 ? 'lastDay' : 26432 diff < 1 ? 'sameDay' : 26433 diff < 2 ? 'nextDay' : 26434 diff < 7 ? 'nextWeek' : 'sameElse'; 26435} 26436 26437function calendar$1 (time, formats) { 26438 // We want to compare the start of today, vs this. 26439 // Getting start-of-today depends on whether we're local/utc/offset or not. 26440 var now = time || createLocal(), 26441 sod = cloneWithOffset(now, this).startOf('day'), 26442 format = hooks.calendarFormat(this, sod) || 'sameElse'; 26443 26444 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); 26445 26446 return this.format(output || this.localeData().calendar(format, this, createLocal(now))); 26447} 26448 26449function clone () { 26450 return new Moment(this); 26451} 26452 26453function isAfter (input, units) { 26454 var localInput = isMoment(input) ? input : createLocal(input); 26455 if (!(this.isValid() && localInput.isValid())) { 26456 return false; 26457 } 26458 units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); 26459 if (units === 'millisecond') { 26460 return this.valueOf() > localInput.valueOf(); 26461 } else { 26462 return localInput.valueOf() < this.clone().startOf(units).valueOf(); 26463 } 26464} 26465 26466function isBefore (input, units) { 26467 var localInput = isMoment(input) ? input : createLocal(input); 26468 if (!(this.isValid() && localInput.isValid())) { 26469 return false; 26470 } 26471 units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); 26472 if (units === 'millisecond') { 26473 return this.valueOf() < localInput.valueOf(); 26474 } else { 26475 return this.clone().endOf(units).valueOf() < localInput.valueOf(); 26476 } 26477} 26478 26479function isBetween (from, to, units, inclusivity) { 26480 inclusivity = inclusivity || '()'; 26481 return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) && 26482 (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units)); 26483} 26484 26485function isSame (input, units) { 26486 var localInput = isMoment(input) ? input : createLocal(input), 26487 inputMs; 26488 if (!(this.isValid() && localInput.isValid())) { 26489 return false; 26490 } 26491 units = normalizeUnits(units || 'millisecond'); 26492 if (units === 'millisecond') { 26493 return this.valueOf() === localInput.valueOf(); 26494 } else { 26495 inputMs = localInput.valueOf(); 26496 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); 26497 } 26498} 26499 26500function isSameOrAfter (input, units) { 26501 return this.isSame(input, units) || this.isAfter(input,units); 26502} 26503 26504function isSameOrBefore (input, units) { 26505 return this.isSame(input, units) || this.isBefore(input,units); 26506} 26507 26508function diff (input, units, asFloat) { 26509 var that, 26510 zoneDelta, 26511 delta, output; 26512 26513 if (!this.isValid()) { 26514 return NaN; 26515 } 26516 26517 that = cloneWithOffset(input, this); 26518 26519 if (!that.isValid()) { 26520 return NaN; 26521 } 26522 26523 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; 26524 26525 units = normalizeUnits(units); 26526 26527 switch (units) { 26528 case 'year': output = monthDiff(this, that) / 12; break; 26529 case 'month': output = monthDiff(this, that); break; 26530 case 'quarter': output = monthDiff(this, that) / 3; break; 26531 case 'second': output = (this - that) / 1e3; break; // 1000 26532 case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 26533 case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 26534 case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst 26535 case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst 26536 default: output = this - that; 26537 } 26538 26539 return asFloat ? output : absFloor(output); 26540} 26541 26542function monthDiff (a, b) { 26543 // difference in months 26544 var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), 26545 // b is in (anchor - 1 month, anchor + 1 month) 26546 anchor = a.clone().add(wholeMonthDiff, 'months'), 26547 anchor2, adjust; 26548 26549 if (b - anchor < 0) { 26550 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); 26551 // linear across the month 26552 adjust = (b - anchor) / (anchor - anchor2); 26553 } else { 26554 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); 26555 // linear across the month 26556 adjust = (b - anchor) / (anchor2 - anchor); 26557 } 26558 26559 //check for negative zero, return zero if negative zero 26560 return -(wholeMonthDiff + adjust) || 0; 26561} 26562 26563hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; 26564hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; 26565 26566function toString () { 26567 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); 26568} 26569 26570function toISOString(keepOffset) { 26571 if (!this.isValid()) { 26572 return null; 26573 } 26574 var utc = keepOffset !== true; 26575 var m = utc ? this.clone().utc() : this; 26576 if (m.year() < 0 || m.year() > 9999) { 26577 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); 26578 } 26579 if (isFunction(Date.prototype.toISOString)) { 26580 // native implementation is ~50x faster, use it when we can 26581 if (utc) { 26582 return this.toDate().toISOString(); 26583 } else { 26584 return new Date(this._d.valueOf()).toISOString().replace('Z', formatMoment(m, 'Z')); 26585 } 26586 } 26587 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); 26588} 26589 26590/** 26591 * Return a human readable representation of a moment that can 26592 * also be evaluated to get a new moment which is the same 26593 * 26594 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects 26595 */ 26596function inspect () { 26597 if (!this.isValid()) { 26598 return 'moment.invalid(/* ' + this._i + ' */)'; 26599 } 26600 var func = 'moment'; 26601 var zone = ''; 26602 if (!this.isLocal()) { 26603 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; 26604 zone = 'Z'; 26605 } 26606 var prefix = '[' + func + '("]'; 26607 var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; 26608 var datetime = '-MM-DD[T]HH:mm:ss.SSS'; 26609 var suffix = zone + '[")]'; 26610 26611 return this.format(prefix + year + datetime + suffix); 26612} 26613 26614function format (inputString) { 26615 if (!inputString) { 26616 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; 26617 } 26618 var output = formatMoment(this, inputString); 26619 return this.localeData().postformat(output); 26620} 26621 26622function from (time, withoutSuffix) { 26623 if (this.isValid() && 26624 ((isMoment(time) && time.isValid()) || 26625 createLocal(time).isValid())) { 26626 return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); 26627 } else { 26628 return this.localeData().invalidDate(); 26629 } 26630} 26631 26632function fromNow (withoutSuffix) { 26633 return this.from(createLocal(), withoutSuffix); 26634} 26635 26636function to (time, withoutSuffix) { 26637 if (this.isValid() && 26638 ((isMoment(time) && time.isValid()) || 26639 createLocal(time).isValid())) { 26640 return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); 26641 } else { 26642 return this.localeData().invalidDate(); 26643 } 26644} 26645 26646function toNow (withoutSuffix) { 26647 return this.to(createLocal(), withoutSuffix); 26648} 26649 26650// If passed a locale key, it will set the locale for this 26651// instance. Otherwise, it will return the locale configuration 26652// variables for this instance. 26653function locale (key) { 26654 var newLocaleData; 26655 26656 if (key === undefined) { 26657 return this._locale._abbr; 26658 } else { 26659 newLocaleData = getLocale(key); 26660 if (newLocaleData != null) { 26661 this._locale = newLocaleData; 26662 } 26663 return this; 26664 } 26665} 26666 26667var lang = deprecate( 26668 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', 26669 function (key) { 26670 if (key === undefined) { 26671 return this.localeData(); 26672 } else { 26673 return this.locale(key); 26674 } 26675 } 26676); 26677 26678function localeData () { 26679 return this._locale; 26680} 26681 26682function startOf (units) { 26683 units = normalizeUnits(units); 26684 // the following switch intentionally omits break keywords 26685 // to utilize falling through the cases. 26686 switch (units) { 26687 case 'year': 26688 this.month(0); 26689 /* falls through */ 26690 case 'quarter': 26691 case 'month': 26692 this.date(1); 26693 /* falls through */ 26694 case 'week': 26695 case 'isoWeek': 26696 case 'day': 26697 case 'date': 26698 this.hours(0); 26699 /* falls through */ 26700 case 'hour': 26701 this.minutes(0); 26702 /* falls through */ 26703 case 'minute': 26704 this.seconds(0); 26705 /* falls through */ 26706 case 'second': 26707 this.milliseconds(0); 26708 } 26709 26710 // weeks are a special case 26711 if (units === 'week') { 26712 this.weekday(0); 26713 } 26714 if (units === 'isoWeek') { 26715 this.isoWeekday(1); 26716 } 26717 26718 // quarters are also special 26719 if (units === 'quarter') { 26720 this.month(Math.floor(this.month() / 3) * 3); 26721 } 26722 26723 return this; 26724} 26725 26726function endOf (units) { 26727 units = normalizeUnits(units); 26728 if (units === undefined || units === 'millisecond') { 26729 return this; 26730 } 26731 26732 // 'date' is an alias for 'day', so it should be considered as such. 26733 if (units === 'date') { 26734 units = 'day'; 26735 } 26736 26737 return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); 26738} 26739 26740function valueOf () { 26741 return this._d.valueOf() - ((this._offset || 0) * 60000); 26742} 26743 26744function unix () { 26745 return Math.floor(this.valueOf() / 1000); 26746} 26747 26748function toDate () { 26749 return new Date(this.valueOf()); 26750} 26751 26752function toArray () { 26753 var m = this; 26754 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; 26755} 26756 26757function toObject () { 26758 var m = this; 26759 return { 26760 years: m.year(), 26761 months: m.month(), 26762 date: m.date(), 26763 hours: m.hours(), 26764 minutes: m.minutes(), 26765 seconds: m.seconds(), 26766 milliseconds: m.milliseconds() 26767 }; 26768} 26769 26770function toJSON () { 26771 // new Date(NaN).toJSON() === null 26772 return this.isValid() ? this.toISOString() : null; 26773} 26774 26775function isValid$2 () { 26776 return isValid(this); 26777} 26778 26779function parsingFlags () { 26780 return extend({}, getParsingFlags(this)); 26781} 26782
vendor: 11,961 bytes, lines 26783-27254
26783function invalidAt () { 26784 return getParsingFlags(this).overflow; 26785} 26786 26787function creationData() { 26788 return { 26789 input: this._i, 26790 format: this._f, 26791 locale: this._locale, 26792 isUTC: this._isUTC, 26793 strict: this._strict 26794 }; 26795} 26796 26797// FORMATTING 26798 26799addFormatToken(0, ['gg', 2], 0, function () { 26800 return this.weekYear() % 100; 26801}); 26802 26803addFormatToken(0, ['GG', 2], 0, function () { 26804 return this.isoWeekYear() % 100; 26805}); 26806 26807function addWeekYearFormatToken (token, getter) { 26808 addFormatToken(0, [token, token.length], 0, getter); 26809} 26810 26811addWeekYearFormatToken('gggg', 'weekYear'); 26812addWeekYearFormatToken('ggggg', 'weekYear'); 26813addWeekYearFormatToken('GGGG', 'isoWeekYear'); 26814addWeekYearFormatToken('GGGGG', 'isoWeekYear'); 26815 26816// ALIASES 26817 26818addUnitAlias('weekYear', 'gg'); 26819addUnitAlias('isoWeekYear', 'GG'); 26820 26821// PRIORITY 26822 26823addUnitPriority('weekYear', 1); 26824addUnitPriority('isoWeekYear', 1); 26825 26826 26827// PARSING 26828 26829addRegexToken('G', matchSigned); 26830addRegexToken('g', matchSigned); 26831addRegexToken('GG', match1to2, match2); 26832addRegexToken('gg', match1to2, match2); 26833addRegexToken('GGGG', match1to4, match4); 26834addRegexToken('gggg', match1to4, match4); 26835addRegexToken('GGGGG', match1to6, match6); 26836addRegexToken('ggggg', match1to6, match6); 26837 26838addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { 26839 week[token.substr(0, 2)] = toInt(input); 26840}); 26841 26842addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { 26843 week[token] = hooks.parseTwoDigitYear(input); 26844}); 26845 26846// MOMENTS 26847 26848function getSetWeekYear (input) { 26849 return getSetWeekYearHelper.call(this, 26850 input, 26851 this.week(), 26852 this.weekday(), 26853 this.localeData()._week.dow, 26854 this.localeData()._week.doy); 26855} 26856 26857function getSetISOWeekYear (input) { 26858 return getSetWeekYearHelper.call(this, 26859 input, this.isoWeek(), this.isoWeekday(), 1, 4); 26860} 26861 26862function getISOWeeksInYear () { 26863 return weeksInYear(this.year(), 1, 4); 26864} 26865 26866function getWeeksInYear () { 26867 var weekInfo = this.localeData()._week; 26868 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); 26869} 26870 26871function getSetWeekYearHelper(input, week, weekday, dow, doy) { 26872 var weeksTarget; 26873 if (input == null) { 26874 return weekOfYear(this, dow, doy).year; 26875 } else { 26876 weeksTarget = weeksInYear(input, dow, doy); 26877 if (week > weeksTarget) { 26878 week = weeksTarget; 26879 } 26880 return setWeekAll.call(this, input, week, weekday, dow, doy); 26881 } 26882} 26883 26884function setWeekAll(weekYear, week, weekday, dow, doy) { 26885 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), 26886 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); 26887 26888 this.year(date.getUTCFullYear()); 26889 this.month(date.getUTCMonth()); 26890 this.date(date.getUTCDate()); 26891 return this; 26892} 26893 26894// FORMATTING 26895 26896addFormatToken('Q', 0, 'Qo', 'quarter'); 26897 26898// ALIASES 26899 26900addUnitAlias('quarter', 'Q'); 26901 26902// PRIORITY 26903 26904addUnitPriority('quarter', 7); 26905 26906// PARSING 26907 26908addRegexToken('Q', match1); 26909addParseToken('Q', function (input, array) { 26910 array[MONTH] = (toInt(input) - 1) * 3; 26911}); 26912 26913// MOMENTS 26914 26915function getSetQuarter (input) { 26916 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); 26917} 26918 26919// FORMATTING 26920 26921addFormatToken('D', ['DD', 2], 'Do', 'date'); 26922 26923// ALIASES 26924 26925addUnitAlias('date', 'D'); 26926 26927// PRIOROITY 26928addUnitPriority('date', 9); 26929 26930// PARSING 26931 26932addRegexToken('D', match1to2); 26933addRegexToken('DD', match1to2, match2); 26934addRegexToken('Do', function (isStrict, locale) { 26935 // TODO: Remove "ordinalParse" fallback in next major release. 26936 return isStrict ? 26937 (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : 26938 locale._dayOfMonthOrdinalParseLenient; 26939}); 26940 26941addParseToken(['D', 'DD'], DATE); 26942addParseToken('Do', function (input, array) { 26943 array[DATE] = toInt(input.match(match1to2)[0]); 26944}); 26945 26946// MOMENTS 26947 26948var getSetDayOfMonth = makeGetSet('Date', true); 26949 26950// FORMATTING 26951 26952addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); 26953 26954// ALIASES 26955 26956addUnitAlias('dayOfYear', 'DDD'); 26957 26958// PRIORITY 26959addUnitPriority('dayOfYear', 4); 26960 26961// PARSING 26962 26963addRegexToken('DDD', match1to3); 26964addRegexToken('DDDD', match3); 26965addParseToken(['DDD', 'DDDD'], function (input, array, config) { 26966 config._dayOfYear = toInt(input); 26967}); 26968 26969// HELPERS 26970 26971// MOMENTS 26972 26973function getSetDayOfYear (input) { 26974 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; 26975 return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); 26976} 26977 26978// FORMATTING 26979 26980addFormatToken('m', ['mm', 2], 0, 'minute'); 26981 26982// ALIASES 26983 26984addUnitAlias('minute', 'm'); 26985 26986// PRIORITY 26987 26988addUnitPriority('minute', 14); 26989 26990// PARSING 26991 26992addRegexToken('m', match1to2); 26993addRegexToken('mm', match1to2, match2); 26994addParseToken(['m', 'mm'], MINUTE); 26995 26996// MOMENTS 26997 26998var getSetMinute = makeGetSet('Minutes', false); 26999 27000// FORMATTING 27001 27002addFormatToken('s', ['ss', 2], 0, 'second'); 27003 27004// ALIASES 27005 27006addUnitAlias('second', 's'); 27007 27008// PRIORITY 27009 27010addUnitPriority('second', 15); 27011 27012// PARSING 27013 27014addRegexToken('s', match1to2); 27015addRegexToken('ss', match1to2, match2); 27016addParseToken(['s', 'ss'], SECOND); 27017 27018// MOMENTS 27019 27020var getSetSecond = makeGetSet('Seconds', false); 27021 27022// FORMATTING 27023 27024addFormatToken('S', 0, 0, function () { 27025 return ~~(this.millisecond() / 100); 27026}); 27027 27028addFormatToken(0, ['SS', 2], 0, function () { 27029 return ~~(this.millisecond() / 10); 27030}); 27031 27032addFormatToken(0, ['SSS', 3], 0, 'millisecond'); 27033addFormatToken(0, ['SSSS', 4], 0, function () { 27034 return this.millisecond() * 10; 27035}); 27036addFormatToken(0, ['SSSSS', 5], 0, function () { 27037 return this.millisecond() * 100; 27038}); 27039addFormatToken(0, ['SSSSSS', 6], 0, function () { 27040 return this.millisecond() * 1000; 27041}); 27042addFormatToken(0, ['SSSSSSS', 7], 0, function () { 27043 return this.millisecond() * 10000; 27044}); 27045addFormatToken(0, ['SSSSSSSS', 8], 0, function () { 27046 return this.millisecond() * 100000; 27047}); 27048addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { 27049 return this.millisecond() * 1000000; 27050}); 27051 27052 27053// ALIASES 27054 27055addUnitAlias('millisecond', 'ms'); 27056 27057// PRIORITY 27058 27059addUnitPriority('millisecond', 16); 27060 27061// PARSING 27062 27063addRegexToken('S', match1to3, match1); 27064addRegexToken('SS', match1to3, match2); 27065addRegexToken('SSS', match1to3, match3); 27066 27067var token; 27068for (token = 'SSSS'; token.length <= 9; token += 'S') { 27069 addRegexToken(token, matchUnsigned); 27070} 27071 27072function parseMs(input, array) { 27073 array[MILLISECOND] = toInt(('0.' + input) * 1000); 27074} 27075 27076for (token = 'S'; token.length <= 9; token += 'S') { 27077 addParseToken(token, parseMs); 27078} 27079// MOMENTS 27080 27081var getSetMillisecond = makeGetSet('Milliseconds', false); 27082 27083// FORMATTING 27084 27085addFormatToken('z', 0, 0, 'zoneAbbr'); 27086addFormatToken('zz', 0, 0, 'zoneName'); 27087 27088// MOMENTS 27089 27090function getZoneAbbr () { 27091 return this._isUTC ? 'UTC' : ''; 27092} 27093 27094function getZoneName () { 27095 return this._isUTC ? 'Coordinated Universal Time' : ''; 27096} 27097 27098var proto = Moment.prototype; 27099 27100proto.add = add; 27101proto.calendar = calendar$1; 27102proto.clone = clone; 27103proto.diff = diff; 27104proto.endOf = endOf; 27105proto.format = format; 27106proto.from = from; 27107proto.fromNow = fromNow; 27108proto.to = to; 27109proto.toNow = toNow; 27110proto.get = stringGet; 27111proto.invalidAt = invalidAt; 27112proto.isAfter = isAfter; 27113proto.isBefore = isBefore; 27114proto.isBetween = isBetween; 27115proto.isSame = isSame; 27116proto.isSameOrAfter = isSameOrAfter; 27117proto.isSameOrBefore = isSameOrBefore; 27118proto.isValid = isValid$2; 27119proto.lang = lang; 27120proto.locale = locale; 27121proto.localeData = localeData; 27122proto.max = prototypeMax; 27123proto.min = prototypeMin; 27124proto.parsingFlags = parsingFlags; 27125proto.set = stringSet; 27126proto.startOf = startOf; 27127proto.subtract = subtract; 27128proto.toArray = toArray; 27129proto.toObject = toObject; 27130proto.toDate = toDate; 27131proto.toISOString = toISOString; 27132proto.inspect = inspect; 27133proto.toJSON = toJSON; 27134proto.toString = toString; 27135proto.unix = unix; 27136proto.valueOf = valueOf; 27137proto.creationData = creationData; 27138 27139// Year 27140proto.year = getSetYear; 27141proto.isLeapYear = getIsLeapYear; 27142 27143// Week Year 27144proto.weekYear = getSetWeekYear; 27145proto.isoWeekYear = getSetISOWeekYear; 27146 27147// Quarter 27148proto.quarter = proto.quarters = getSetQuarter; 27149 27150// Month 27151proto.month = getSetMonth; 27152proto.daysInMonth = getDaysInMonth; 27153 27154// Week 27155proto.week = proto.weeks = getSetWeek; 27156proto.isoWeek = proto.isoWeeks = getSetISOWeek; 27157proto.weeksInYear = getWeeksInYear; 27158proto.isoWeeksInYear = getISOWeeksInYear; 27159 27160// Day 27161proto.date = getSetDayOfMonth; 27162proto.day = proto.days = getSetDayOfWeek; 27163proto.weekday = getSetLocaleDayOfWeek; 27164proto.isoWeekday = getSetISODayOfWeek; 27165proto.dayOfYear = getSetDayOfYear; 27166 27167// Hour 27168proto.hour = proto.hours = getSetHour; 27169 27170// Minute 27171proto.minute = proto.minutes = getSetMinute; 27172 27173// Second 27174proto.second = proto.seconds = getSetSecond; 27175 27176// Millisecond 27177proto.millisecond = proto.milliseconds = getSetMillisecond; 27178 27179// Offset 27180proto.utcOffset = getSetOffset; 27181proto.utc = setOffsetToUTC; 27182proto.local = setOffsetToLocal; 27183proto.parseZone = setOffsetToParsedOffset; 27184proto.hasAlignedHourOffset = hasAlignedHourOffset; 27185proto.isDST = isDaylightSavingTime; 27186proto.isLocal = isLocal; 27187proto.isUtcOffset = isUtcOffset; 27188proto.isUtc = isUtc; 27189proto.isUTC = isUtc; 27190 27191// Timezone 27192proto.zoneAbbr = getZoneAbbr; 27193proto.zoneName = getZoneName; 27194 27195// Deprecations 27196proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); 27197proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); 27198proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); 27199proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); 27200proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); 27201 27202function createUnix (input) { 27203 return createLocal(input * 1000); 27204} 27205 27206function createInZone () { 27207 return createLocal.apply(null, arguments).parseZone(); 27208} 27209 27210function preParsePostFormat (string) { 27211 return string; 27212} 27213 27214var proto$1 = Locale.prototype; 27215 27216proto$1.calendar = calendar; 27217proto$1.longDateFormat = longDateFormat; 27218proto$1.invalidDate = invalidDate; 27219proto$1.ordinal = ordinal; 27220proto$1.preparse = preParsePostFormat; 27221proto$1.postformat = preParsePostFormat; 27222proto$1.relativeTime = relativeTime; 27223proto$1.pastFuture = pastFuture; 27224proto$1.set = set; 27225 27226// Month 27227proto$1.months = localeMonths; 27228proto$1.monthsShort = localeMonthsShort; 27229proto$1.monthsParse = localeMonthsParse; 27230proto$1.monthsRegex = monthsRegex; 27231proto$1.monthsShortRegex = monthsShortRegex; 27232 27233// Week 27234proto$1.week = localeWeek; 27235proto$1.firstDayOfYear = localeFirstDayOfYear; 27236proto$1.firstDayOfWeek = localeFirstDayOfWeek; 27237 27238// Day of Week 27239proto$1.weekdays = localeWeekdays; 27240proto$1.weekdaysMin = localeWeekdaysMin; 27241proto$1.weekdaysShort = localeWeekdaysShort; 27242proto$1.weekdaysParse = localeWeekdaysParse; 27243 27244proto$1.weekdaysRegex = weekdaysRegex; 27245proto$1.weekdaysShortRegex = weekdaysShortRegex; 27246proto$1.weekdaysMinRegex = weekdaysMinRegex; 27247 27248// Hours 27249proto$1.isPM = localeIsPM; 27250proto$1.meridiem = localeMeridiem; 27251 27252function get$1 (format, index, field, setter) { 27253 var locale = getLocale(); 27254 var utc = createUTC().set(setter, index);
vendor: 7,931 bytes, lines 27255-27547
27255 return locale[field](utc, format); 27256} 27257 27258function listMonthsImpl (format, index, field) { 27259 if (isNumber(format)) { 27260 index = format; 27261 format = undefined; 27262 } 27263 27264 format = format || ''; 27265 27266 if (index != null) { 27267 return get$1(format, index, field, 'month'); 27268 } 27269 27270 var i; 27271 var out = []; 27272 for (i = 0; i < 12; i++) { 27273 out[i] = get$1(format, i, field, 'month'); 27274 } 27275 return out; 27276} 27277 27278// () 27279// (5) 27280// (fmt, 5) 27281// (fmt) 27282// (true) 27283// (true, 5) 27284// (true, fmt, 5) 27285// (true, fmt) 27286function listWeekdaysImpl (localeSorted, format, index, field) { 27287 if (typeof localeSorted === 'boolean') { 27288 if (isNumber(format)) { 27289 index = format; 27290 format = undefined; 27291 } 27292 27293 format = format || ''; 27294 } else { 27295 format = localeSorted; 27296 index = format; 27297 localeSorted = false; 27298 27299 if (isNumber(format)) { 27300 index = format; 27301 format = undefined; 27302 } 27303 27304 format = format || ''; 27305 } 27306 27307 var locale = getLocale(), 27308 shift = localeSorted ? locale._week.dow : 0; 27309 27310 if (index != null) { 27311 return get$1(format, (index + shift) % 7, field, 'day'); 27312 } 27313 27314 var i; 27315 var out = []; 27316 for (i = 0; i < 7; i++) { 27317 out[i] = get$1(format, (i + shift) % 7, field, 'day'); 27318 } 27319 return out; 27320} 27321 27322function listMonths (format, index) { 27323 return listMonthsImpl(format, index, 'months'); 27324} 27325 27326function listMonthsShort (format, index) { 27327 return listMonthsImpl(format, index, 'monthsShort'); 27328} 27329 27330function listWeekdays (localeSorted, format, index) { 27331 return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); 27332} 27333 27334function listWeekdaysShort (localeSorted, format, index) { 27335 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); 27336} 27337 27338function listWeekdaysMin (localeSorted, format, index) { 27339 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); 27340} 27341 27342getSetGlobalLocale('en', { 27343 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, 27344 ordinal : function (number) { 27345 var b = number % 10, 27346 output = (toInt(number % 100 / 10) === 1) ? 'th' : 27347 (b === 1) ? 'st' : 27348 (b === 2) ? 'nd' : 27349 (b === 3) ? 'rd' : 'th'; 27350 return number + output; 27351 } 27352}); 27353 27354// Side effect imports 27355hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); 27356hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); 27357 27358var mathAbs = Math.abs; 27359 27360function abs () { 27361 var data = this._data; 27362 27363 this._milliseconds = mathAbs(this._milliseconds); 27364 this._days = mathAbs(this._days); 27365 this._months = mathAbs(this._months); 27366 27367 data.milliseconds = mathAbs(data.milliseconds); 27368 data.seconds = mathAbs(data.seconds); 27369 data.minutes = mathAbs(data.minutes); 27370 data.hours = mathAbs(data.hours); 27371 data.months = mathAbs(data.months); 27372 data.years = mathAbs(data.years); 27373 27374 return this; 27375} 27376 27377function addSubtract$1 (duration, input, value, direction) { 27378 var other = createDuration(input, value); 27379 27380 duration._milliseconds += direction * other._milliseconds; 27381 duration._days += direction * other._days; 27382 duration._months += direction * other._months; 27383 27384 return duration._bubble(); 27385} 27386 27387// supports only 2.0-style add(1, 's') or add(duration) 27388function add$1 (input, value) { 27389 return addSubtract$1(this, input, value, 1); 27390} 27391 27392// supports only 2.0-style subtract(1, 's') or subtract(duration) 27393function subtract$1 (input, value) { 27394 return addSubtract$1(this, input, value, -1); 27395} 27396 27397function absCeil (number) { 27398 if (number < 0) { 27399 return Math.floor(number); 27400 } else { 27401 return Math.ceil(number); 27402 } 27403} 27404 27405function bubble () { 27406 var milliseconds = this._milliseconds; 27407 var days = this._days; 27408 var months = this._months; 27409 var data = this._data; 27410 var seconds, minutes, hours, years, monthsFromDays; 27411 27412 // if we have a mix of positive and negative values, bubble down first 27413 // check: https://github.com/moment/moment/issues/2166 27414 if (!((milliseconds >= 0 && days >= 0 && months >= 0) || 27415 (milliseconds <= 0 && days <= 0 && months <= 0))) { 27416 milliseconds += absCeil(monthsToDays(months) + days) * 864e5; 27417 days = 0; 27418 months = 0; 27419 } 27420 27421 // The following code bubbles up values, see the tests for 27422 // examples of what that means. 27423 data.milliseconds = milliseconds % 1000; 27424 27425 seconds = absFloor(milliseconds / 1000); 27426 data.seconds = seconds % 60; 27427 27428 minutes = absFloor(seconds / 60); 27429 data.minutes = minutes % 60; 27430 27431 hours = absFloor(minutes / 60); 27432 data.hours = hours % 24; 27433 27434 days += absFloor(hours / 24); 27435 27436 // convert days to months 27437 monthsFromDays = absFloor(daysToMonths(days)); 27438 months += monthsFromDays; 27439 days -= absCeil(monthsToDays(monthsFromDays)); 27440 27441 // 12 months -> 1 year 27442 years = absFloor(months / 12); 27443 months %= 12; 27444 27445 data.days = days; 27446 data.months = months; 27447 data.years = years; 27448 27449 return this; 27450} 27451 27452function daysToMonths (days) { 27453 // 400 years have 146097 days (taking into account leap year rules) 27454 // 400 years have 12 months === 4800 27455 return days * 4800 / 146097; 27456} 27457 27458function monthsToDays (months) { 27459 // the reverse of daysToMonths 27460 return months * 146097 / 4800; 27461} 27462 27463function as (units) { 27464 if (!this.isValid()) { 27465 return NaN; 27466 } 27467 var days; 27468 var months; 27469 var milliseconds = this._milliseconds; 27470 27471 units = normalizeUnits(units); 27472 27473 if (units === 'month' || units === 'year') { 27474 days = this._days + milliseconds / 864e5; 27475 months = this._months + daysToMonths(days); 27476 return units === 'month' ? months : months / 12; 27477 } else { 27478 // handle milliseconds separately because of floating point math errors (issue #1867) 27479 days = this._days + Math.round(monthsToDays(this._months)); 27480 switch (units) { 27481 case 'week' : return days / 7 + milliseconds / 6048e5; 27482 case 'day' : return days + milliseconds / 864e5; 27483 case 'hour' : return days * 24 + milliseconds / 36e5; 27484 case 'minute' : return days * 1440 + milliseconds / 6e4; 27485 case 'second' : return days * 86400 + milliseconds / 1000; 27486 // Math.floor prevents floating point math errors here 27487 case 'millisecond': return Math.floor(days * 864e5) + milliseconds; 27488 default: throw new Error('Unknown unit ' + units); 27489 } 27490 } 27491} 27492 27493// TODO: Use this.as('ms')? 27494function valueOf$1 () { 27495 if (!this.isValid()) { 27496 return NaN; 27497 } 27498 return ( 27499 this._milliseconds + 27500 this._days * 864e5 + 27501 (this._months % 12) * 2592e6 + 27502 toInt(this._months / 12) * 31536e6 27503 ); 27504} 27505 27506function makeAs (alias) { 27507 return function () { 27508 return this.as(alias); 27509 }; 27510} 27511 27512var asMilliseconds = makeAs('ms'); 27513var asSeconds = makeAs('s'); 27514var asMinutes = makeAs('m'); 27515var asHours = makeAs('h'); 27516var asDays = makeAs('d'); 27517var asWeeks = makeAs('w'); 27518var asMonths = makeAs('M'); 27519var asYears = makeAs('y'); 27520 27521function clone$1 () { 27522 return createDuration(this); 27523} 27524 27525function get$2 (units) { 27526 units = normalizeUnits(units); 27527 return this.isValid() ? this[units + 's']() : NaN; 27528} 27529 27530function makeGetter(name) { 27531 return function () { 27532 return this.isValid() ? this._data[name] : NaN; 27533 }; 27534} 27535 27536var milliseconds = makeGetter('milliseconds'); 27537var seconds = makeGetter('seconds'); 27538var minutes = makeGetter('minutes'); 27539var hours = makeGetter('hours'); 27540var days = makeGetter('days'); 27541var months = makeGetter('months'); 27542var years = makeGetter('years'); 27543 27544function weeks () { 27545 return absFloor(this.days() / 7); 27546} 27547
vendor: 6,285 bytes, lines 27548-27744
27548var round = Math.round; 27549var thresholds = { 27550 ss: 44, // a few seconds to seconds 27551 s : 45, // seconds to minute 27552 m : 45, // minutes to hour 27553 h : 22, // hours to day 27554 d : 26, // days to month 27555 M : 11 // months to year 27556}; 27557 27558// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize 27559function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { 27560 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); 27561} 27562 27563function relativeTime$1 (posNegDuration, withoutSuffix, locale) { 27564 var duration = createDuration(posNegDuration).abs(); 27565 var seconds = round(duration.as('s')); 27566 var minutes = round(duration.as('m')); 27567 var hours = round(duration.as('h')); 27568 var days = round(duration.as('d')); 27569 var months = round(duration.as('M')); 27570 var years = round(duration.as('y')); 27571 27572 var a = seconds <= thresholds.ss && ['s', seconds] || 27573 seconds < thresholds.s && ['ss', seconds] || 27574 minutes <= 1 && ['m'] || 27575 minutes < thresholds.m && ['mm', minutes] || 27576 hours <= 1 && ['h'] || 27577 hours < thresholds.h && ['hh', hours] || 27578 days <= 1 && ['d'] || 27579 days < thresholds.d && ['dd', days] || 27580 months <= 1 && ['M'] || 27581 months < thresholds.M && ['MM', months] || 27582 years <= 1 && ['y'] || ['yy', years]; 27583 27584 a[2] = withoutSuffix; 27585 a[3] = +posNegDuration > 0; 27586 a[4] = locale; 27587 return substituteTimeAgo.apply(null, a); 27588} 27589 27590// This function allows you to set the rounding function for relative time strings 27591function getSetRelativeTimeRounding (roundingFunction) { 27592 if (roundingFunction === undefined) { 27593 return round; 27594 } 27595 if (typeof(roundingFunction) === 'function') { 27596 round = roundingFunction; 27597 return true; 27598 } 27599 return false; 27600} 27601 27602// This function allows you to set a threshold for relative time strings 27603function getSetRelativeTimeThreshold (threshold, limit) { 27604 if (thresholds[threshold] === undefined) { 27605 return false; 27606 } 27607 if (limit === undefined) { 27608 return thresholds[threshold]; 27609 } 27610 thresholds[threshold] = limit; 27611 if (threshold === 's') { 27612 thresholds.ss = limit - 1; 27613 } 27614 return true; 27615} 27616 27617function humanize (withSuffix) { 27618 if (!this.isValid()) { 27619 return this.localeData().invalidDate(); 27620 } 27621 27622 var locale = this.localeData(); 27623 var output = relativeTime$1(this, !withSuffix, locale); 27624 27625 if (withSuffix) { 27626 output = locale.pastFuture(+this, output); 27627 } 27628 27629 return locale.postformat(output); 27630} 27631 27632var abs$1 = Math.abs; 27633 27634function sign(x) { 27635 return ((x > 0) - (x < 0)) || +x; 27636} 27637 27638function toISOString$1() { 27639 // for ISO strings we do not use the normal bubbling rules: 27640 // * milliseconds bubble up until they become hours 27641 // * days do not bubble at all 27642 // * months bubble up until they become years 27643 // This is because there is no context-free conversion between hours and days 27644 // (think of clock changes) 27645 // and also not between days and months (28-31 days per month) 27646 if (!this.isValid()) { 27647 return this.localeData().invalidDate(); 27648 } 27649 27650 var seconds = abs$1(this._milliseconds) / 1000; 27651 var days = abs$1(this._days); 27652 var months = abs$1(this._months); 27653 var minutes, hours, years; 27654 27655 // 3600 seconds -> 60 minutes -> 1 hour 27656 minutes = absFloor(seconds / 60); 27657 hours = absFloor(minutes / 60); 27658 seconds %= 60; 27659 minutes %= 60; 27660 27661 // 12 months -> 1 year 27662 years = absFloor(months / 12); 27663 months %= 12; 27664 27665 27666 // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js 27667 var Y = years; 27668 var M = months; 27669 var D = days; 27670 var h = hours; 27671 var m = minutes; 27672 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; 27673 var total = this.asSeconds(); 27674 27675 if (!total) { 27676 // this is the same as C#'s (Noda) and python (isodate)... 27677 // but not other JS (goog.date) 27678 return 'P0D'; 27679 } 27680 27681 var totalSign = total < 0 ? '-' : ''; 27682 var ymSign = sign(this._months) !== sign(total) ? '-' : ''; 27683 var daysSign = sign(this._days) !== sign(total) ? '-' : ''; 27684 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; 27685 27686 return totalSign + 'P' + 27687 (Y ? ymSign + Y + 'Y' : '') + 27688 (M ? ymSign + M + 'M' : '') + 27689 (D ? daysSign + D + 'D' : '') + 27690 ((h || m || s) ? 'T' : '') + 27691 (h ? hmsSign + h + 'H' : '') + 27692 (m ? hmsSign + m + 'M' : '') + 27693 (s ? hmsSign + s + 'S' : ''); 27694} 27695 27696var proto$2 = Duration.prototype; 27697 27698proto$2.isValid = isValid$1; 27699proto$2.abs = abs; 27700proto$2.add = add$1; 27701proto$2.subtract = subtract$1; 27702proto$2.as = as; 27703proto$2.asMilliseconds = asMilliseconds; 27704proto$2.asSeconds = asSeconds; 27705proto$2.asMinutes = asMinutes; 27706proto$2.asHours = asHours; 27707proto$2.asDays = asDays; 27708proto$2.asWeeks = asWeeks; 27709proto$2.asMonths = asMonths; 27710proto$2.asYears = asYears; 27711proto$2.valueOf = valueOf$1; 27712proto$2._bubble = bubble; 27713proto$2.clone = clone$1; 27714proto$2.get = get$2; 27715proto$2.milliseconds = milliseconds; 27716proto$2.seconds = seconds; 27717proto$2.minutes = minutes; 27718proto$2.hours = hours; 27719proto$2.days = days; 27720proto$2.weeks = weeks; 27721proto$2.months = months; 27722proto$2.years = years; 27723proto$2.humanize = humanize; 27724proto$2.toISOString = toISOString$1; 27725proto$2.toString = toISOString$1; 27726proto$2.toJSON = toISOString$1; 27727proto$2.locale = locale; 27728proto$2.localeData = localeData; 27729 27730// Deprecations 27731proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); 27732proto$2.lang = lang; 27733 27734// Side effect imports 27735 27736// FORMATTING 27737 27738addFormatToken('X', 0, 0, 'unix'); 27739addFormatToken('x', 0, 0, 'valueOf'); 27740 27741// PARSING 27742 27743addRegexToken('x', matchSigned); 27744addRegexToken('X', matchTimestamp);
27745addParseToken('X', function (input, array, config) { 27746 config._d = new Date(parseFloat(input, 10) * 1000); 27747}); 27748addParseToken('x', function (input, array, config) { 27749 config._d = new Date(toInt(input)); 27750}); 27751 27752// Side effect imports 27753 27754 27755hooks.version = '2.20.1'; 27756 27757setHookCallback(createLocal); 27758 27759hooks.fn = proto; 27760hooks.min = min; 27761hooks.max = max; 27762hooks.now = now; 27763hooks.utc = createUTC; 27764hooks.unix = createUnix; 27765hooks.months = listMonths; 27766hooks.isDate = isDate; 27767hooks.locale = getSetGlobalLocale; 27768hooks.invalid = createInvalid; 27769hooks.duration = createDuration; 27770hooks.isMoment = isMoment; 27771hooks.weekdays = listWeekdays; 27772hooks.parseZone = createInZone; 27773hooks.localeData = getLocale; 27774hooks.isDuration = isDuration; 27775hooks.monthsShort = listMonthsShort; 27776hooks.weekdaysMin = listWeekdaysMin; 27777hooks.defineLocale = defineLocale; 27778hooks.updateLocale = updateLocale; 27779hooks.locales = listLocales; 27780hooks.weekdaysShort = listWeekdaysShort; 27781hooks.normalizeUnits = normalizeUnits; 27782hooks.relativeTimeRounding = getSetRelativeTimeRounding; 27783hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; 27784hooks.calendarFormat = getCalendarFormat; 27785hooks.prototype = proto; 27786 27787// currently HTML5 input type only supports 24-hour formats 27788hooks.HTML5_FMT = { 27789 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" /> 27790 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" /> 27791 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" /> 27792 DATE: 'YYYY-MM-DD', // <input type="date" /> 27793 TIME: 'HH:mm', // <input type="time" /> 27794 TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" /> 27795 TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" /> 27796 WEEK: 'YYYY-[W]WW', // <input type="week" /> 27797 MONTH: 'YYYY-MM' // <input type="month" /> 27798}; 27799 27800return hooks; 27801 27802}))); 27803 27804},{}],7:[function(require,module,exports){ 27805/** 27806 * @namespace Chart 27807 */ 27808var Chart = require(29)(); 27809 27810Chart.helpers = require(45); 27811 27812// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests! 27813require(27)(Chart); 27814 27815Chart.defaults = require(25); 27816Chart.Element = require(26); 27817Chart.elements = require(40); 27818Chart.Interaction = require(28); 27819Chart.layouts = require(30); 27820Chart.platform = require(48); 27821Chart.plugins = require(31); 27822Chart.Ticks = require(34); 27823 27824require(22)(Chart); 27825require(23)(Chart); 27826require(24)(Chart); 27827require(33)(Chart); 27828require(32)(Chart); 27829require(35)(Chart); 27830 27831require(55)(Chart); 27832require(53)(Chart); 27833require(54)(Chart); 27834require(56)(Chart); 27835require(57)(Chart); 27836require(58)(Chart); 27837 27838// Controllers must be loaded after elements 27839// See Chart.core.datasetController.dataElementType 27840require(15)(Chart); 27841require(16)(Chart); 27842require(17)(Chart); 27843require(18)(Chart); 27844require(19)(Chart); 27845require(20)(Chart); 27846require(21)(Chart); 27847 27848require(8)(Chart); 27849require(9)(Chart); 27850require(10)(Chart); 27851require(11)(Chart); 27852require(12)(Chart); 27853require(13)(Chart); 27854require(14)(Chart); 27855 27856// Loading built-it plugins 27857var plugins = require(49); 27858for (var k in plugins) { 27859 if (plugins.hasOwnProperty(k)) { 27860 Chart.plugins.register(plugins[k]); 27861 } 27862} 27863 27864Chart.platform.initialize(); 27865 27866module.exports = Chart; 27867if (typeof window !== 'undefined') { 27868 window.Chart = Chart; 27869} 27870 27871// DEPRECATIONS 27872 27873/** 27874 * Provided for backward compatibility, not available anymore 27875 * @namespace Chart.Legend 27876 * @deprecated since version 2.1.5 27877 * @todo remove at version 3 27878 * @private 27879 */ 27880Chart.Legend = plugins.legend._element; 27881 27882/** 27883 * Provided for backward compatibility, not available anymore 27884 * @namespace Chart.Title 27885 * @deprecated since version 2.1.5 27886 * @todo remove at version 3 27887 * @private 27888 */ 27889Chart.Title = plugins.title._element; 27890 27891/** 27892 * Provided for backward compatibility, use Chart.plugins instead
27893 * @namespace Chart.pluginService 27894 * @deprecated since version 2.1.5 27895 * @todo remove at version 3 27896 * @private 27897 */ 27898Chart.pluginService = Chart.plugins; 27899 27900/** 27901 * Provided for backward compatibility, inheriting from Chart.PlugingBase has no 27902 * effect, instead simply create/register plugins via plain JavaScript objects. 27903 * @interface Chart.PluginBase 27904 * @deprecated since version 2.5.0 27905 * @todo remove at version 3 27906 * @private 27907 */ 27908Chart.PluginBase = Chart.Element.extend({}); 27909 27910/** 27911 * Provided for backward compatibility, use Chart.helpers.canvas instead. 27912 * @namespace Chart.canvasHelpers 27913 * @deprecated since version 2.6.0 27914 * @todo remove at version 3 27915 * @private 27916 */ 27917Chart.canvasHelpers = Chart.helpers.canvas; 27918 27919/** 27920 * Provided for backward compatibility, use Chart.layouts instead. 27921 * @namespace Chart.layoutService 27922 * @deprecated since version 2.8.0 27923 * @todo remove at version 3 27924 * @private 27925 */ 27926Chart.layoutService = Chart.layouts; 27927 27928},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"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,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"40":40,"45":45,"48":48,"49":49,"53":53,"54":54,"55":55,"56":56,"57":57,"58":58,"8":8,"9":9}],8:[function(require,module,exports){ 27929'use strict'; 27930 27931module.exports = function(Chart) { 27932 27933 Chart.Bar = function(context, config) { 27934 config.type = 'bar'; 27935 27936 return new Chart(context, config); 27937 }; 27938 27939}; 27940 27941},{}],9:[function(require,module,exports){ 27942'use strict'; 27943 27944module.exports = function(Chart) { 27945 27946 Chart.Bubble = function(context, config) { 27947 config.type = 'bubble'; 27948 return new Chart(context, config); 27949 }; 27950 27951}; 27952 27953},{}],10:[function(require,module,exports){ 27954'use strict'; 27955 27956module.exports = function(Chart) { 27957 27958 Chart.Doughnut = function(context, config) { 27959 config.type = 'doughnut'; 27960 27961 return new Chart(context, config); 27962 }; 27963 27964}; 27965 27966},{}],11:[function(require,module,exports){ 27967'use strict'; 27968 27969module.exports = function(Chart) { 27970 27971 Chart.Line = function(context, config) { 27972 config.type = 'line'; 27973 27974 return new Chart(context, config); 27975 }; 27976 27977}; 27978 27979},{}],12:[function(require,module,exports){ 27980'use strict'; 27981 27982module.exports = function(Chart) { 27983 27984 Chart.PolarArea = function(context, config) { 27985 config.type = 'polarArea'; 27986 27987 return new Chart(context, config); 27988 }; 27989 27990}; 27991 27992},{}],13:[function(require,module,exports){ 27993'use strict'; 27994 27995module.exports = function(Chart) { 27996 27997 Chart.Radar = function(context, config) { 27998 config.type = 'radar'; 27999 28000 return new Chart(context, config); 28001 }; 28002 28003}; 28004 28005},{}],14:[function(require,module,exports){ 28006'use strict'; 28007 28008module.exports = function(Chart) { 28009 Chart.Scatter = function(context, config) { 28010 config.type = 'scatter'; 28011 return new Chart(context, config); 28012 }; 28013}; 28014 28015},{}],15:[function(require,module,exports){ 28016'use strict'; 28017 28018var defaults = require(25); 28019var elements = require(40); 28020var helpers = require(45); 28021 28022defaults._set('bar', { 28023 hover: { 28024 mode: 'label' 28025 }, 28026 28027 scales: { 28028 xAxes: [{ 28029 type: 'category', 28030 28031 // Specific to Bar Controller 28032 categoryPercentage: 0.8, 28033 barPercentage: 0.9, 28034 28035 // offset settings 28036 offset: true, 28037 28038 // grid line settings 28039 gridLines: { 28040 offsetGridLines: true 28041 } 28042 }], 28043 28044 yAxes: [{ 28045 type: 'linear' 28046 }] 28047 } 28048}); 28049 28050defaults._set('horizontalBar', { 28051 hover: { 28052 mode: 'index', 28053 axis: 'y' 28054 }, 28055 28056 scales: { 28057 xAxes: [{ 28058 type: 'linear', 28059 position: 'bottom' 28060 }], 28061 28062 yAxes: [{ 28063 position: 'left', 28064 type: 'category', 28065 28066 // Specific to Horizontal Bar Controller 28067 categoryPercentage: 0.8, 28068 barPercentage: 0.9, 28069 28070 // offset settings 28071 offset: true, 28072 28073 // grid line settings 28074 gridLines: { 28075 offsetGridLines: true 28076 } 28077 }] 28078 }, 28079 28080 elements: { 28081 rectangle: { 28082 borderSkipped: 'left' 28083 } 28084 }, 28085 28086 tooltips: { 28087 callbacks: { 28088 title: function(item, data) { 28089 // Pick first xLabel for now 28090 var title = ''; 28091 28092 if (item.length > 0) { 28093 if (item[0].yLabel) { 28094 title = item[0].yLabel; 28095 } else if (data.labels.length > 0 && item[0].index < data.labels.length) { 28096 title = data.labels[item[0].index]; 28097 } 28098 } 28099 28100 return title; 28101 }, 28102 28103 label: function(item, data) { 28104 var datasetLabel = data.datasets[item.datasetIndex].label || ''; 28105 return datasetLabel + ': ' + item.xLabel; 28106 } 28107 }, 28108 mode: 'index', 28109 axis: 'y' 28110 } 28111}); 28112 28113/** 28114 * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap. 28115 * @private 28116 */ 28117function computeMinSampleSize(scale, pixels) { 28118 var min = scale.isHorizontal() ? scale.width : scale.height; 28119 var ticks = scale.getTicks(); 28120 var prev, curr, i, ilen; 28121 28122 for (i = 1, ilen = pixels.length; i < ilen; ++i) { 28123 min = Math.min(min, pixels[i] - pixels[i - 1]); 28124 } 28125 28126 for (i = 0, ilen = ticks.length; i < ilen; ++i) { 28127 curr = scale.getPixelForTick(i); 28128 min = i > 0 ? Math.min(min, curr - prev) : min; 28129 prev = curr; 28130 } 28131 28132 return min; 28133} 28134 28135/** 28136 * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null, 28137 * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This 28138 * mode currently always generates bars equally sized (until we introduce scriptable options?). 28139 * @private 28140 */ 28141function computeFitCategoryTraits(index, ruler, options) { 28142 var thickness = options.barThickness; 28143 var count = ruler.stackCount; 28144 var curr = ruler.pixels[index]; 28145 var size, ratio; 28146 28147 if (helpers.isNullOrUndef(thickness)) { 28148 size = ruler.min * options.categoryPercentage; 28149 ratio = options.barPercentage; 28150 } else { 28151 // When bar thickness is enforced, category and bar percentages are ignored. 28152 // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%') 28153 // and deprecate barPercentage since this value is ignored when thickness is absolute. 28154 size = thickness * count; 28155 ratio = 1; 28156 } 28157 28158 return { 28159 chunk: size / count, 28160 ratio: ratio, 28161 start: curr - (size / 2) 28162 }; 28163} 28164 28165/** 28166 * Computes an "optimal" category that globally arranges bars side by side (no gap when 28167 * percentage options are 1), based on the previous and following categories. This mode 28168 * generates bars with different widths when data are not evenly spaced. 28169 * @private 28170 */ 28171function computeFlexCategoryTraits(index, ruler, options) { 28172 var pixels = ruler.pixels; 28173 var curr = pixels[index]; 28174 var prev = index > 0 ? pixels[index - 1] : null; 28175 var next = index < pixels.length - 1 ? pixels[index + 1] : null; 28176 var percent = options.categoryPercentage; 28177 var start, size; 28178 28179 if (prev === null) { 28180 // first data: its size is double based on the next point or, 28181 // if it's also the last data, we use the scale end extremity. 28182 prev = curr - (next === null ? ruler.end - curr : next - curr); 28183 } 28184 28185 if (next === null) { 28186 // last data: its size is also double based on the previous point. 28187 next = curr + curr - prev; 28188 } 28189 28190 start = curr - ((curr - prev) / 2) * percent; 28191 size = ((next - prev) / 2) * percent; 28192 28193 return { 28194 chunk: size / ruler.stackCount, 28195 ratio: options.barPercentage, 28196 start: start 28197 }; 28198} 28199 28200module.exports = function(Chart) { 28201 28202 Chart.controllers.bar = Chart.DatasetController.extend({ 28203 28204 dataElementType: elements.Rectangle, 28205 28206 initialize: function() { 28207 var me = this; 28208 var meta; 28209 28210 Chart.DatasetController.prototype.initialize.apply(me, arguments); 28211 28212 meta = me.getMeta(); 28213 meta.stack = me.getDataset().stack; 28214 meta.bar = true; 28215 }, 28216 28217 update: function(reset) { 28218 var me = this; 28219 var rects = me.getMeta().data; 28220 var i, ilen; 28221 28222 me._ruler = me.getRuler(); 28223 28224 for (i = 0, ilen = rects.length; i < ilen; ++i) { 28225 me.updateElement(rects[i], i, reset); 28226 } 28227 }, 28228 28229 updateElement: function(rectangle, index, reset) { 28230 var me = this; 28231 var chart = me.chart; 28232 var meta = me.getMeta(); 28233 var dataset = me.getDataset(); 28234 var custom = rectangle.custom || {}; 28235 var rectangleOptions = chart.options.elements.rectangle; 28236 28237 rectangle._xScale = me.getScaleForId(meta.xAxisID); 28238 rectangle._yScale = me.getScaleForId(meta.yAxisID); 28239 rectangle._datasetIndex = me.index; 28240 rectangle._index = index; 28241 28242 rectangle._model = { 28243 datasetLabel: dataset.label, 28244 label: chart.data.labels[index], 28245 borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped, 28246 backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor), 28247 borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor), 28248 borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth) 28249 }; 28250 28251 me.updateElementGeometry(rectangle, index, reset); 28252 28253 rectangle.pivot(); 28254 }, 28255 28256 /** 28257 * @private 28258 */ 28259 updateElementGeometry: function(rectangle, index, reset) { 28260 var me = this; 28261 var model = rectangle._model; 28262 var vscale = me.getValueScale(); 28263 var base = vscale.getBasePixel(); 28264 var horizontal = vscale.isHorizontal(); 28265 var ruler = me._ruler || me.getRuler(); 28266 var vpixels = me.calculateBarValuePixels(me.index, index); 28267 var ipixels = me.calculateBarIndexPixels(me.index, index, ruler); 28268 28269 model.horizontal = horizontal; 28270 model.base = reset ? base : vpixels.base; 28271 model.x = horizontal ? reset ? base : vpixels.head : ipixels.center; 28272 model.y = horizontal ? ipixels.center : reset ? base : vpixels.head; 28273 model.height = horizontal ? ipixels.size : undefined; 28274 model.width = horizontal ? undefined : ipixels.size; 28275 }, 28276 28277 /** 28278 * @private 28279 */ 28280 getValueScaleId: function() { 28281 return this.getMeta().yAxisID; 28282 }, 28283 28284 /** 28285 * @private 28286 */ 28287 getIndexScaleId: function() { 28288 return this.getMeta().xAxisID; 28289 }, 28290 28291 /** 28292 * @private 28293 */ 28294 getValueScale: function() {
28295 return this.getScaleForId(this.getValueScaleId()); 28296 }, 28297 28298 /** 28299 * @private 28300 */ 28301 getIndexScale: function() { 28302 return this.getScaleForId(this.getIndexScaleId()); 28303 }, 28304 28305 /** 28306 * Returns the stacks based on groups and bar visibility. 28307 * @param {Number} [last] - The dataset index 28308 * @returns {Array} The stack list 28309 * @private 28310 */ 28311 _getStacks: function(last) { 28312 var me = this; 28313 var chart = me.chart; 28314 var scale = me.getIndexScale(); 28315 var stacked = scale.options.stacked; 28316 var ilen = last === undefined ? chart.data.datasets.length : last + 1; 28317 var stacks = []; 28318 var i, meta; 28319 28320 for (i = 0; i < ilen; ++i) { 28321 meta = chart.getDatasetMeta(i); 28322 if (meta.bar && chart.isDatasetVisible(i) && 28323 (stacked === false || 28324 (stacked === true && stacks.indexOf(meta.stack) === -1) || 28325 (stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) { 28326 stacks.push(meta.stack); 28327 } 28328 } 28329 28330 return stacks; 28331 }, 28332 28333 /** 28334 * Returns the effective number of stacks based on groups and bar visibility. 28335 * @private 28336 */ 28337 getStackCount: function() { 28338 return this._getStacks().length; 28339 }, 28340 28341 /** 28342 * Returns the stack index for the given dataset based on groups and bar visibility. 28343 * @param {Number} [datasetIndex] - The dataset index 28344 * @param {String} [name] - The stack name to find 28345 * @returns {Number} The stack index 28346 * @private 28347 */ 28348 getStackIndex: function(datasetIndex, name) { 28349 var stacks = this._getStacks(datasetIndex); 28350 var index = (name !== undefined) 28351 ? stacks.indexOf(name) 28352 : -1; // indexOf returns -1 if element is not present 28353 28354 return (index === -1) 28355 ? stacks.length - 1 28356 : index; 28357 }, 28358 28359 /** 28360 * @private 28361 */ 28362 getRuler: function() { 28363 var me = this; 28364 var scale = me.getIndexScale(); 28365 var stackCount = me.getStackCount(); 28366 var datasetIndex = me.index; 28367 var isHorizontal = scale.isHorizontal(); 28368 var start = isHorizontal ? scale.left : scale.top; 28369 var end = start + (isHorizontal ? scale.width : scale.height); 28370 var pixels = []; 28371 var i, ilen, min; 28372 28373 for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) { 28374 pixels.push(scale.getPixelForValue(null, i, datasetIndex)); 28375 } 28376 28377 min = helpers.isNullOrUndef(scale.options.barThickness) 28378 ? computeMinSampleSize(scale, pixels) 28379 : -1; 28380 28381 return { 28382 min: min, 28383 pixels: pixels, 28384 start: start, 28385 end: end, 28386 stackCount: stackCount, 28387 scale: scale 28388 }; 28389 }, 28390 28391 /** 28392 * Note: pixel values are not clamped to the scale area. 28393 * @private 28394 */ 28395 calculateBarValuePixels: function(datasetIndex, index) { 28396 var me = this; 28397 var chart = me.chart; 28398 var meta = me.getMeta(); 28399 var scale = me.getValueScale(); 28400 var datasets = chart.data.datasets; 28401 var value = scale.getRightValue(datasets[datasetIndex].data[index]); 28402 var stacked = scale.options.stacked; 28403 var stack = meta.stack; 28404 var start = 0; 28405 var i, imeta, ivalue, base, head, size; 28406 28407 if (stacked || (stacked === undefined && stack !== undefined)) { 28408 for (i = 0; i < datasetIndex; ++i) { 28409 imeta = chart.getDatasetMeta(i); 28410 28411 if (imeta.bar && 28412 imeta.stack === stack && 28413 imeta.controller.getValueScaleId() === scale.id && 28414 chart.isDatasetVisible(i)) { 28415 28416 ivalue = scale.getRightValue(datasets[i].data[index]); 28417 if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) { 28418 start += ivalue; 28419 } 28420 } 28421 } 28422 } 28423 28424 base = scale.getPixelForValue(start); 28425 head = scale.getPixelForValue(start + value); 28426 size = (head - base) / 2; 28427 28428 return { 28429 size: size, 28430 base: base, 28431 head: head, 28432 center: head + size / 2 28433 }; 28434 }, 28435 28436 /** 28437 * @private 28438 */ 28439 calculateBarIndexPixels: function(datasetIndex, index, ruler) { 28440 var me = this; 28441 var options = ruler.scale.options; 28442 var range = options.barThickness === 'flex' 28443 ? computeFlexCategoryTraits(index, ruler, options) 28444 : computeFitCategoryTraits(index, ruler, options); 28445 28446 var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack); 28447 var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2); 28448 var size = Math.min( 28449 helpers.valueOrDefault(options.maxBarThickness, Infinity), 28450 range.chunk * range.ratio); 28451 28452 return { 28453 base: center - size / 2, 28454 head: center + size / 2, 28455 center: center, 28456 size: size 28457 }; 28458 }, 28459 28460 draw: function() { 28461 var me = this; 28462 var chart = me.chart; 28463 var scale = me.getValueScale(); 28464 var rects = me.getMeta().data; 28465 var dataset = me.getDataset(); 28466 var ilen = rects.length; 28467 var i = 0; 28468 28469 helpers.canvas.clipArea(chart.ctx, chart.chartArea); 28470 28471 for (; i < ilen; ++i) { 28472 if (!isNaN(scale.getRightValue(dataset.data[i]))) { 28473 rects[i].draw(); 28474 } 28475 } 28476 28477 helpers.canvas.unclipArea(chart.ctx); 28478 }, 28479 28480 setHoverStyle: function(rectangle) { 28481 var dataset = this.chart.data.datasets[rectangle._datasetIndex]; 28482 var index = rectangle._index; 28483 var custom = rectangle.custom || {}; 28484 var model = rectangle._model; 28485
28486 model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); 28487 model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); 28488 model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); 28489 }, 28490 28491 removeHoverStyle: function(rectangle) { 28492 var dataset = this.chart.data.datasets[rectangle._datasetIndex]; 28493 var index = rectangle._index; 28494 var custom = rectangle.custom || {}; 28495 var model = rectangle._model; 28496 var rectangleElementOptions = this.chart.options.elements.rectangle; 28497 28498 model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor); 28499 model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor); 28500 model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth); 28501 } 28502 }); 28503 28504 Chart.controllers.horizontalBar = Chart.controllers.bar.extend({ 28505 /** 28506 * @private 28507 */ 28508 getValueScaleId: function() { 28509 return this.getMeta().xAxisID; 28510 }, 28511 28512 /** 28513 * @private 28514 */ 28515 getIndexScaleId: function() { 28516 return this.getMeta().yAxisID; 28517 } 28518 }); 28519}; 28520 28521},{"25":25,"40":40,"45":45}],16:[function(require,module,exports){ 28522'use strict'; 28523 28524var defaults = require(25); 28525var elements = require(40); 28526var helpers = require(45); 28527 28528defaults._set('bubble', { 28529 hover: { 28530 mode: 'single' 28531 }, 28532 28533 scales: { 28534 xAxes: [{ 28535 type: 'linear', // bubble should probably use a linear scale by default 28536 position: 'bottom', 28537 id: 'x-axis-0' // need an ID so datasets can reference the scale 28538 }], 28539 yAxes: [{ 28540 type: 'linear', 28541 position: 'left', 28542 id: 'y-axis-0' 28543 }] 28544 }, 28545 28546 tooltips: { 28547 callbacks: { 28548 title: function() { 28549 // Title doesn't make sense for scatter since we format the data as a point 28550 return ''; 28551 }, 28552 label: function(item, data) { 28553 var datasetLabel = data.datasets[item.datasetIndex].label || ''; 28554 var dataPoint = data.datasets[item.datasetIndex].data[item.index]; 28555 return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')'; 28556 } 28557 } 28558 } 28559}); 28560 28561 28562module.exports = function(Chart) { 28563 28564 Chart.controllers.bubble = Chart.DatasetController.extend({ 28565 /** 28566 * @protected 28567 */ 28568 dataElementType: elements.Point, 28569 28570 /** 28571 * @protected 28572 */ 28573 update: function(reset) { 28574 var me = this; 28575 var meta = me.getMeta(); 28576 var points = meta.data; 28577 28578 // Update Points 28579 helpers.each(points, function(point, index) { 28580 me.updateElement(point, index, reset); 28581 }); 28582 }, 28583 28584 /** 28585 * @protected 28586 */ 28587 updateElement: function(point, index, reset) { 28588 var me = this; 28589 var meta = me.getMeta(); 28590 var custom = point.custom || {}; 28591 var xScale = me.getScaleForId(meta.xAxisID); 28592 var yScale = me.getScaleForId(meta.yAxisID); 28593 var options = me._resolveElementOptions(point, index); 28594 var data = me.getDataset().data[index]; 28595 var dsIndex = me.index; 28596 28597 var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex); 28598 var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex); 28599 28600 point._xScale = xScale; 28601 point._yScale = yScale; 28602 point._options = options; 28603 point._datasetIndex = dsIndex; 28604 point._index = index; 28605 point._model = { 28606 backgroundColor: options.backgroundColor, 28607 borderColor: options.borderColor, 28608 borderWidth: options.borderWidth, 28609 hitRadius: options.hitRadius, 28610 pointStyle: options.pointStyle, 28611 radius: reset ? 0 : options.radius, 28612 skip: custom.skip || isNaN(x) || isNaN(y), 28613 x: x, 28614 y: y, 28615 }; 28616 28617 point.pivot(); 28618 }, 28619 28620 /** 28621 * @protected 28622 */ 28623 setHoverStyle: function(point) { 28624 var model = point._model; 28625 var options = point._options; 28626 28627 model.backgroundColor = helpers.valueOrDefault(options.hoverBackgroun
28627dColor, helpers.getHoverColor(options.backgroundColor)); 28628 model.borderColor = helpers.valueOrDefault(options.hoverBorderColor, helpers.getHoverColor(options.borderColor)); 28629 model.borderWidth = helpers.valueOrDefault(options.hoverBorderWidth, options.borderWidth); 28630 model.radius = options.radius + options.hoverRadius; 28631 }, 28632 28633 /** 28634 * @protected 28635 */ 28636 removeHoverStyle: function(point) { 28637 var model = point._model; 28638 var options = point._options; 28639 28640 model.backgroundColor = options.backgroundColor; 28641 model.borderColor = options.borderColor; 28642 model.borderWidth = options.borderWidth; 28643 model.radius = options.radius; 28644 }, 28645 28646 /** 28647 * @private 28648 */ 28649 _resolveElementOptions: function(point, index) { 28650 var me = this; 28651 var chart = me.chart; 28652 var datasets = chart.data.datasets; 28653 var dataset = datasets[me.index]; 28654 var custom = point.custom || {}; 28655 var options = chart.options.elements.point; 28656 var resolve = helpers.options.resolve; 28657 var data = dataset.data[index]; 28658 var values = {}; 28659 var i, ilen, key; 28660 28661 // Scriptable options 28662 var context = { 28663 chart: chart, 28664 dataIndex: index, 28665 dataset: dataset, 28666 datasetIndex: me.index 28667 }; 28668 28669 var keys = [ 28670 'backgroundColor', 28671 'borderColor', 28672 'borderWidth', 28673 'hoverBackgroundColor', 28674 'hoverBorderColor', 28675 'hoverBorderWidth', 28676 'hoverRadius', 28677 'hitRadius', 28678 'pointStyle' 28679 ]; 28680 28681 for (i = 0, ilen = keys.length; i < ilen; ++i) { 28682 key = keys[i]; 28683 values[key] = resolve([ 28684 custom[key], 28685 dataset[key], 28686 options[key] 28687 ], context, index); 28688 } 28689 28690 // Custom radius resolution 28691 values.radius = resolve([ 28692 custom.radius, 28693 data ? data.r : undefined, 28694 dataset.radius, 28695 options.radius 28696 ], context, index); 28697 28698 return values; 28699 } 28700 }); 28701}; 28702 28703},{"25":25,"40":40,"45":45}],17:[function(require,module,exports){ 28704'use strict'; 28705 28706var defaults = require(25); 28707var elements = require(40); 28708var helpers = require(45); 28709 28710defaults._set('doughnut', { 28711 animation: { 28712 // Boolean - Whether we animate the rotation of the Doughnut 28713 animateRotate: true, 28714 // Boolean - Whether we animate scaling the Doughnut from the centre 28715 animateScale: false 28716 }, 28717 hover: { 28718 mode: 'single' 28719 }, 28720 legendCallback: function(chart) { 28721 var text = []; 28722 text.push('<ul class="' + chart.id + '-legend">'); 28723 28724 var data = chart.data; 28725 var datasets = data.datasets; 28726 var labels = data.labels; 28727 28728 if (datasets.length) { 28729 for (var i = 0; i < datasets[0].data.length; ++i) { 28730 text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>'); 28731 if (labels[i]) { 28732 text.push(labels[i]); 28733 } 28734 text.push('</li>'); 28735 } 28736 } 28737 28738 text.push('</ul>'); 28739 return text.join(''); 28740 }, 28741 legend: { 28742 labels: { 28743 generateLabels: function(chart) { 28744 var data = chart.data; 28745 if (data.labels.length && data.datasets.length) { 28746 return data.labels.map(function(label, i) { 28747 var meta = chart.getDatasetMeta(0); 28748 var ds = data.datasets[0]; 28749 var arc = meta.data[i]; 28750 var custom = arc && arc.custom || {}; 28751 var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault; 28752 var arcOpts = chart.options.elements.arc; 28753 var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); 28754 var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); 28755 var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); 28756 28757 return { 28758 text: label, 28759 fillStyle: fill, 28760 strokeStyle: stroke, 28761 lineWidth: bw, 28762 hidden: isNaN(ds.data[i]) || meta.data[i].hidden, 28763 28764 // Extra data used for toggling the correct item 28765 index: i 28766 }; 28767 }); 28768 } 28769 return []; 28770 } 28771 }, 28772 28773 onClick: function(e, legendItem) { 28774 var index = legendItem.index; 28775 var chart = this.chart; 28776 var i, ilen, meta; 28777 28778 for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { 28779 meta = chart.getDatasetMeta(i); 28780 // toggle visibility of index if exists 28781 if (meta.data[index]) { 28782 meta.data[index].hidden = !meta.data[index].hidden; 28783 } 28784 } 28785
28786 chart.update(); 28787 } 28788 }, 28789 28790 // The percentage of the chart that we cut out of the middle. 28791 cutoutPercentage: 50, 28792 28793 // The rotation of the chart, where the first data arc begins. 28794 rotation: Math.PI * -0.5, 28795 28796 // The total circumference of the chart. 28797 circumference: Math.PI * 2.0, 28798 28799 // Need to override these to give a nice default 28800 tooltips: { 28801 callbacks: { 28802 title: function() { 28803 return ''; 28804 }, 28805 label: function(tooltipItem, data) { 28806 var dataLabel = data.labels[tooltipItem.index]; 28807 var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; 28808 28809 if (helpers.isArray(dataLabel)) { 28810 // show value on first line of multiline label 28811 // need to clone because we are changing the value 28812 dataLabel = dataLabel.slice(); 28813 dataLabel[0] += value; 28814 } else { 28815 dataLabel += value; 28816 } 28817 28818 return dataLabel; 28819 } 28820 } 28821 } 28822}); 28823 28824defaults._set('pie', helpers.clone(defaults.doughnut)); 28825defaults._set('pie', { 28826 cutoutPercentage: 0 28827}); 28828 28829module.exports = function(Chart) { 28830 28831 Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({ 28832 28833 dataElementType: elements.Arc, 28834 28835 linkScales: helpers.noop, 28836 28837 // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly 28838 getRingIndex: function(datasetIndex) { 28839 var ringIndex = 0; 28840 28841 for (var j = 0; j < datasetIndex; ++j) { 28842 if (this.chart.isDatasetVisible(j)) { 28843 ++ringIndex; 28844 } 28845 } 28846 28847 return ringIndex; 28848 }, 28849 28850 update: function(reset) { 28851 var me = this; 28852 var chart = me.chart; 28853 var chartArea = chart.chartArea; 28854 var opts = chart.options; 28855 var arcOpts = opts.elements.arc; 28856 var availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth; 28857 var availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth; 28858 var minSize = Math.min(availableWidth, availableHeight); 28859 var offset = {x: 0, y: 0}; 28860 var meta = me.getMeta(); 28861 var cutoutPercentage = opts.cutoutPercentage; 28862 var circumference = opts.circumference; 28863 28864 // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc 28865 if (circumference < Math.PI * 2.0) { 28866 var startAngle = opts.rotation % (Math.PI * 2.0); 28867 startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0); 28868 var endAngle = startAngle + circumference; 28869 var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)}; 28870 var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)}; 28871 var contains0 = (startAngle <= 0 && endAngle >= 0) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle); 28872 var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle); 28873 var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle); 28874 var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle); 28875 var cutout = cutoutPercentage / 100.0; 28876 var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))}; 28877 var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))}; 28878 var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5}; 28879 minSize = Math.min(availableWidth / size.width, availableHeight / size.height); 28880 offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5}; 28881 } 28882 28883 chart.borderWidth = me.getMaxBorderWidth(meta.data); 28884 chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0); 28885 chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0); 28886 chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); 28887 chart.offsetX = offset.x * chart.outerRadius; 28888 chart.offsetY = offset.y * chart.outerRadius; 28889 28890 meta.total = me.calculateTotal(); 28891
28892 me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index)); 28893 me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0); 28894 28895 helpers.each(meta.data, function(arc, index) { 28896 me.updateElement(arc, index, reset); 28897 }); 28898 }, 28899 28900 updateElement: function(arc, index, reset) { 28901 var me = this; 28902 var chart = me.chart; 28903 var chartArea = chart.chartArea; 28904 var opts = chart.options; 28905 var animationOpts = opts.animation; 28906 var centerX = (chartArea.left + chartArea.right) / 2; 28907 var centerY = (chartArea.top + chartArea.bottom) / 2; 28908 var startAngle = opts.rotation; // non reset case handled later 28909 var endAngle = opts.rotation; // non reset case handled later 28910 var dataset = me.getDataset(); 28911 var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)); 28912 var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius; 28913 var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius; 28914 var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault; 28915 28916 helpers.extend(arc, { 28917 // Utility 28918 _datasetIndex: me.index, 28919 _index: index, 28920 28921 // Desired view properties 28922 _model: { 28923 x: centerX + chart.offsetX, 28924 y: centerY + chart.offsetY, 28925 startAngle: startAngle, 28926 endAngle: endAngle, 28927 circumference: circumference, 28928 outerRadius: outerRadius, 28929 innerRadius: innerRadius, 28930 label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index]) 28931 } 28932 }); 28933 28934 var model = arc._model; 28935 // Resets the visual styles 28936 this.removeHoverStyle(arc); 28937 28938 // Set correct angles if not resetting 28939 if (!reset || !animationOpts.animateRotate) { 28940 if (index === 0) { 28941 model.startAngle = opts.rotation; 28942 } else { 28943 model.startAngle = me.getMeta().data[index - 1]._model.endAngle; 28944 } 28945 28946 model.endAngle = model.startAngle + model.circumference; 28947 } 28948 28949 arc.pivot(); 28950 }, 28951 28952 removeHoverStyle: function(arc) { 28953 Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc); 28954 }, 28955 28956 calculateTotal: function() { 28957 var dataset = this.getDataset(); 28958 var meta = this.getMeta(); 28959 var total = 0; 28960 var value; 28961 28962 helpers.each(meta.data, function(element, index) { 28963 value = dataset.data[index]; 28964 if (!isNaN(value) && !element.hidden) { 28965 total += Math.abs(value); 28966 } 28967 }); 28968 28969 /* if (total === 0) { 28970 total = NaN; 28971 }*/ 28972 28973 return total; 28974 }, 28975 28976 calculateCircumference: function(value) { 28977 var total = this.getMeta().total; 28978 if (total > 0 && !isNaN(value)) { 28979 return (Math.PI * 2.0) * (Math.abs(value) / total); 28980 } 28981 return 0; 28982 }, 28983 28984 // gets the max border or hover width to properly scale pie charts 28985 getMaxBorderWidth: function(arcs) { 28986 var max = 0; 28987 var index = this.index; 28988 var length = arcs.length; 28989 var borderWidth; 28990 var hoverWidth; 28991 28992 for (var i = 0; i < length; i++) { 28993 borderWidth = arcs[i]._model ? arcs[i]._model.borderWidth : 0; 28994 hoverWidth = arcs[i]._chart ? arcs[i]._chart.config.data.datasets[index].hoverBorderWidth : 0; 28995 28996 max = borderWidth > max ? borderWidth : max; 28997 max = hoverWidth > max ? hoverWidth : max; 28998 } 28999 return max; 29000 } 29001 }); 29002}; 29003 29004},{"25":25,"40":40,"45":45}],18:[function(require,module,exports){ 29005'use strict'; 29006 29007var defaults = require(25); 29008var elements = require(40); 29009var helpers = require(45); 29010 29011defaults._set('line', { 29012 showLines: true, 29013 spanGaps: false, 29014 29015 hover: { 29016 mode: 'label' 29017 }, 29018 29019 scales: { 29020 xAxes: [{ 29021 type: 'category', 29022 id: 'x-axis-0' 29023 }], 29024 yAxes: [{ 29025 type: 'linear', 29026 id: 'y-axis-0' 29027 }] 29028 } 29029}); 29030 29031module.exports = function(Chart) { 29032 29033 function lineEnabled(dataset, options) { 29034 return helpers.valueOrDefault(dataset.showLine, options.showLines); 29035 } 29036 29037 Chart.controllers.line = Chart.DatasetController.extend({ 29038 29039 datasetElementType: elements.Line, 29040 29041 dataElementType: elements.Point, 29042 29043 update: function(reset) { 29044 var me = this; 29045 var meta = me.getMeta(); 29046 var line = meta.dataset; 29047 var points = meta.data || []; 29048 var options = me.chart.options; 29049 var lineElementOptions = options.elements.line; 29050 var scale = me.getScaleForId(meta.yAxisID); 29051 var i, ilen, custom; 29052 var dataset = me.getDataset(); 29053 var showLine = lineEnabled(dataset, options); 29054 29055 // Update Line 29056 if (showLine) { 29057 custom = line.custom || {}; 29058 29059 // Compatibility: If the properties are defined with only the old name, use those values 29060 if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { 29061 dataset.lineTension = dataset.tension; 29062 } 29063 29064 // Utility 29065 line._scale = scale; 29066 line._datasetIndex = me.index; 29067 // Data 29068 line._children = points; 29069 // Model 29070 line._model = { 29071 // Appearance 29072 // The default behavior of lines is to break at null values, according 29073 // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158 29074 // This option gives lines the ability to span gaps 29075 spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps, 29076 tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension), 29077 backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), 29078 borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), 29079 borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), 29080 borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), 29081 borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), 29082 borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), 29083 borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
29084 fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), 29085 steppedLine: custom.steppedLine ? custom.steppedLine : helpers.valueOrDefault(dataset.steppedLine, lineElementOptions.stepped), 29086 cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.valueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode), 29087 }; 29088 29089 line.pivot(); 29090 } 29091 29092 // Update Points 29093 for (i = 0, ilen = points.length; i < ilen; ++i) { 29094 me.updateElement(points[i], i, reset); 29095 } 29096 29097 if (showLine && line._model.tension !== 0) { 29098 me.updateBezierControlPoints(); 29099 } 29100 29101 // Now pivot the point for animation 29102 for (i = 0, ilen = points.length; i < ilen; ++i) { 29103 points[i].pivot(); 29104 } 29105 }, 29106 29107 getPointBackgroundColor: function(point, index) { 29108 var backgroundColor = this.chart.options.elements.point.backgroundColor; 29109 var dataset = this.getDataset(); 29110 var custom = point.custom || {}; 29111 29112 if (custom.backgroundColor) { 29113 backgroundColor = custom.backgroundColor; 29114 }
29114 else if (dataset.pointBackgroundColor) { 29115 backgroundColor = helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor); 29116 } else if (dataset.backgroundColor) { 29117 backgroundColor = dataset.backgroundColor; 29118 } 29119 29120 return backgroundColor; 29121 }, 29122 29123 getPointBorderColor: function(point, index) { 29124 var borderColor = this.chart.options.elements.point.borderColor; 29125 var dataset = this.getDataset(); 29126 var custom = point.custom || {}; 29127 29128 if (custom.borderColor) { 29129 borderColor = custom.borderColor; 29130 } else if (dataset.pointBorderColor) { 29131 borderColor = helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor); 29132 } else if (dataset.borderColor) { 29133 borderColor = dataset.borderColor; 29134 } 29135 29136 return borderColor; 29137 }, 29138 29139 getPointBorderWidth: function(point, index) { 29140 var borderWidth = this.chart.options.elements.point.borderWidth; 29141 var dataset = this.getDataset(); 29142 var custom = point.custom || {}; 29143 29144 if (!isNaN(custom.borderWidth)) { 29145 borderWidth = custom.borderWidth; 29146 } else if (!isNaN(dataset.pointBorderWidth) || helpers.isArray(dataset.pointBorderWidth)) { 29147 borderWidth = helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth); 29148 } else if (!isNaN(dataset.borderWidth)) { 29149 borderWidth = dataset.borderWidth; 29150 } 29151 29152 return borderWidth; 29153 }, 29154 29155 updateElement: function(point, index, reset) { 29156 var me = this; 29157 var meta = me.getMeta(); 29158 var custom = point.custom || {}; 29159 var dataset = me.getDataset(); 29160 var datasetIndex = me.index; 29161 var value = dataset.data[index]; 29162 var yScale = me.getScaleForId(meta.yAxisID); 29163 var xScale = me.getScaleForId(meta.xAxisID); 29164 var pointOptions = me.chart.options.elements.point; 29165 var x, y; 29166 29167 // Compatibility: If the properties are defined with only the old name, use those values 29168 if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { 29169 dataset.pointRadius = dataset.radius; 29170 } 29171 if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) { 29172 dataset.pointHitRadius = dataset.hitRadius; 29173 } 29174 29175 x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex); 29176 y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex); 29177 29178 // Utility 29179 point._xScale = xScale; 29180 point._yScale = yScale; 29181 point._datasetIndex = datasetIndex; 29182 point._index = index; 29183 29184 // Desired view properties 29185 point._model = { 29186 x: x, 29187 y: y, 29188 skip: custom.skip || isNaN(x) || isNaN(y), 29189 // Appearance 29190 radius: custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius), 29191 pointStyle: custom.pointStyle || helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
29192 backgroundColor: me.getPointBackgroundColor(point, index), 29193 borderColor: me.getPointBorderColor(point, index), 29194 borderWidth: me.getPointBorderWidth(point, index), 29195 tension: meta.dataset._model ? meta.dataset._model.tension : 0, 29196 steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false, 29197 // Tooltip 29198 hitRadius: custom.hitRadius || helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius) 29199 }; 29200 }, 29201 29202 calculatePointY: function(value, index, datasetIndex) { 29203 var me = this; 29204 var chart = me.chart; 29205 var meta = me.getMeta(); 29206 var yScale = me.getScaleForId(meta.yAxisID); 29207 var sumPos = 0; 29208 var sumNeg = 0; 29209 var i, ds, dsMeta; 29210 29211 if (yScale.options.stacked) { 29212 for (i = 0; i < datasetIndex; i++) { 29213 ds = chart.data.datasets[i]; 29214 dsMeta = chart.getDatasetMeta(i); 29215 if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) { 29216 var stackedRightValue = Number(yScale.getRightValue(ds.data[index])); 29217 if (stackedRightValue < 0) { 29218 sumNeg += stackedRightValue || 0; 29219 } else { 29220 sumPos += stackedRightValue || 0; 29221 } 29222 } 29223 } 29224 29225 var rightValue = Number(yScale.getRightValue(value)); 29226 if (rightValue < 0) { 29227 return yScale.getPixelForValue(sumNeg + rightValue); 29228 } 29229 return yScale.getPixelForValue(sumPos + rightValue); 29230 } 29231 29232 return yScale.getPixelForValue(value); 29233 }, 29234 29235 updateBezierControlPoints: function() { 29236 var me = this; 29237 var meta = me.getMeta(); 29238 var area = me.chart.chartArea; 29239 var points = (meta.data || []); 29240 var i, ilen, point, model, controlPoints; 29241 29242 // Only consider points that are drawn in case the spanGaps option is used 29243 if (meta.dataset._model.spanGaps) { 29244 points = points.filter(function(pt) { 29245 return !pt._model.skip; 29246 }); 29247 } 29248 29249 function capControlPoint(pt, min, max) { 29250 return Math.max(Math.min(pt, max), min); 29251 } 29252 29253 if (meta.dataset._model.cubicInterpolationMode === 'monotone') { 29254 helpers.splineCurveMonotone(points); 29255 } else { 29256 for (i = 0, ilen = points.length; i < ilen; ++i) { 29257 point = points[i]; 29258 model = point._model; 29259 controlPoints = helpers.splineCurve( 29260 helpers.previousItem(points, i)._model, 29261 model, 29262 helpers.nextItem(points, i)._model, 29263 meta.dataset._model.tension 29264 ); 29265 model.controlPointPreviousX = controlPoints.previous.x; 29266 model.controlPointPreviousY = controlPoints.previous.y; 29267 model.controlPointNextX = controlPoints.next.x; 29268 model.controlPointNextY = controlPoints.next.y; 29269 } 29270 } 29271 29272 if (me.chart.options.elements.line.capBezierPoints) { 29273 for (i = 0, ilen = points.length; i < ilen; ++i) { 29274 model = points[i]._model; 29275 model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right); 29276 model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom); 29277 model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right); 29278 model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom); 29279 } 29280 } 29281 }, 29282 29283 draw: function() { 29284 var me = this; 29285 var chart = me.chart; 29286 var meta = me.getMeta(); 29287 var points = meta.data || []; 29288 var area = chart.chartArea; 29289 var ilen = points.length; 29290 var i = 0; 29291 29292 helpers.canvas.clipArea(chart.ctx, area); 29293 29294 if (lineEnabled(me.getDataset(), chart.options)) { 29295 meta.dataset.draw(); 29296 } 29297 29298 helpers.canvas.unclipArea(chart.ctx); 29299 29300 // Draw the points 29301 for (; i < ilen; ++i) { 29302 points[i].draw(area); 29303 } 29304 }, 29305 29306 setHoverStyle: function(point) { 29307 // Point 29308 var dataset = this.chart.data.datasets[point._datasetIndex]; 29309 var index = point._index; 29310 var custom = point.custom || {}; 29311 var model = point._model; 29312 29313 model.radius = custom.hoverRadius || helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); 29314 model.backgroundColor = custom.hoverBackgroundColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); 29315 model.borderColor = custom.hoverBorderColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor)); 29316 model.borderWidth = custom.hoverBorderWidth || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth); 29317 }, 29318 29319 removeHoverStyle: function(point) { 29320 var me = this; 29321 var dataset = me.chart.data.datasets[point._datasetIndex]; 29322 var index = point._index; 29323 var custom = point.custom || {}; 29324 var model = point._model; 29325 29326 // Compatibility: If the properties are defined with only the old name, use those values 29327 if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { 29328 dataset.pointRadius = dataset.radius; 29329 } 29330 29331 model.radius = custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);
29332 model.backgroundColor = me.getPointBackgroundColor(point, index); 29333 model.borderColor = me.getPointBorderColor(point, index); 29334 model.borderWidth = me.getPointBorderWidth(point, index); 29335 } 29336 }); 29337}; 29338 29339},{"25":25,"40":40,"45":45}],19:[function(require,module,exports){ 29340'use strict'; 29341 29342var defaults = require(25); 29343var elements = require(40); 29344var helpers = require(45); 29345 29346defaults._set('polarArea', { 29347 scale: { 29348 type: 'radialLinear', 29349 angleLines: { 29350 display: false 29351 }, 29352 gridLines: { 29353 circular: true 29354 }, 29355 pointLabels: { 29356 display: false 29357 }, 29358 ticks: { 29359 beginAtZero: true 29360 } 29361 }, 29362 29363 // Boolean - Whether to animate the rotation of the chart 29364 animation: { 29365 animateRotate: true, 29366 animateScale: true 29367 }, 29368 29369 startAngle: -0.5 * Math.PI, 29370 legendCallback: function(chart) { 29371 var text = []; 29372 text.push('<ul class="' + chart.id + '-legend">'); 29373 29374 var data = chart.data; 29375 var datasets = data.datasets; 29376 var labels = data.labels; 29377 29378 if (datasets.length) { 29379 for (var i = 0; i < datasets[0].data.length; ++i) { 29380 text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>'); 29381 if (labels[i]) { 29382 text.push(labels[i]); 29383 } 29384 text.push('</li>'); 29385 } 29386 } 29387 29388 text.push('</ul>'); 29389 return text.join(''); 29390 }, 29391 legend: { 29392 labels: { 29393 generateLabels: function(chart) { 29394 var data = chart.data; 29395 if (data.labels.length && data.datasets.length) { 29396 return data.labels.map(function(label, i) { 29397 var meta = chart.getDatasetMeta(0); 29398 var ds = data.datasets[0]; 29399 var arc = meta.data[i]; 29400 var custom = arc.custom || {}; 29401 var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault; 29402 var arcOpts = chart.options.elements.arc; 29403 var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); 29404 var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); 29405 var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); 29406 29407 return { 29408 text: label, 29409 fillStyle: fill, 29410 strokeStyle: stroke, 29411 lineWidth: bw, 29412 hidden: isNaN(ds.data[i]) || meta.data[i].hidden, 29413 29414 // Extra data used for toggling the correct item 29415 index: i 29416 }; 29417 }); 29418 } 29419 return []; 29420 } 29421 }, 29422 29423 onClick: function(e, legendItem) { 29424 var index = legendItem.index; 29425 var chart = this.chart; 29426 var i, ilen, meta; 29427 29428 for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { 29429 meta = chart.getDatasetMeta(i); 29430 meta.data[index].hidden = !meta.data[index].hidden; 29431 } 29432 29433 chart.update(); 29434 } 29435 }, 29436 29437 // Need to override these to give a nice default 29438 tooltips: { 29439 callbacks: { 29440 title: function() { 29441 return ''; 29442 }, 29443 label: function(item, data) { 29444 return data.labels[item.index] + ': ' + item.yLabel; 29445 } 29446 } 29447 } 29448}); 29449 29450module.exports = function(Chart) { 29451 29452 Chart.controllers.polarArea = Chart.DatasetController.extend({ 29453 29454 dataElementType: elements.Arc, 29455 29456 linkScales: helpers.noop, 29457 29458 update: function(reset) { 29459 var me = this; 29460 var chart = me.chart; 29461 var chartArea = chart.chartArea; 29462 var meta = me.getMeta(); 29463 var opts = chart.options; 29464 var arcOpts = opts.elements.arc; 29465 var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); 29466 chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0); 29467 chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0); 29468 chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); 29469 29470 me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
29471 me.innerRadius = me.outerRadius - chart.radiusLength; 29472 29473 meta.count = me.countVisibleElements(); 29474 29475 helpers.each(meta.data, function(arc, index) { 29476 me.updateElement(arc, index, reset); 29477 }); 29478 }, 29479 29480 updateElement: function(arc, index, reset) { 29481 var me = this; 29482 var chart = me.chart; 29483 var dataset = me.getDataset(); 29484 var opts = chart.options; 29485 var animationOpts = opts.animation; 29486 var scale = chart.scale; 29487 var labels = chart.data.labels; 29488 29489 var circumference = me.calculateCircumference(dataset.data[index]); 29490 var centerX = scale.xCenter; 29491 var centerY = scale.yCenter; 29492 29493 // If there is NaN data before us, we need to calculate the starting angle correctly. 29494 // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data 29495 var visibleCount = 0; 29496 var meta = me.getMeta(); 29497 for (var i = 0; i < index; ++i) { 29498 if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) { 29499 ++visibleCount; 29500 } 29501 } 29502 29503 // var negHalfPI = -0.5 * Math.PI; 29504 var datasetStartAngle = opts.startAngle; 29505 var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); 29506 var startAngle = datasetStartAngle + (circumference * visibleCount); 29507 var endAngle = startAngle + (arc.hidden ? 0 : circumference); 29508 29509 var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); 29510 29511 helpers.extend(arc, { 29512 // Utility 29513 _datasetIndex: me.index, 29514 _index: index, 29515 _scale: scale, 29516 29517 // Desired view properties 29518 _model: { 29519 x: centerX, 29520 y: centerY, 29521 innerRadius: 0, 29522 outerRadius: reset ? resetRadius : distance, 29523 startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle, 29524 endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle, 29525 label: helpers.valueAtIndexOrDefault(labels, index, labels[index]) 29526 } 29527 }); 29528 29529 // Apply border and fill style 29530 me.removeHoverStyle(arc); 29531 29532 arc.pivot(); 29533 }, 29534 29535 removeHoverStyle: function(arc) { 29536 Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc); 29537 }, 29538 29539 countVisibleElements: function() { 29540 var dataset = this.getDataset(); 29541 var meta = this.getMeta(); 29542 var count = 0; 29543 29544 helpers.each(meta.data, function(element, index) { 29545 if (!isNaN(dataset.data[index]) && !element.hidden) { 29546 count++; 29547 } 29548 }); 29549 29550 return count; 29551 }, 29552 29553 calculateCircumference: function(value) { 29554 var count = this.getMeta().count; 29555 if (count > 0 && !isNaN(value)) { 29556 return (2 * Math.PI) / count; 29557 } 29558 return 0; 29559 } 29560 }); 29561}; 29562 29563},{"25":25,"40":40,"45":45}],20:[function(require,module,exports){ 29564'use strict'; 29565 29566var defaults = require(25); 29567var elements = require(40); 29568var helpers = require(45); 29569 29570defaults._set('radar', { 29571 scale: { 29572 type: 'radialLinear' 29573 }, 29574 elements: { 29575 line: { 29576 tension: 0 // no bezier in radar 29577 } 29578 } 29579}); 29580 29581module.exports = function(Chart) { 29582 29583 Chart.controllers.radar = Chart.DatasetController.extend({ 29584 29585 datasetElementType: elements.Line, 29586 29587 dataElementType: elements.Point, 29588 29589 linkScales: helpers.noop, 29590 29591 update: function(reset) { 29592 var me = this; 29593 var meta = me.getMeta(); 29594 var line = meta.dataset; 29595 var points = meta.data; 29596 var custom = line.custom || {}; 29597 var dataset = me.getDataset(); 29598 var lineElementOptions = me.chart.options.elements.line; 29599 var scale = me.chart.scale; 29600 29601 // Compatibility: If the properties are defined with only the old name, use those values 29602 if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { 29603 dataset.lineTension = dataset.tension; 29604 } 29605 29606 helpers.extend(meta.dataset, { 29607 // Utility 29608 _datasetIndex: me.index, 29609 _scale: scale, 29610 // Data 29611 _children: points, 29612 _loop: true, 29613 // Model 29614 _model: { 29615 // Appearance 29616 tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension), 29617 backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), 29618 borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), 29619 borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
29620 fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), 29621 borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), 29622 borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), 29623 borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), 29624 borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), 29625 } 29626 }); 29627 29628 meta.dataset.pivot(); 29629 29630 // Update Points 29631 helpers.each(points, function(point, index) { 29632 me.updateElement(point, index, reset); 29633 }, me); 29634 29635 // Update bezier control points 29636 me.updateBezierControlPoints(); 29637 }, 29638 updateElement: function(point, index, reset) { 29639 var me = this; 29640 var custom = point.custom || {}; 29641 var dataset = me.getDataset(); 29642 var scale = me.chart.scale; 29643 var pointElementOptions = me.chart.options.elements.point; 29644 var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); 29645 29646 // Compatibility: If the properties are defined with only the old name, use those values 29647 if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { 29648 dataset.pointRadius = dataset.radius; 29649 } 29650 if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) { 29651 dataset.pointHitRadius = dataset.hitRadius; 29652 } 29653 29654 helpers.extend(point, { 29655 // Utility 29656 _datasetIndex: me.index, 29657 _index: index, 29658 _scale: scale, 29659 29660 // Desired view properties 29661 _model: { 29662 x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales 29663 y: reset ? scale.yCenter : pointPosition.y, 29664 29665 // Appearance 29666 tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension), 29667 radius: custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius), 29668 backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroun
29668dColor, index, pointElementOptions.backgroundColor), 29669 borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor), 29670 borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth), 29671 pointStyle: custom.pointStyle ? custom.pointStyle : helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle), 29672 29673 // Tooltip 29674 hitRadius: custom.hitRadius ? custom.hitRadius : helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius) 29675 } 29676 }); 29677 29678 point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); 29679 }, 29680 updateBezierControlPoints: function() { 29681 var chartArea = this.chart.chartArea; 29682 var meta = this.getMeta(); 29683 29684 helpers.each(meta.data, function(point, index) { 29685 var model = point._model; 29686 var controlPoints = helpers.splineCurve( 29687 helpers.previousItem(meta.data, index, true)._model, 29688 model, 29689 helpers.nextItem(meta.data, index, true)._model, 29690 model.tension 29691 ); 29692 29693 // Prevent the bezier going outside of the bounds of the graph 29694 model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left); 29695 model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top); 29696 29697 model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left); 29698 model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top); 29699 29700 // Now pivot the point for animation 29701 point.pivot(); 29702 }); 29703 }, 29704 29705 setHoverStyle: function(point) { 29706 // Point 29707 var dataset = this.chart.data.datasets[point._datasetIndex]; 29708 var custom = point.custom || {}; 29709 var index = point._index; 29710 var model = point._model; 29711 29712 model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); 29713 model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); 29714 model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor)); 29715 model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth); 29716 }, 29717 29718 removeHoverStyle: function(point) { 29719 var dataset = this.chart.data.datasets[point._datasetIndex]; 29720 var custom = point.custom || {}; 29721 var index = point._index; 29722 var model = point._model; 29723 var pointElementOptions = this.chart.options.elements.point; 29724 29725 model.radius = custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius); 29726 model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroun
29726dColor, index, pointElementOptions.backgroundColor); 29727 model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor); 29728 model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth); 29729 } 29730 }); 29731}; 29732 29733},{"25":25,"40":40,"45":45}],21:[function(require,module,exports){ 29734'use strict'; 29735 29736var defaults = require(25); 29737 29738defaults._set('scatter', { 29739 hover: { 29740 mode: 'single' 29741 }, 29742 29743 scales: { 29744 xAxes: [{ 29745 id: 'x-axis-1', // need an ID so datasets can reference the scale 29746 type: 'linear', // scatter should not use a category axis 29747 position: 'bottom' 29748 }], 29749 yAxes: [{ 29750 id: 'y-axis-1', 29751 type: 'linear', 29752 position: 'left' 29753 }] 29754 }, 29755 29756 showLines: false, 29757 29758 tooltips: { 29759 callbacks: { 29760 title: function() { 29761 return ''; // doesn't make sense for scatter since data are formatted as a point 29762 }, 29763 label: function(item) { 29764 return '(' + item.xLabel + ', ' + item.yLabel + ')'; 29765 } 29766 } 29767 } 29768}); 29769 29770module.exports = function(Chart) { 29771 29772 // Scatter charts use line controllers 29773 Chart.controllers.scatter = Chart.controllers.line; 29774 29775}; 29776 29777},{"25":25}],22:[function(require,module,exports){ 29778/* global window: false */ 29779'use strict'; 29780 29781var defaults = require(25); 29782var Element = require(26); 29783var helpers = require(45); 29784 29785defaults._set('global', { 29786 animation: { 29787 duration: 1000, 29788 easing: 'easeOutQuart', 29789 onProgress: helpers.noop, 29790 onComplete: helpers.noop 29791 } 29792}); 29793 29794module.exports = function(Chart) { 29795 29796 Chart.Animation = Element.extend({ 29797 chart: null, // the animation associated chart instance 29798 currentStep: 0, // the current animation step 29799 numSteps: 60, // default number of steps 29800 easing: '', // the easing to use for this animation 29801 render: null, // render function used by the animation service 29802 29803 onAnimationProgress: null, // user specified callback to fire on each step of the animation 29804 onAnimationComplete: null, // user specified callback to fire when the animation finishes 29805 }); 29806 29807 Chart.animationService = { 29808 frameDuration: 17, 29809 animations: [], 29810 dropFrames: 0, 29811 request: null, 29812 29813 /** 29814 * @param {Chart} chart - The chart to animate. 29815 * @param {Chart.Animation} animation - The animation that we will animate. 29816 * @param {Number} duration - The animation duration in ms. 29817 * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions 29818 */ 29819 addAnimation: function(chart, animation, duration, lazy) { 29820 var animations = this.animations; 29821 var i, ilen; 29822 29823 animation.chart = chart; 29824 29825 if (!lazy) { 29826 chart.animating = true; 29827 } 29828 29829 for (i = 0, ilen = animations.length; i < ilen; ++i) { 29830 if (animations[i].chart === chart) { 29831 animations[i] = animation; 29832 return; 29833 } 29834 } 29835 29836 animations.push(animation); 29837 29838 // If there are no animations queued, manually kickstart a digest, for lack of a better word 29839 if (animations.length === 1) { 29840 this.requestAnimationFrame(); 29841 } 29842 }, 29843 29844 cancelAnimation: function(chart) { 29845 var index = helpers.findIndex(this.animations, function(animation) { 29846 return animation.chart === chart; 29847 }); 29848 29849 if (index !== -1) { 29850 this.animations.splice(index, 1); 29851 chart.animating = false; 29852 } 29853 }, 29854 29855 requestAnimationFrame: function() { 29856 var me = this; 29857 if (me.request === null) { 29858 // Skip animation frame requests until the active one is executed. 29859 // This can happen when processing mouse events, e.g. 'mousemove' 29860 // and 'mouseout' events will trigger multiple renders. 29861 me.request = helpers.requestAnimFrame.call(window, function() { 29862 me.request = null; 29863 me.startDigest(); 29864 }); 29865 } 29866 }, 29867 29868 /** 29869 * @private 29870 */ 29871 startDigest: function() { 29872 var me = this; 29873 var startTime = Date.now(); 29874 var framesToDrop = 0; 29875 29876 if (me.dropFrames > 1) { 29877 framesToDrop = Math.floor(me.dropFrames); 29878 me.dropFrames = me.dropFrames % 1; 29879 } 29880 29881 me.advance(1 + framesToDrop); 29882 29883 var endTime = Date.now(); 29884 29885 me.dropFrames += (endTime - startTime) / me.frameDuration; 29886 29887 // Do we have more stuff to animate? 29888 if (me.animations.length > 0) { 29889 me.requestAnimationFrame(); 29890 } 29891 }, 29892 29893 /** 29894 * @private 29895 */ 29896 advance: function(count) { 29897 var animations = this.animations; 29898 var animation, chart; 29899 var i = 0; 29900 29901 while (i < animations.length) { 29902 animation = animations[i]; 29903 chart = animation.chart; 29904 29905 animation.currentStep = (animation.currentStep || 0) + count; 29906 animation.currentStep = Math.min(animation.currentStep, animation.numSteps); 29907 29908 helpers.callback(animation.render, [chart, animation], chart); 29909 helpers.callback(animation.onAnimationProgress, [animation], chart); 29910 29911 if (animation.currentStep >= animation.numSteps) { 29912 helpers.callback(animation.onAnimationComplete, [animation], chart); 29913 chart.animating = false;
29914 animations.splice(i, 1); 29915 } else { 29916 ++i; 29917 } 29918 } 29919 } 29920 }; 29921 29922 /** 29923 * Provided for backward compatibility, use Chart.Animation instead 29924 * @prop Chart.Animation#animationObject 29925 * @deprecated since version 2.6.0 29926 * @todo remove at version 3 29927 */ 29928 Object.defineProperty(Chart.Animation.prototype, 'animationObject', { 29929 get: function() { 29930 return this; 29931 } 29932 }); 29933 29934 /** 29935 * Provided for backward compatibility, use Chart.Animation#chart instead 29936 * @prop Chart.Animation#chartInstance 29937 * @deprecated since version 2.6.0 29938 * @todo remove at version 3 29939 */ 29940 Object.defineProperty(Chart.Animation.prototype, 'chartInstance', { 29941 get: function() { 29942 return this.chart; 29943 }, 29944 set: function(value) { 29945 this.chart = value; 29946 } 29947 }); 29948 29949}; 29950 29951},{"25":25,"26":26,"45":45}],23:[function(require,module,exports){ 29952'use strict'; 29953 29954var defaults = require(25); 29955var helpers = require(45); 29956var Interaction = require(28); 29957var layouts = require(30); 29958var platform = require(48); 29959var plugins = require(31); 29960 29961module.exports = function(Chart) { 29962 29963 // Create a dictionary of chart types, to allow for extension of existing types 29964 Chart.types = {}; 29965 29966 // Store a reference to each instance - allowing us to globally resize chart instances on window resize. 29967 // Destroy method on the chart will remove the instance of the chart from this reference. 29968 Chart.instances = {}; 29969 29970 // Controllers available for dataset visualization eg. bar, line, slice, etc. 29971 Chart.controllers = {}; 29972 29973 /** 29974 * Initializes the given config with global and chart default values. 29975 */ 29976 function initConfig(config) { 29977 config = config || {}; 29978 29979 // Do NOT use configMerge() for the data object because this method merges arrays 29980 // and so would change references to labels and datasets, preventing data updates. 29981 var data = config.data = config.data || {}; 29982 data.datasets = data.datasets || []; 29983 data.labels = data.labels || []; 29984 29985 config.options = helpers.configMerge( 29986 defaults.global, 29987 defaults[config.type], 29988 config.options || {}); 29989 29990 return config; 29991 } 29992 29993 /** 29994 * Updates the config of the chart 29995 * @param chart {Chart} chart to update the options for 29996 */ 29997 function updateConfig(chart) { 29998 var newOptions = chart.options; 29999 30000 helpers.each(chart.scales, function(scale) { 30001 layouts.removeBox(chart, scale); 30002 }); 30003 30004 newOptions = helpers.configMerge( 30005 Chart.defaults.global, 30006 Chart.defaults[chart.config.type], 30007 newOptions); 30008 30009 chart.options = chart.config.options = newOptions; 30010 chart.ensureScalesHaveIDs(); 30011 chart.buildOrUpdateScales(); 30012 // Tooltip 30013 chart.tooltip._options = newOptions.tooltips; 30014 chart.tooltip.initialize(); 30015 } 30016 30017 function positionIsHorizontal(position) { 30018 return position === 'top' || position === 'bottom'; 30019 } 30020 30021 helpers.extend(Chart.prototype, /** @lends Chart */ { 30022 /** 30023 * @private 30024 */ 30025 construct: function(item, config) { 30026 var me = this; 30027 30028 config = initConfig(config); 30029 30030 var context = platform.acquireContext(item, config); 30031 var canvas = context && context.canvas; 30032 var height = canvas && canvas.height; 30033 var width = canvas && canvas.width; 30034 30035 me.id = helpers.uid(); 30036 me.ctx = context; 30037 me.canvas = canvas; 30038 me.config = config; 30039 me.width = width; 30040 me.height = height; 30041 me.aspectRatio = height ? width / height : null; 30042 me.options = config.options; 30043 me._bufferedRender = false;
vendor: 10,788 bytes, lines 30044-30442
30044 30045 /** 30046 * Provided for backward compatibility, Chart and Chart.Controller have been merged, 30047 * the "instance" still need to be defined since it might be called from plugins. 30048 * @prop Chart#chart 30049 * @deprecated since version 2.6.0 30050 * @todo remove at version 3 30051 * @private 30052 */ 30053 me.chart = me; 30054 me.controller = me; // chart.chart.controller #inception 30055 30056 // Add the chart instance to the global namespace 30057 Chart.instances[me.id] = me; 30058 30059 // Define alias to the config data: `chart.data === chart.config.data` 30060 Object.defineProperty(me, 'data', { 30061 get: function() { 30062 return me.config.data; 30063 }, 30064 set: function(value) { 30065 me.config.data = value; 30066 } 30067 }); 30068 30069 if (!context || !canvas) { 30070 // The given item is not a compatible context2d element, let's return before finalizing 30071 // the chart initialization but after setting basic chart / controller properties that 30072 // can help to figure out that the chart is not valid (e.g chart.canvas !== null); 30073 // https://github.com/chartjs/Chart.js/issues/2807 30074 console.error("Failed to create chart: can't acquire context from the given item"); 30075 return; 30076 } 30077 30078 me.initialize(); 30079 me.update(); 30080 }, 30081 30082 /** 30083 * @private 30084 */ 30085 initialize: function() { 30086 var me = this; 30087 30088 // Before init plugin notification 30089 plugins.notify(me, 'beforeInit'); 30090 30091 helpers.retinaScale(me, me.options.devicePixelRatio); 30092 30093 me.bindEvents(); 30094 30095 if (me.options.responsive) { 30096 // Initial resize before chart draws (must be silent to preserve initial animations). 30097 me.resize(true); 30098 } 30099 30100 // Make sure scales have IDs and are built before we build any controllers. 30101 me.ensureScalesHaveIDs(); 30102 me.buildOrUpdateScales(); 30103 me.initToolTip(); 30104 30105 // After init plugin notification 30106 plugins.notify(me, 'afterInit'); 30107 30108 return me; 30109 }, 30110 30111 clear: function() { 30112 helpers.canvas.clear(this); 30113 return this; 30114 }, 30115 30116 stop: function() { 30117 // Stops any current animation loop occurring 30118 Chart.animationService.cancelAnimation(this); 30119 return this; 30120 }, 30121 30122 resize: function(silent) { 30123 var me = this; 30124 var options = me.options; 30125 var canvas = me.canvas; 30126 var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null; 30127 30128 // the canvas render width and height will be casted to integers so make sure that 30129 // the canvas display style uses the same integer values to avoid blurring effect. 30130 30131 // Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collased 30132 var newWidth = Math.max(0, Math.floor(helpers.getMaximumWidth(canvas))); 30133 var newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas))); 30134 30135 if (me.width === newWidth && me.height === newHeight) { 30136 return; 30137 } 30138 30139 canvas.width = me.width = newWidth; 30140 canvas.height = me.height = newHeight; 30141 canvas.style.width = newWidth + 'px'; 30142 canvas.style.height = newHeight + 'px'; 30143 30144 helpers.retinaScale(me, options.devicePixelRatio); 30145 30146 if (!silent) { 30147 // Notify any plugins about the resize 30148 var newSize = {width: newWidth, height: newHeight}; 30149 plugins.notify(me, 'resize', [newSize]); 30150 30151 // Notify of resize 30152 if (me.options.onResize) { 30153 me.options.onResize(me, newSize); 30154 } 30155 30156 me.stop(); 30157 me.update(me.options.responsiveAnimationDuration); 30158 } 30159 }, 30160 30161 ensureScalesHaveIDs: function() { 30162 var options = this.options; 30163 var scalesOptions = options.scales || {}; 30164 var scaleOptions = options.scale; 30165 30166 helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) { 30167 xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index); 30168 }); 30169 30170 helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) { 30171 yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index); 30172 }); 30173 30174 if (scaleOptions) { 30175 scaleOptions.id = scaleOptions.id || 'scale'; 30176 } 30177 }, 30178 30179 /** 30180 * Builds a map of scale ID to scale object for future lookup. 30181 */ 30182 buildOrUpdateScales: function() { 30183 var me = this; 30184 var options = me.options; 30185 var scales = me.scales || {}; 30186 var items = []; 30187 var updated = Object.keys(scales).reduce(function(obj, id) { 30188 obj[id] = false; 30189 return obj; 30190 }, {}); 30191 30192 if (options.scales) { 30193 items = items.concat( 30194 (options.scales.xAxes || []).map(function(xAxisOptions) { 30195 return {options: xAxisOptions, dtype: 'category', dposition: 'bottom'}; 30196 }), 30197 (options.scales.yAxes || []).map(function(yAxisOptions) { 30198 return {options: yAxisOptions, dtype: 'linear', dposition: 'left'}; 30199 }) 30200 ); 30201 } 30202 30203 if (options.scale) { 30204 items.push({ 30205 options: options.scale, 30206 dtype: 'radialLinear', 30207 isDefault: true, 30208 dposition: 'chartArea' 30209 }); 30210 } 30211 30212 helpers.each(items, function(item) { 30213 var scaleOptions = item.options; 30214 var id = scaleOptions.id; 30215 var scaleType = helpers.valueOrDefault(scaleOptions.type, item.dtype); 30216 30217 if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) { 30218 scaleOptions.position = item.dposition; 30219 } 30220 30221 updated[id] = true; 30222 var scale = null; 30223 if (id in scales && scales[id].type === scaleType) { 30224 scale = scales[id]; 30225 scale.options = scaleOptions; 30226 scale.ctx = me.ctx; 30227 scale.chart = me; 30228 } else { 30229 var scaleClass = Chart.scaleService.getScaleConstructor(scaleType); 30230 if (!scaleClass) { 30231 return; 30232 } 30233 scale = new scaleClass({ 30234 id: id, 30235 type: scaleType, 30236 options: scaleOptions, 30237 ctx: me.ctx, 30238 chart: me 30239 }); 30240 scales[scale.id] = scale; 30241 } 30242 30243 scale.mergeTicksOptions(); 30244 30245 // TODO(SB): I think we should be able to remove this custom case (options.scale) 30246 // and consider it as a regular scale part of the "scales"" map only! This would 30247 // make the logic easier and remove some useless? custom code. 30248 if (item.isDefault) { 30249 me.scale = scale; 30250 } 30251 }); 30252 // clear up discarded scales 30253 helpers.each(updated, function(hasUpdated, id) { 30254 if (!hasUpdated) { 30255 delete scales[id]; 30256 } 30257 }); 30258 30259 me.scales = scales; 30260 30261 Chart.scaleService.addScalesToLayout(this); 30262 }, 30263 30264 buildOrUpdateControllers: function() { 30265 var me = this; 30266 var types = []; 30267 var newControllers = []; 30268 30269 helpers.each(me.data.datasets, function(dataset, datasetIndex) { 30270 var meta = me.getDatasetMeta(datasetIndex); 30271 var type = dataset.type || me.config.type; 30272 30273 if (meta.type && meta.type !== type) { 30274 me.destroyDatasetMeta(datasetIndex); 30275 meta = me.getDatasetMeta(datasetIndex); 30276 } 30277 meta.type = type; 30278 30279 types.push(meta.type); 30280 30281 if (meta.controller) { 30282 meta.controller.updateIndex(datasetIndex); 30283 meta.controller.linkScales(); 30284 } else { 30285 var ControllerClass = Chart.controllers[meta.type]; 30286 if (ControllerClass === undefined) { 30287 throw new Error('"' + meta.type + '" is not a chart type.'); 30288 } 30289 30290 meta.controller = new ControllerClass(me, datasetIndex); 30291 newControllers.push(meta.controller); 30292 } 30293 }, me); 30294 30295 return newControllers; 30296 }, 30297 30298 /** 30299 * Reset the elements of all datasets 30300 * @private 30301 */ 30302 resetElements: function() { 30303 var me = this; 30304 helpers.each(me.data.datasets, function(dataset, datasetIndex) { 30305 me.getDatasetMeta(datasetIndex).controller.reset(); 30306 }, me); 30307 }, 30308 30309 /** 30310 * Resets the chart back to it's state before the initial animation 30311 */ 30312 reset: function() { 30313 this.resetElements(); 30314 this.tooltip.initialize(); 30315 }, 30316 30317 update: function(config) { 30318 var me = this; 30319 30320 if (!config || typeof config !== 'object') { 30321 // backwards compatibility 30322 config = { 30323 duration: config, 30324 lazy: arguments[1] 30325 }; 30326 } 30327 30328 updateConfig(me); 30329 30330 // plugins options references might have change, let's invalidate the cache 30331 // https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167 30332 plugins._invalidate(me); 30333 30334 if (plugins.notify(me, 'beforeUpdate') === false) { 30335 return; 30336 } 30337 30338 // In case the entire data object changed 30339 me.tooltip._data = me.data; 30340 30341 // Make sure dataset controllers are updated and new controllers are reset 30342 var newControllers = me.buildOrUpdateControllers(); 30343 30344 // Make sure all dataset controllers have correct meta data counts 30345 helpers.each(me.data.datasets, function(dataset, datasetIndex) { 30346 me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements(); 30347 }, me); 30348 30349 me.updateLayout(); 30350 30351 // Can only reset the new controllers after the scales have been updated 30352 if (me.options.animation && me.options.animation.duration) { 30353 helpers.each(newControllers, function(controller) { 30354 controller.reset(); 30355 }); 30356 } 30357 30358 me.updateDatasets(); 30359 30360 // Need to reset tooltip in case it is displayed with elements that are removed 30361 // after update. 30362 me.tooltip.initialize(); 30363 30364 // Last active contains items that were previously in the tooltip. 30365 // When we reset the tooltip, we need to clear it 30366 me.lastActive = []; 30367 30368 // Do this before render so that any plugins that need final scale updates can use it 30369 plugins.notify(me, 'afterUpdate'); 30370 30371 if (me._bufferedRender) { 30372 me._bufferedRequest = { 30373 duration: config.duration, 30374 easing: config.easing, 30375 lazy: config.lazy 30376 }; 30377 } else { 30378 me.render(config); 30379 } 30380 }, 30381 30382 /** 30383 * Updates the chart layout unless a plugin returns `false` to the `beforeLayout` 30384 * hook, in which case, plugins will not be called on `afterLayout`. 30385 * @private 30386 */ 30387 updateLayout: function() { 30388 var me = this; 30389 30390 if (plugins.notify(me, 'beforeLayout') === false) { 30391 return; 30392 } 30393 30394 layouts.update(this, this.width, this.height); 30395 30396 /** 30397 * Provided for backward compatibility, use `afterLayout` instead. 30398 * @method IPlugin#afterScaleUpdate 30399 * @deprecated since version 2.5.0 30400 * @todo remove at version 3 30401 * @private 30402 */ 30403 plugins.notify(me, 'afterScaleUpdate'); 30404 plugins.notify(me, 'afterLayout'); 30405 }, 30406 30407 /** 30408 * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate` 30409 * hook, in which case, plugins will not be called on `afterDatasetsUpdate`. 30410 * @private 30411 */ 30412 updateDatasets: function() { 30413 var me = this; 30414 30415 if (plugins.notify(me, 'beforeDatasetsUpdate') === false) { 30416 return; 30417 } 30418 30419 for (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) { 30420 me.updateDataset(i); 30421 } 30422 30423 plugins.notify(me, 'afterDatasetsUpdate'); 30424 }, 30425 30426 /** 30427 * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate` 30428 * hook, in which case, plugins will not be called on `afterDatasetUpdate`. 30429 * @private 30430 */ 30431 updateDataset: function(index) { 30432 var me = this; 30433 var meta = me.getDatasetMeta(index); 30434 var args = { 30435 meta: meta, 30436 index: index 30437 }; 30438 30439 if (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) { 30440 return; 30441 } 30442
30443 meta.controller.update(); 30444 30445 plugins.notify(me, 'afterDatasetUpdate', [args]); 30446 }, 30447 30448 render: function(config) { 30449 var me = this; 30450 30451 if (!config || typeof config !== 'object') { 30452 // backwards compatibility 30453 config = { 30454 duration: config, 30455 lazy: arguments[1] 30456 }; 30457 } 30458 30459 var duration = config.duration; 30460 var lazy = config.lazy; 30461 30462 if (plugins.notify(me, 'beforeRender') === false) { 30463 return; 30464 } 30465 30466 var animationOptions = me.options.animation; 30467 var onComplete = function(animation) { 30468 plugins.notify(me, 'afterRender'); 30469 helpers.callback(animationOptions && animationOptions.onComplete, [animation], me); 30470 }; 30471 30472 if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) { 30473 var animation = new Chart.Animation({ 30474 numSteps: (duration || animationOptions.duration) / 16.66, // 60 fps 30475 easing: config.easing || animationOptions.easing, 30476 30477 render: function(chart, animationObject) { 30478 var easingFunction = helpers.easing.effects[animationObject.easing]; 30479 var currentStep = animationObject.currentStep; 30480 var stepDecimal = currentStep / animationObject.numSteps; 30481 30482 chart.draw(easingFunction(stepDecimal), stepDecimal, currentStep); 30483 }, 30484 30485 onAnimationProgress: animationOptions.onProgress, 30486 onAnimationComplete: onComplete 30487 }); 30488 30489 Chart.animationService.addAnimation(me, animation, duration, lazy); 30490 } else { 30491 me.draw(); 30492 30493 // See https://github.com/chartjs/Chart.js/issues/3781 30494 onComplete(new Chart.Animation({numSteps: 0, chart: me})); 30495 } 30496 30497 return me; 30498 }, 30499 30500 draw: function(easingValue) { 30501 var me = this; 30502 30503 me.clear(); 30504 30505 if (helpers.isNullOrUndef(easingValue)) { 30506 easingValue = 1; 30507 } 30508 30509 me.transition(easingValue); 30510 30511 if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) { 30512 return; 30513 } 30514 30515 // Draw all the scales 30516 helpers.each(me.boxes, function(box) { 30517 box.draw(me.chartArea); 30518 }, me); 30519 30520 if (me.scale) { 30521 me.scale.draw(); 30522 } 30523 30524 me.drawDatasets(easingValue); 30525 me._drawTooltip(easingValue); 30526 30527 plugins.notify(me, 'afterDraw', [easingValue]); 30528 }, 30529 30530 /** 30531 * @private 30532 */ 30533 transition: function(easingValue) { 30534 var me = this; 30535 30536 for (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) { 30537 if (me.isDatasetVisible(i)) { 30538 me.getDatasetMeta(i).controller.transition(easingValue); 30539 } 30540 } 30541 30542 me.tooltip.transition(easingValue); 30543 }, 30544 30545 /** 30546 * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw` 30547 * hook, in which case, plugins will not be called on `afterDatasetsDraw`. 30548 * @private 30549 */ 30550 drawDatasets: function(easingValue) { 30551 var me = this; 30552 30553 if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) { 30554 return; 30555 } 30556 30557 // Draw datasets reversed to support proper line stacking 30558 for (var i = (me.data.datasets || []).length - 1; i >= 0; --i) { 30559 if (me.isDatasetVisible(i)) { 30560 me.drawDataset(i, easingValue); 30561 } 30562 } 30563 30564 plugins.notify(me, 'afterDatasetsDraw', [easingValue]); 30565 }, 30566 30567 /** 30568 * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw` 30569 * hook, in which case, plugins will not be called on `afterDatasetDraw`. 30570 * @private 30571 */ 30572 drawDataset: function(index, easingValue) { 30573 var me = this; 30574 var meta = me.getDatasetMeta(index); 30575 var args = { 30576 meta: meta, 30577 index: index, 30578 easingValue: easingValue 30579 }; 30580 30581 if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) { 30582 return; 30583 } 30584 30585 meta.controller.draw(easingValue); 30586 30587 plugins.notify(me, 'afterDatasetDraw', [args]); 30588 }, 30589 30590 /** 30591 * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw` 30592 * hook, in which case, plugins will not be called on `afterTooltipDraw`. 30593 * @private 30594 */ 30595 _drawTooltip: function(easingValue) { 30596 var me = this; 30597 var tooltip = me.tooltip; 30598 var args = { 30599 tooltip: tooltip, 30600 easingValue: easingValue 30601 }; 30602 30603 if (plugins.notify(me, 'beforeTooltipDraw', [args]) === false) { 30604 return; 30605 } 30606 30607 tooltip.draw(); 30608 30609 plugins.notify(me, 'afterTooltipDraw', [args]); 30610 }, 30611 30612 // Get the single element that was clicked on
vendor: 45,871 bytes, lines 30613-32217
30613 // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw 30614 getElementAtEvent: function(e) { 30615 return Interaction.modes.single(this, e); 30616 }, 30617 30618 getElementsAtEvent: function(e) { 30619 return Interaction.modes.label(this, e, {intersect: true}); 30620 }, 30621 30622 getElementsAtXAxis: function(e) { 30623 return Interaction.modes['x-axis'](this, e, {intersect: true}); 30624 }, 30625 30626 getElementsAtEventForMode: function(e, mode, options) { 30627 var method = Interaction.modes[mode]; 30628 if (typeof method === 'function') { 30629 return method(this, e, options); 30630 } 30631 30632 return []; 30633 }, 30634 30635 getDatasetAtEvent: function(e) { 30636 return Interaction.modes.dataset(this, e, {intersect: true}); 30637 }, 30638 30639 getDatasetMeta: function(datasetIndex) { 30640 var me = this; 30641 var dataset = me.data.datasets[datasetIndex]; 30642 if (!dataset._meta) { 30643 dataset._meta = {}; 30644 } 30645 30646 var meta = dataset._meta[me.id]; 30647 if (!meta) { 30648 meta = dataset._meta[me.id] = { 30649 type: null, 30650 data: [], 30651 dataset: null, 30652 controller: null, 30653 hidden: null, // See isDatasetVisible() comment 30654 xAxisID: null, 30655 yAxisID: null 30656 }; 30657 } 30658 30659 return meta; 30660 }, 30661 30662 getVisibleDatasetCount: function() { 30663 var count = 0; 30664 for (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) { 30665 if (this.isDatasetVisible(i)) { 30666 count++; 30667 } 30668 } 30669 return count; 30670 }, 30671 30672 isDatasetVisible: function(datasetIndex) { 30673 var meta = this.getDatasetMeta(datasetIndex); 30674 30675 // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false, 30676 // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned. 30677 return typeof meta.hidden === 'boolean' ? !meta.hidden : !this.data.datasets[datasetIndex].hidden; 30678 }, 30679 30680 generateLegend: function() { 30681 return this.options.legendCallback(this); 30682 }, 30683 30684 /** 30685 * @private 30686 */ 30687 destroyDatasetMeta: function(datasetIndex) { 30688 var id = this.id; 30689 var dataset = this.data.datasets[datasetIndex]; 30690 var meta = dataset._meta && dataset._meta[id]; 30691 30692 if (meta) { 30693 meta.controller.destroy(); 30694 delete dataset._meta[id]; 30695 } 30696 }, 30697 30698 destroy: function() { 30699 var me = this; 30700 var canvas = me.canvas; 30701 var i, ilen; 30702 30703 me.stop(); 30704 30705 // dataset controllers need to cleanup associated data 30706 for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) { 30707 me.destroyDatasetMeta(i); 30708 } 30709 30710 if (canvas) { 30711 me.unbindEvents(); 30712 helpers.canvas.clear(me); 30713 platform.releaseContext(me.ctx); 30714 me.canvas = null; 30715 me.ctx = null; 30716 } 30717 30718 plugins.notify(me, 'destroy'); 30719 30720 delete Chart.instances[me.id]; 30721 }, 30722 30723 toBase64Image: function() { 30724 return this.canvas.toDataURL.apply(this.canvas, arguments); 30725 }, 30726 30727 initToolTip: function() { 30728 var me = this; 30729 me.tooltip = new Chart.Tooltip({ 30730 _chart: me, 30731 _chartInstance: me, // deprecated, backward compatibility 30732 _data: me.data, 30733 _options: me.options.tooltips 30734 }, me); 30735 }, 30736 30737 /** 30738 * @private 30739 */ 30740 bindEvents: function() { 30741 var me = this; 30742 var listeners = me._listeners = {}; 30743 var listener = function() { 30744 me.eventHandler.apply(me, arguments); 30745 }; 30746 30747 helpers.each(me.options.events, function(type) { 30748 platform.addEventListener(me, type, listener); 30749 listeners[type] = listener; 30750 }); 30751 30752 // Elements used to detect size change should not be injected for non responsive charts. 30753 // See https://github.com/chartjs/Chart.js/issues/2210 30754 if (me.options.responsive) { 30755 listener = function() { 30756 me.resize(); 30757 }; 30758 30759 platform.addEventListener(me, 'resize', listener); 30760 listeners.resize = listener; 30761 } 30762 }, 30763 30764 /** 30765 * @private 30766 */ 30767 unbindEvents: function() { 30768 var me = this; 30769 var listeners = me._listeners; 30770 if (!listeners) { 30771 return; 30772 } 30773 30774 delete me._listeners; 30775 helpers.each(listeners, function(listener, type) { 30776 platform.removeEventListener(me, type, listener); 30777 }); 30778 }, 30779 30780 updateHoverStyle: function(elements, mode, enabled) { 30781 var method = enabled ? 'setHoverStyle' : 'removeHoverStyle'; 30782 var element, i, ilen; 30783 30784 for (i = 0, ilen = elements.length; i < ilen; ++i) { 30785 element = elements[i]; 30786 if (element) { 30787 this.getDatasetMeta(element._datasetIndex).controller[method](element); 30788 } 30789 } 30790 }, 30791 30792 /** 30793 * @private 30794 */ 30795 eventHandler: function(e) { 30796 var me = this; 30797 var tooltip = me.tooltip; 30798 30799 if (plugins.notify(me, 'beforeEvent', [e]) === false) { 30800 return; 30801 } 30802 30803 // Buffer any update calls so that renders do not occur 30804 me._bufferedRender = true; 30805 me._bufferedRequest = null; 30806 30807 var changed = me.handleEvent(e); 30808 // for smooth tooltip animations issue #4989 30809 // the tooltip should be the source of change 30810 // Animation check workaround: 30811 // tooltip._start will be null when tooltip isn't animating 30812 if (tooltip) { 30813 changed = tooltip._start 30814 ? tooltip.handleEvent(e) 30815 : changed | tooltip.handleEvent(e); 30816 } 30817 30818 plugins.notify(me, 'afterEvent', [e]); 30819 30820 var bufferedRequest = me._bufferedRequest; 30821 if (bufferedRequest) { 30822 // If we have an update that was triggered, we need to do a normal render 30823 me.render(bufferedRequest); 30824 } else if (changed && !me.animating) { 30825 // If entering, leaving, or changing elements, animate the change via pivot 30826 me.stop(); 30827 30828 // We only need to render at this point. Updating will cause scales to be 30829 // recomputed generating flicker & using more memory than necessary. 30830 me.render(me.options.hover.animationDuration, true); 30831 } 30832 30833 me._bufferedRender = false; 30834 me._bufferedRequest = null; 30835 30836 return me; 30837 }, 30838 30839 /** 30840 * Handle an event 30841 * @private 30842 * @param {IEvent} event the event to handle 30843 * @return {Boolean} true if the chart needs to re-render 30844 */ 30845 handleEvent: function(e) { 30846 var me = this; 30847 var options = me.options || {}; 30848 var hoverOptions = options.hover; 30849 var changed = false; 30850 30851 me.lastActive = me.lastActive || []; 30852 30853 // Find Active Elements for hover and tooltips 30854 if (e.type === 'mouseout') { 30855 me.active = []; 30856 } else { 30857 me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions); 30858 } 30859 30860 // Invoke onHover hook 30861 // Need to call with native event here to not break backwards compatibility 30862 helpers.callback(options.onHover || options.hover.onHover, [e.native, me.active], me); 30863 30864 if (e.type === 'mouseup' || e.type === 'click') { 30865 if (options.onClick) { 30866 // Use e.native here for backwards compatibility 30867 options.onClick.call(me, e.native, me.active); 30868 } 30869 } 30870 30871 // Remove styling for last active (even if it may still be active) 30872 if (me.lastActive.length) { 30873 me.updateHoverStyle(me.lastActive, hoverOptions.mode, false); 30874 } 30875 30876 // Built in hover styling 30877 if (me.active.length && hoverOptions.mode) { 30878 me.updateHoverStyle(me.active, hoverOptions.mode, true); 30879 } 30880 30881 changed = !helpers.arrayEquals(me.active, me.lastActive); 30882 30883 // Remember Last Actives 30884 me.lastActive = me.active; 30885 30886 return changed; 30887 } 30888 }); 30889 30890 /** 30891 * Provided for backward compatibility, use Chart instead. 30892 * @class Chart.Controller 30893 * @deprecated since version 2.6.0 30894 * @todo remove at version 3 30895 * @private 30896 */ 30897 Chart.Controller = Chart; 30898}; 30899 30900},{"25":25,"28":28,"30":30,"31":31,"45":45,"48":48}],24:[function(require,module,exports){ 30901'use strict'; 30902 30903var helpers = require(45); 30904 30905module.exports = function(Chart) { 30906 30907 var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift']; 30908 30909 /** 30910 * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice', 30911 * 'unshift') and notify the listener AFTER the array has been altered. Listeners are 30912 * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments. 30913 */ 30914 function listenArrayEvents(array, listener) { 30915 if (array._chartjs) { 30916 array._chartjs.listeners.push(listener); 30917 return; 30918 } 30919 30920 Object.defineProperty(array, '_chartjs', { 30921 configurable: true, 30922 enumerable: false, 30923 value: { 30924 listeners: [listener] 30925 } 30926 }); 30927 30928 arrayEvents.forEach(function(key) { 30929 var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1); 30930 var base = array[key]; 30931 30932 Object.defineProperty(array, key, { 30933 configurable: true, 30934 enumerable: false, 30935 value: function() { 30936 var args = Array.prototype.slice.call(arguments); 30937 var res = base.apply(this, args); 30938 30939 helpers.each(array._chartjs.listeners, function(object) { 30940 if (typeof object[method] === 'function') { 30941 object[method].apply(object, args); 30942 } 30943 }); 30944 30945 return res; 30946 } 30947 }); 30948 }); 30949 } 30950 30951 /** 30952 * Removes the given array event listener and cleanup extra attached properties (such as 30953 * the _chartjs stub and overridden methods) if array doesn't have any more listeners. 30954 */ 30955 function unlistenArrayEvents(array, listener) { 30956 var stub = array._chartjs; 30957 if (!stub) { 30958 return; 30959 } 30960 30961 var listeners = stub.listeners; 30962 var index = listeners.indexOf(listener); 30963 if (index !== -1) { 30964 listeners.splice(index, 1); 30965 } 30966 30967 if (listeners.length > 0) { 30968 return; 30969 } 30970 30971 arrayEvents.forEach(function(key) { 30972 delete array[key]; 30973 }); 30974 30975 delete array._chartjs; 30976 } 30977 30978 // Base class for all dataset controllers (line, bar, etc) 30979 Chart.DatasetController = function(chart, datasetIndex) { 30980 this.initialize(chart, datasetIndex); 30981 }; 30982 30983 helpers.extend(Chart.DatasetController.prototype, { 30984 30985 /** 30986 * Element type used to generate a meta dataset (e.g. Chart.element.Line). 30987 * @type {Chart.core.element} 30988 */ 30989 datasetElementType: null, 30990 30991 /** 30992 * Element type used to generate a meta data (e.g. Chart.element.Point). 30993 * @type {Chart.core.element} 30994 */ 30995 dataElementType: null, 30996 30997 initialize: function(chart, datasetIndex) { 30998 var me = this; 30999 me.chart = chart; 31000 me.index = datasetIndex; 31001 me.linkScales(); 31002 me.addElements(); 31003 }, 31004 31005 updateIndex: function(datasetIndex) { 31006 this.index = datasetIndex; 31007 }, 31008 31009 linkScales: function() { 31010 var me = this; 31011 var meta = me.getMeta(); 31012 var dataset = me.getDataset(); 31013 31014 if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) { 31015 meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id; 31016 } 31017 if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) { 31018 meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id; 31019 } 31020 }, 31021 31022 getDataset: function() { 31023 return this.chart.data.datasets[this.index]; 31024 }, 31025 31026 getMeta: function() { 31027 return this.chart.getDatasetMeta(this.index); 31028 }, 31029 31030 getScaleForId: function(scaleID) { 31031 return this.chart.scales[scaleID]; 31032 }, 31033 31034 reset: function() { 31035 this.update(true); 31036 }, 31037 31038 /** 31039 * @private 31040 */ 31041 destroy: function() { 31042 if (this._data) { 31043 unlistenArrayEvents(this._data, this); 31044 } 31045 }, 31046 31047 createMetaDataset: function() { 31048 var me = this; 31049 var type = me.datasetElementType; 31050 return type && new type({ 31051 _chart: me.chart, 31052 _datasetIndex: me.index 31053 }); 31054 }, 31055 31056 createMetaData: function(index) { 31057 var me = this; 31058 var type = me.dataElementType; 31059 return type && new type({ 31060 _chart: me.chart, 31061 _datasetIndex: me.index, 31062 _index: index 31063 }); 31064 }, 31065 31066 addElements: function() { 31067 var me = this; 31068 var meta = me.getMeta(); 31069 var data = me.getDataset().data || []; 31070 var metaData = meta.data; 31071 var i, ilen; 31072 31073 for (i = 0, ilen = data.length; i < ilen; ++i) { 31074 metaData[i] = metaData[i] || me.createMetaData(i); 31075 } 31076 31077 meta.dataset = meta.dataset || me.createMetaDataset(); 31078 }, 31079 31080 addElementAndReset: function(index) { 31081 var element = this.createMetaData(index); 31082 this.getMeta().data.splice(index, 0, element); 31083 this.updateElement(element, index, true); 31084 }, 31085 31086 buildOrUpdateElements: function() { 31087 var me = this; 31088 var dataset = me.getDataset(); 31089 var data = dataset.data || (dataset.data = []); 31090 31091 // In order to correctly handle data addition/deletion animation (an thus simulate 31092 // real-time charts), we need to monitor these data modifications and synchronize 31093 // the internal meta data accordingly. 31094 if (me._data !== data) { 31095 if (me._data) { 31096 // This case happens when the user replaced the data array instance. 31097 unlistenArrayEvents(me._data, me); 31098 } 31099 31100 listenArrayEvents(data, me); 31101 me._data = data; 31102 } 31103 31104 // Re-sync meta data in case the user replaced the data array or if we missed 31105 // any updates and so make sure that we handle number of datapoints changing. 31106 me.resyncElements(); 31107 }, 31108 31109 update: helpers.noop, 31110 31111 transition: function(easingValue) { 31112 var meta = this.getMeta(); 31113 var elements = meta.data || []; 31114 var ilen = elements.length; 31115 var i = 0; 31116 31117 for (; i < ilen; ++i) { 31118 elements[i].transition(easingValue); 31119 } 31120 31121 if (meta.dataset) { 31122 meta.dataset.transition(easingValue); 31123 } 31124 }, 31125 31126 draw: function() { 31127 var meta = this.getMeta(); 31128 var elements = meta.data || []; 31129 var ilen = elements.length; 31130 var i = 0; 31131 31132 if (meta.dataset) { 31133 meta.dataset.draw(); 31134 } 31135 31136 for (; i < ilen; ++i) { 31137 elements[i].draw(); 31138 } 31139 }, 31140 31141 removeHoverStyle: function(element, elementOpts) { 31142 var dataset = this.chart.data.datasets[element._datasetIndex]; 31143 var index = element._index; 31144 var custom = element.custom || {}; 31145 var valueOrDefault = helpers.valueAtIndexOrDefault; 31146 var model = element._model; 31147 31148 model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor); 31149 model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor); 31150 model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth); 31151 }, 31152 31153 setHoverStyle: function(element) { 31154 var dataset = this.chart.data.datasets[element._datasetIndex]; 31155 var index = element._index; 31156 var custom = element.custom || {}; 31157 var valueOrDefault = helpers.valueAtIndexOrDefault; 31158 var getHoverColor = helpers.getHoverColor; 31159 var model = element._model; 31160 31161 model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor)); 31162 model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor)); 31163 model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); 31164 }, 31165 31166 /** 31167 * @private 31168 */ 31169 resyncElements: function() { 31170 var me = this; 31171 var meta = me.getMeta(); 31172 var data = me.getDataset().data; 31173 var numMeta = meta.data.length; 31174 var numData = data.length; 31175 31176 if (numData < numMeta) { 31177 meta.data.splice(numData, numMeta - numData); 31178 } else if (numData > numMeta) { 31179 me.insertElements(numMeta, numData - numMeta); 31180 } 31181 }, 31182 31183 /** 31184 * @private 31185 */ 31186 insertElements: function(start, count) { 31187 for (var i = 0; i < count; ++i) { 31188 this.addElementAndReset(start + i); 31189 } 31190 }, 31191 31192 /** 31193 * @private 31194 */ 31195 onDataPush: function() { 31196 this.insertElements(this.getDataset().data.length - 1, arguments.length); 31197 }, 31198 31199 /** 31200 * @private 31201 */ 31202 onDataPop: function() { 31203 this.getMeta().data.pop(); 31204 }, 31205 31206 /** 31207 * @private 31208 */ 31209 onDataShift: function() { 31210 this.getMeta().data.shift(); 31211 }, 31212 31213 /** 31214 * @private 31215 */ 31216 onDataSplice: function(start, count) { 31217 this.getMeta().data.splice(start, count); 31218 this.insertElements(start, arguments.length - 2); 31219 }, 31220 31221 /** 31222 * @private 31223 */ 31224 onDataUnshift: function() { 31225 this.insertElements(0, arguments.length); 31226 } 31227 }); 31228 31229 Chart.DatasetController.extend = helpers.inherits; 31230}; 31231 31232},{"45":45}],25:[function(require,module,exports){ 31233'use strict'; 31234 31235var helpers = require(45); 31236 31237module.exports = { 31238 /** 31239 * @private 31240 */ 31241 _set: function(scope, values) { 31242 return helpers.merge(this[scope] || (this[scope] = {}), values); 31243 } 31244}; 31245 31246},{"45":45}],26:[function(require,module,exports){ 31247'use strict'; 31248 31249var color = require(2); 31250var helpers = require(45); 31251 31252function interpolate(start, view, model, ease) { 31253 var keys = Object.keys(model); 31254 var i, ilen, key, actual, origin, target, type, c0, c1; 31255 31256 for (i = 0, ilen = keys.length; i < ilen; ++i) { 31257 key = keys[i]; 31258 31259 target = model[key]; 31260 31261 // if a value is added to the model after pivot() has been called, the view 31262 // doesn't contain it, so let's initialize the view to the target value. 31263 if (!view.hasOwnProperty(key)) { 31264 view[key] = target; 31265 } 31266 31267 actual = view[key]; 31268 31269 if (actual === target || key[0] === '_') { 31270 continue; 31271 } 31272 31273 if (!start.hasOwnProperty(key)) { 31274 start[key] = actual; 31275 } 31276 31277 origin = start[key]; 31278 31279 type = typeof target; 31280 31281 if (type === typeof origin) { 31282 if (type === 'string') { 31283 c0 = color(origin); 31284 if (c0.valid) { 31285 c1 = color(target); 31286 if (c1.valid) { 31287 view[key] = c1.mix(c0, ease).rgbString(); 31288 continue; 31289 } 31290 } 31291 } else if (type === 'number' && isFinite(origin) && isFinite(target)) { 31292 view[key] = origin + (target - origin) * ease; 31293 continue; 31294 } 31295 } 31296 31297 view[key] = target; 31298 } 31299} 31300 31301var Element = function(configuration) { 31302 helpers.extend(this, configuration); 31303 this.initialize.apply(this, arguments); 31304}; 31305 31306helpers.extend(Element.prototype, { 31307 31308 initialize: function() { 31309 this.hidden = false; 31310 }, 31311 31312 pivot: function() { 31313 var me = this; 31314 if (!me._view) { 31315 me._view = helpers.clone(me._model); 31316 } 31317 me._start = {}; 31318 return me; 31319 }, 31320 31321 transition: function(ease) { 31322 var me = this; 31323 var model = me._model; 31324 var start = me._start; 31325 var view = me._view; 31326 31327 // No animation -> No Transition 31328 if (!model || ease === 1) { 31329 me._view = model; 31330 me._start = null; 31331 return me; 31332 } 31333 31334 if (!view) { 31335 view = me._view = {}; 31336 } 31337 31338 if (!start) { 31339 start = me._start = {}; 31340 } 31341 31342 interpolate(start, view, model, ease); 31343 31344 return me; 31345 }, 31346 31347 tooltipPosition: function() { 31348 return { 31349 x: this._model.x, 31350 y: this._model.y 31351 }; 31352 }, 31353 31354 hasValue: function() { 31355 return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y); 31356 } 31357}); 31358 31359Element.extend = helpers.inherits; 31360 31361module.exports = Element; 31362 31363},{"2":2,"45":45}],27:[function(require,module,exports){ 31364/* global window: false */ 31365/* global document: false */ 31366'use strict'; 31367 31368var color = require(2); 31369var defaults = require(25); 31370var helpers = require(45); 31371 31372module.exports = function(Chart) { 31373 31374 // -- Basic js utility methods 31375 31376 helpers.configMerge = function(/* objects ... */) { 31377 return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), { 31378 merger: function(key, target, source, options) { 31379 var tval = target[key] || {}; 31380 var sval = source[key]; 31381 31382 if (key === 'scales') { 31383 // scale config merging is complex. Add our own function here for that 31384 target[key] = helpers.scaleMerge(tval, sval); 31385 } else if (key === 'scale') { 31386 // used in polar area & radar charts since there is only one scale 31387 target[key] = helpers.merge(tval, [Chart.scaleService.getScaleDefaults(sval.type), sval]); 31388 } else { 31389 helpers._merger(key, target, source, options); 31390 } 31391 } 31392 }); 31393 }; 31394 31395 helpers.scaleMerge = function(/* objects ... */) { 31396 return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), { 31397 merger: function(key, target, source, options) { 31398 if (key === 'xAxes' || key === 'yAxes') { 31399 var slen = source[key].length; 31400 var i, type, scale; 31401 31402 if (!target[key]) { 31403 target[key] = []; 31404 } 31405 31406 for (i = 0; i < slen; ++i) { 31407 scale = source[key][i]; 31408 type = helpers.valueOrDefault(scale.type, key === 'xAxes' ? 'category' : 'linear'); 31409 31410 if (i >= target[key].length) { 31411 target[key].push({}); 31412 } 31413 31414 if (!target[key][i].type || (scale.type && scale.type !== target[key][i].type)) { 31415 // new/untyped scale or type changed: let's apply the new defaults 31416 // then merge source scale to correctly overwrite the defaults. 31417 helpers.merge(target[key][i], [Chart.scaleService.getScaleDefaults(type), scale]); 31418 } else { 31419 // scales type are the same 31420 helpers.merge(target[key][i], scale); 31421 } 31422 } 31423 } else { 31424 helpers._merger(key, target, source, options); 31425 } 31426 } 31427 }); 31428 }; 31429 31430 helpers.where = function(collection, filterCallback) { 31431 if (helpers.isArray(collection) && Array.prototype.filter) { 31432 return collection.filter(filterCallback); 31433 } 31434 var filtered = []; 31435 31436 helpers.each(collection, function(item) { 31437 if (filterCallback(item)) { 31438 filtered.push(item); 31439 } 31440 }); 31441 31442 return filtered; 31443 }; 31444 helpers.findIndex = Array.prototype.findIndex ? 31445 function(array, callback, scope) { 31446 return array.findIndex(callback, scope); 31447 } : 31448 function(array, callback, scope) { 31449 scope = scope === undefined ? array : scope; 31450 for (var i = 0, ilen = array.length; i < ilen; ++i) { 31451 if (callback.call(scope, array[i], i, array)) { 31452 return i; 31453 } 31454 } 31455 return -1; 31456 }; 31457 helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) { 31458 // Default to start of the array 31459 if (helpers.isNullOrUndef(startIndex)) { 31460 startIndex = -1; 31461 } 31462 for (var i = startIndex + 1; i < arrayToSearch.length; i++) { 31463 var currentItem = arrayToSearch[i]; 31464 if (filterCallback(currentItem)) { 31465 return currentItem; 31466 } 31467 } 31468 }; 31469 helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) { 31470 // Default to end of the array 31471 if (helpers.isNullOrUndef(startIndex)) { 31472 startIndex = arrayToSearch.length; 31473 } 31474 for (var i = startIndex - 1; i >= 0; i--) { 31475 var currentItem = arrayToSearch[i]; 31476 if (filterCallback(currentItem)) { 31477 return currentItem; 31478 } 31479 } 31480 }; 31481 31482 // -- Math methods 31483 helpers.isNumber = function(n) { 31484 return !isNaN(parseFloat(n)) && isFinite(n); 31485 }; 31486 helpers.almostEquals = function(x, y, epsilon) { 31487 return Math.abs(x - y) < epsilon; 31488 }; 31489 helpers.almostWhole = function(x, epsilon) { 31490 var rounded = Math.round(x); 31491 return (((rounded - epsilon) < x) && ((rounded + epsilon) > x)); 31492 }; 31493 helpers.max = function(array) { 31494 return array.reduce(function(max, value) { 31495 if (!isNaN(value)) { 31496 return Math.max(max, value); 31497 } 31498 return max; 31499 }, Number.NEGATIVE_INFINITY); 31500 }; 31501 helpers.min = function(array) { 31502 return array.reduce(function(min, value) { 31503 if (!isNaN(value)) { 31504 return Math.min(min, value); 31505 } 31506 return min; 31507 }, Number.POSITIVE_INFINITY); 31508 }; 31509 helpers.sign = Math.sign ? 31510 function(x) { 31511 return Math.sign(x); 31512 } : 31513 function(x) { 31514 x = +x; // convert to a number 31515 if (x === 0 || isNaN(x)) { 31516 return x; 31517 } 31518 return x > 0 ? 1 : -1; 31519 }; 31520 helpers.log10 = Math.log10 ? 31521 function(x) { 31522 return Math.log10(x); 31523 } : 31524 function(x) { 31525 var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10. 31526 // Check for whole powers of 10, 31527 // which due to floating point rounding error should be corrected. 31528 var powerOf10 = Math.round(exponent); 31529 var isPowerOf10 = x === Math.pow(10, powerOf10); 31530 31531 return isPowerOf10 ? powerOf10 : exponent; 31532 }; 31533 helpers.toRadians = function(degrees) { 31534 return degrees * (Math.PI / 180); 31535 }; 31536 helpers.toDegrees = function(radians) { 31537 return radians * (180 / Math.PI); 31538 }; 31539 // Gets the angle from vertical upright to the point about a centre. 31540 helpers.getAngleFromPoint = function(centrePoint, anglePoint) { 31541 var distanceFromXCenter = anglePoint.x - centrePoint.x; 31542 var distanceFromYCenter = anglePoint.y - centrePoint.y; 31543 var radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); 31544 31545 var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter); 31546 31547 if (angle < (-0.5 * Math.PI)) { 31548 angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2] 31549 } 31550 31551 return { 31552 angle: angle, 31553 distance: radialDistanceFromCenter 31554 }; 31555 }; 31556 helpers.distanceBetweenPoints = function(pt1, pt2) { 31557 return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2)); 31558 }; 31559 helpers.aliasPixel = function(pixelWidth) { 31560 return (pixelWidth % 2 === 0) ? 0 : 0.5; 31561 }; 31562 helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) { 31563 // Props to Rob Spencer at scaled innovation for his post on splining between points 31564 // http://scaledinnovation.com/analytics/splines/aboutSplines.html 31565 31566 // This function must also respect "skipped" points 31567 31568 var previous = firstPoint.skip ? middlePoint : firstPoint; 31569 var current = middlePoint; 31570 var next = afterPoint.skip ? middlePoint : afterPoint; 31571 31572 var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2)); 31573 var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2)); 31574 31575 var s01 = d01 / (d01 + d12); 31576 var s12 = d12 / (d01 + d12); 31577 31578 // If all points are the same, s01 & s02 will be inf 31579 s01 = isNaN(s01) ? 0 : s01; 31580 s12 = isNaN(s12) ? 0 : s12; 31581 31582 var fa = t * s01; // scaling factor for triangle Ta 31583 var fb = t * s12; 31584 31585 return { 31586 previous: { 31587 x: current.x - fa * (next.x - previous.x), 31588 y: current.y - fa * (next.y - previous.y) 31589 }, 31590 next: { 31591 x: current.x + fb * (next.x - previous.x), 31592 y: current.y + fb * (next.y - previous.y) 31593 } 31594 }; 31595 }; 31596 helpers.EPSILON = Number.EPSILON || 1e-14; 31597 helpers.splineCurveMonotone = function(points) { 31598 // This function calculates Bézier control points in a similar way than |splineCurve|, 31599 // but preserves monotonicity of the provided data and ensures no local extremums are added 31600 // between the dataset discrete points due to the interpolation. 31601 // See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation 31602 31603 var pointsWithTangents = (points || []).map(function(point) { 31604 return { 31605 model: point._model, 31606 deltaK: 0, 31607 mK: 0 31608 }; 31609 }); 31610 31611 // Calculate slopes (deltaK) and initialize tangents (mK) 31612 var pointsLen = pointsWithTangents.length; 31613 var i, pointBefore, pointCurrent, pointAfter; 31614 for (i = 0; i < pointsLen; ++i) { 31615 pointCurrent = pointsWithTangents[i]; 31616 if (pointCurrent.model.skip) { 31617 continue; 31618 } 31619 31620 pointBefore = i > 0 ? pointsWithTangents[i - 1] : null; 31621 pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null; 31622 if (pointAfter && !pointAfter.model.skip) { 31623 var slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x); 31624 31625 // In the case of two points that appear at the same x pixel, slopeDeltaX is 0 31626 pointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0; 31627 } 31628 31629 if (!pointBefore || pointBefore.model.skip) { 31630 pointCurrent.mK = pointCurrent.deltaK; 31631 } else if (!pointAfter || pointAfter.model.skip) { 31632 pointCurrent.mK = pointBefore.deltaK; 31633 } else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) { 31634 pointCurrent.mK = 0; 31635 } else { 31636 pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2; 31637 } 31638 } 31639 31640 // Adjust tangents to ensure monotonic properties 31641 var alphaK, betaK, tauK, squaredMagnitude; 31642 for (i = 0; i < pointsLen - 1; ++i) { 31643 pointCurrent = pointsWithTangents[i]; 31644 pointAfter = pointsWithTangents[i + 1]; 31645 if (pointCurrent.model.skip || pointAfter.model.skip) { 31646 continue; 31647 } 31648 31649 if (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) { 31650 pointCurrent.mK = pointAfter.mK = 0; 31651 continue; 31652 } 31653 31654 alphaK = pointCurrent.mK / pointCurrent.deltaK; 31655 betaK = pointAfter.mK / pointCurrent.deltaK; 31656 squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2); 31657 if (squaredMagnitude <= 9) { 31658 continue; 31659 } 31660 31661 tauK = 3 / Math.sqrt(squaredMagnitude); 31662 pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK; 31663 pointAfter.mK = betaK * tauK * pointCurrent.deltaK; 31664 } 31665 31666 // Compute control points 31667 var deltaX; 31668 for (i = 0; i < pointsLen; ++i) { 31669 pointCurrent = pointsWithTangents[i]; 31670 if (pointCurrent.model.skip) { 31671 continue; 31672 } 31673 31674 pointBefore = i > 0 ? pointsWithTangents[i - 1] : null; 31675 pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null; 31676 if (pointBefore && !pointBefore.model.skip) { 31677 deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3; 31678 pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX; 31679 pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK; 31680 } 31681 if (pointAfter && !pointAfter.model.skip) { 31682 deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3; 31683 pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX; 31684 pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK; 31685 } 31686 } 31687 }; 31688 helpers.nextItem = function(collection, index, loop) { 31689 if (loop) { 31690 return index >= collection.length - 1 ? collection[0] : collection[index + 1]; 31691 } 31692 return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1]; 31693 }; 31694 helpers.previousItem = function(collection, index, loop) { 31695 if (loop) { 31696 return index <= 0 ? collection[collection.length - 1] : collection[index - 1]; 31697 } 31698 return index <= 0 ? collection[0] : collection[index - 1]; 31699 }; 31700 // Implementation of the nice number algorithm used in determining where axis labels will go 31701 helpers.niceNum = function(range, round) { 31702 var exponent = Math.floor(helpers.log10(range)); 31703 var fraction = range / Math.pow(10, exponent); 31704 var niceFraction; 31705 31706 if (round) { 31707 if (fraction < 1.5) { 31708 niceFraction = 1; 31709 } else if (fraction < 3) { 31710 niceFraction = 2; 31711 } else if (fraction < 7) { 31712 niceFraction = 5; 31713 } else { 31714 niceFraction = 10; 31715 } 31716 } else if (fraction <= 1.0) { 31717 niceFraction = 1; 31718 } else if (fraction <= 2) { 31719 niceFraction = 2; 31720 } else if (fraction <= 5) { 31721 niceFraction = 5; 31722 } else { 31723 niceFraction = 10; 31724 } 31725 31726 return niceFraction * Math.pow(10, exponent); 31727 }; 31728 // Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ 31729 helpers.requestAnimFrame = (function() { 31730 if (typeof window === 'undefined') { 31731 return function(callback) { 31732 callback(); 31733 }; 31734 } 31735 return window.requestAnimationFrame || 31736 window.webkitRequestAnimationFrame || 31737 window.mozRequestAnimationFrame || 31738 window.oRequestAnimationFrame || 31739 window.msRequestAnimationFrame || 31740 function(callback) { 31741 return window.setTimeout(callback, 1000 / 60); 31742 }; 31743 }()); 31744 // -- DOM methods 31745 helpers.getRelativePosition = function(evt, chart) { 31746 var mouseX, mouseY; 31747 var e = evt.originalEvent || evt; 31748 var canvas = evt.currentTarget || evt.srcElement; 31749 var boundingRect = canvas.getBoundingClientRect(); 31750 31751 var touches = e.touches; 31752 if (touches && touches.length > 0) { 31753 mouseX = touches[0].clientX; 31754 mouseY = touches[0].clientY; 31755 31756 } else { 31757 mouseX = e.clientX; 31758 mouseY = e.clientY; 31759 } 31760 31761 // Scale mouse coordinates into canvas coordinates 31762 // by following the pattern laid out by 'jerryj' in the comments of 31763 // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/ 31764 var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left')); 31765 var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top')); 31766 var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right')); 31767 var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom')); 31768 var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight; 31769 var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom; 31770 31771 // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However 31772 // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here 31773 mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio); 31774 mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio); 31775 31776 return { 31777 x: mouseX, 31778 y: mouseY 31779 }; 31780 31781 }; 31782 31783 // Private helper function to convert max-width/max-height values that may be percentages into a number 31784 function parseMaxStyle(styleValue, node, parentProperty) { 31785 var valueInPixels; 31786 if (typeof styleValue === 'string') { 31787 valueInPixels = parseInt(styleValue, 10); 31788 31789 if (styleValue.indexOf('%') !== -1) { 31790 // percentage * size in dimension 31791 valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty]; 31792 } 31793 } else { 31794 valueInPixels = styleValue; 31795 } 31796 31797 return valueInPixels; 31798 } 31799 31800 /** 31801 * Returns if the given value contains an effective constraint. 31802 * @private 31803 */ 31804 function isConstrainedValue(value) { 31805 return value !== undefined && value !== null && value !== 'none'; 31806 } 31807 31808 // Private helper to get a constraint dimension 31809 // @param domNode : the node to check the constraint on 31810 // @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight) 31811 // @param percentageProperty : property of parent to use when calculating width as a percentage 31812 // @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser 31813 function getConstraintDimension(domNode, maxStyle, percentageProperty) { 31814 var view = document.defaultView; 31815 var parentNode = domNode.parentNode; 31816 var constrainedNode = view.getComputedStyle(domNode)[maxStyle]; 31817 var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle]; 31818 var hasCNode = isConstrainedValue(constrainedNode); 31819 var hasCContainer = isConstrainedValue(constrainedContainer); 31820 var infinity = Number.POSITIVE_INFINITY; 31821 31822 if (hasCNode || hasCContainer) { 31823 return Math.min( 31824 hasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity, 31825 hasCContainer ? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity); 31826 } 31827 31828 return 'none'; 31829 } 31830 // returns Number or undefined if no constraint 31831 helpers.getConstraintWidth = function(domNode) { 31832 return getConstraintDimension(domNode, 'max-width', 'clientWidth'); 31833 }; 31834 // returns Number or undefined if no constraint 31835 helpers.getConstraintHeight = function(domNode) { 31836 return getConstraintDimension(domNode, 'max-height', 'clientHeight'); 31837 }; 31838 helpers.getMaximumWidth = function(domNode) { 31839 var container = domNode.parentNode; 31840 if (!container) { 31841 return domNode.clientWidth; 31842 } 31843 31844 var paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10); 31845 var paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10); 31846 var w = container.clientWidth - paddingLeft - paddingRight; 31847 var cw = helpers.getConstraintWidth(domNode); 31848 return isNaN(cw) ? w : Math.min(w, cw); 31849 }; 31850 helpers.getMaximumHeight = function(domNode) { 31851 var container = domNode.parentNode; 31852 if (!container) { 31853 return domNode.clientHeight; 31854 } 31855 31856 var paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10); 31857 var paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10); 31858 var h = container.clientHeight - paddingTop - paddingBottom; 31859 var ch = helpers.getConstraintHeight(domNode); 31860 return isNaN(ch) ? h : Math.min(h, ch); 31861 }; 31862 helpers.getStyle = function(el, property) { 31863 return el.currentStyle ? 31864 el.currentStyle[property] : 31865 document.defaultView.getComputedStyle(el, null).getPropertyValue(property); 31866 }; 31867 helpers.retinaScale = function(chart, forceRatio) { 31868 var pixelRatio = chart.currentDevicePixelRatio = forceRatio || window.devicePixelRatio || 1; 31869 if (pixelRatio === 1) { 31870 return; 31871 } 31872 31873 var canvas = chart.canvas; 31874 var height = chart.height; 31875 var width = chart.width; 31876 31877 canvas.height = height * pixelRatio; 31878 canvas.width = width * pixelRatio; 31879 chart.ctx.scale(pixelRatio, pixelRatio); 31880 31881 // If no style has been set on the canvas, the render size is used as display size, 31882 // making the chart visually bigger, so let's enforce it to the "correct" values. 31883 // See https://github.com/chartjs/Chart.js/issues/3575 31884 if (!canvas.style.height && !canvas.style.width) { 31885 canvas.style.height = height + 'px'; 31886 canvas.style.width = width + 'px'; 31887 } 31888 }; 31889 // -- Canvas methods 31890 helpers.fontString = function(pixelSize, fontStyle, fontFamily) { 31891 return fontStyle + ' ' + pixelSize + 'px ' + fontFamily; 31892 }; 31893 helpers.longestText = function(ctx, font, arrayOfThings, cache) { 31894 cache = cache || {}; 31895 var data = cache.data = cache.data || {}; 31896 var gc = cache.garbageCollect = cache.garbageCollect || []; 31897 31898 if (cache.font !== font) { 31899 data = cache.data = {}; 31900 gc = cache.garbageCollect = []; 31901 cache.font = font; 31902 } 31903 31904 ctx.font = font; 31905 var longest = 0; 31906 helpers.each(arrayOfThings, function(thing) { 31907 // Undefined strings and arrays should not be measured 31908 if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) { 31909 longest = helpers.measureText(ctx, data, gc, longest, thing); 31910 } else if (helpers.isArray(thing)) { 31911 // if it is an array lets measure each element 31912 // to do maybe simplify this function a bit so we can do this more recursively? 31913 helpers.each(thing, function(nestedThing) { 31914 // Undefined strings and arrays should not be measured 31915 if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) { 31916 longest = helpers.measureText(ctx, data, gc, longest, nestedThing); 31917 } 31918 }); 31919 } 31920 }); 31921 31922 var gcLen = gc.length / 2; 31923 if (gcLen > arrayOfThings.length) { 31924 for (var i = 0; i < gcLen; i++) { 31925 delete data[gc[i]]; 31926 } 31927 gc.splice(0, gcLen); 31928 } 31929 return longest; 31930 }; 31931 helpers.measureText = function(ctx, data, gc, longest, string) { 31932 var textWidth = data[string]; 31933 if (!textWidth) { 31934 textWidth = data[string] = ctx.measureText(string).width; 31935 gc.push(string); 31936 } 31937 if (textWidth > longest) { 31938 longest = textWidth; 31939 } 31940 return longest; 31941 }; 31942 helpers.numberOfLabelLines = function(arrayOfThings) { 31943 var numberOfLines = 1; 31944 helpers.each(arrayOfThings, function(thing) { 31945 if (helpers.isArray(thing)) { 31946 if (thing.length > numberOfLines) { 31947 numberOfLines = thing.length; 31948 } 31949 } 31950 }); 31951 return numberOfLines; 31952 }; 31953 31954 helpers.color = !color ? 31955 function(value) { 31956 console.error('Color.js not found!'); 31957 return value; 31958 } : 31959 function(value) { 31960 /* global CanvasGradient */ 31961 if (value instanceof CanvasGradient) { 31962 value = defaults.global.defaultColor; 31963 } 31964 31965 return color(value); 31966 }; 31967 31968 helpers.getHoverColor = function(colorValue) { 31969 /* global CanvasPattern */ 31970 return (colorValue instanceof CanvasPattern) ? 31971 colorValue : 31972 helpers.color(colorValue).saturate(0.5).darken(0.1).rgbString(); 31973 }; 31974}; 31975 31976},{"2":2,"25":25,"45":45}],28:[function(require,module,exports){ 31977'use strict'; 31978 31979var helpers = require(45); 31980 31981/** 31982 * Helper function to get relative position for an event 31983 * @param {Event|IEvent} event - The event to get the position for 31984 * @param {Chart} chart - The chart 31985 * @returns {Point} the event position 31986 */ 31987function getRelativePosition(e, chart) { 31988 if (e.native) { 31989 return { 31990 x: e.x, 31991 y: e.y 31992 }; 31993 } 31994 31995 return helpers.getRelativePosition(e, chart); 31996} 31997 31998/** 31999 * Helper function to traverse all of the visible elements in the chart 32000 * @param chart {chart} the chart 32001 * @param handler {Function} the callback to execute for each visible item 32002 */ 32003function parseVisibleItems(chart, handler) { 32004 var datasets = chart.data.datasets; 32005 var meta, i, j, ilen, jlen; 32006 32007 for (i = 0, ilen = datasets.length; i < ilen; ++i) { 32008 if (!chart.isDatasetVisible(i)) { 32009 continue; 32010 } 32011 32012 meta = chart.getDatasetMeta(i); 32013 for (j = 0, jlen = meta.data.length; j < jlen; ++j) { 32014 var element = meta.data[j]; 32015 if (!element._view.skip) { 32016 handler(element); 32017 } 32018 } 32019 } 32020} 32021 32022/** 32023 * Helper function to get the items that intersect the event position 32024 * @param items {ChartElement[]} elements to filter 32025 * @param position {Point} the point to be nearest to 32026 * @return {ChartElement[]} the nearest items 32027 */ 32028function getIntersectItems(chart, position) { 32029 var elements = []; 32030 32031 parseVisibleItems(chart, function(element) { 32032 if (element.inRange(position.x, position.y)) { 32033 elements.push(element); 32034 } 32035 }); 32036 32037 return elements; 32038} 32039 32040/** 32041 * Helper function to get the items nearest to the event position considering all visible items in teh chart 32042 * @param chart {Chart} the chart to look at elements from 32043 * @param position {Point} the point to be nearest to 32044 * @param intersect {Boolean} if true, only consider items that intersect the position 32045 * @param distanceMetric {Function} function to provide the distance between points 32046 * @return {ChartElement[]} the nearest items 32047 */ 32048function getNearestItems(chart, position, intersect, distanceMetric) { 32049 var minDistance = Number.POSITIVE_INFINITY; 32050 var nearestItems = []; 32051 32052 parseVisibleItems(chart, function(element) { 32053 if (intersect && !element.inRange(position.x, position.y)) { 32054 return; 32055 } 32056 32057 var center = element.getCenterPoint(); 32058 var distance = distanceMetric(position, center); 32059 32060 if (distance < minDistance) { 32061 nearestItems = [element]; 32062 minDistance = distance; 32063 } else if (distance === minDistance) { 32064 // Can have multiple items at the same distance in which case we sort by size 32065 nearestItems.push(element); 32066 } 32067 }); 32068 32069 return nearestItems; 32070} 32071 32072/** 32073 * Get a distance metric function for two points based on the 32074 * axis mode setting 32075 * @param {String} axis the axis mode. x|y|xy 32076 */ 32077function getDistanceMetricForAxis(axis) { 32078 var useX = axis.indexOf('x') !== -1; 32079 var useY = axis.indexOf('y') !== -1; 32080 32081 return function(pt1, pt2) { 32082 var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; 32083 var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; 32084 return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); 32085 }; 32086} 32087 32088function indexMode(chart, e, options) { 32089 var position = getRelativePosition(e, chart); 32090 // Default axis for index mode is 'x' to match old behaviour 32091 options.axis = options.axis || 'x'; 32092 var distanceMetric = getDistanceMetricForAxis(options.axis); 32093 var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); 32094 var elements = []; 32095 32096 if (!items.length) { 32097 return []; 32098 } 32099 32100 chart.data.datasets.forEach(function(dataset, datasetIndex) { 32101 if (chart.isDatasetVisible(datasetIndex)) { 32102 var meta = chart.getDatasetMeta(datasetIndex); 32103 var element = meta.data[items[0]._index]; 32104 32105 // don't count items that are skipped (null data) 32106 if (element && !element._view.skip) { 32107 elements.push(element); 32108 } 32109 } 32110 }); 32111 32112 return elements; 32113} 32114 32115/** 32116 * @interface IInteractionOptions 32117 */ 32118/** 32119 * If true, only consider items that intersect the point 32120 * @name IInterfaceOptions#boolean 32121 * @type Boolean 32122 */ 32123 32124/** 32125 * Contains interaction related functions 32126 * @namespace Chart.Interaction 32127 */ 32128module.exports = { 32129 // Helper function for different modes 32130 modes: { 32131 single: function(chart, e) { 32132 var position = getRelativePosition(e, chart); 32133 var elements = []; 32134 32135 parseVisibleItems(chart, function(element) { 32136 if (element.inRange(position.x, position.y)) { 32137 elements.push(element); 32138 return elements; 32139 } 32140 }); 32141 32142 return elements.slice(0, 1); 32143 }, 32144 32145 /** 32146 * @function Chart.Interaction.modes.label 32147 * @deprecated since version 2.4.0 32148 * @todo remove at version 3 32149 * @private 32150 */ 32151 label: indexMode, 32152 32153 /** 32154 * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something 32155 * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item 32156 * @function Chart.Interaction.modes.index 32157 * @since v2.4.0 32158 * @param chart {chart} the chart we are returning items from 32159 * @param e {Event} the event we are find things at 32160 * @param options {IInteractionOptions} options to use during interaction 32161 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned 32162 */ 32163 index: indexMode, 32164 32165 /** 32166 * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something 32167 * If the options.intersect is false, we find the nearest item and return the items in that dataset 32168 * @function Chart.Interaction.modes.dataset 32169 * @param chart {chart} the chart we are returning items from 32170 * @param e {Event} the event we are find things at 32171 * @param options {IInteractionOptions} options to use during interaction 32172 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned 32173 */ 32174 dataset: function(chart, e, options) { 32175 var position = getRelativePosition(e, chart); 32176 options.axis = options.axis || 'xy'; 32177 var distanceMetric = getDistanceMetricForAxis(options.axis); 32178 var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); 32179 32180 if (items.length > 0) { 32181 items = chart.getDatasetMeta(items[0]._datasetIndex).data; 32182 } 32183 32184 return items; 32185 }, 32186 32187 /** 32188 * @function Chart.Interaction.modes.x-axis 32189 * @deprecated since version 2.4.0. Use index mode and intersect == true 32190 * @todo remove at version 3 32191 * @private 32192 */ 32193 'x-axis': function(chart, e) { 32194 return indexMode(chart, e, {intersect: false}); 32195 }, 32196 32197 /** 32198 * Point mode returns all elements that hit test based on the event position 32199 * of the event 32200 * @function Chart.Interaction.modes.intersect 32201 * @param chart {chart} the chart we are returning items from 32202 * @param e {Event} the event we are find things at 32203 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned 32204 */ 32205 point: function(chart, e) { 32206 var position = getRelativePosition(e, chart); 32207 return getIntersectItems(chart, position); 32208 }, 32209 32210 /** 32211 * nearest mode returns the element closest to the point 32212 * @function Chart.Interaction.modes.intersect 32213 * @param chart {chart} the chart we are returning items from 32214 * @param e {Event} the event we are find things at 32215 * @param options {IInteractionOptions} options to use 32216 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned 32217 */
32218 nearest: function(chart, e, options) { 32219 var position = getRelativePosition(e, chart); 32220 options.axis = options.axis || 'xy'; 32221 var distanceMetric = getDistanceMetricForAxis(options.axis); 32222 var nearestItems = getNearestItems(chart, position, options.intersect, distanceMetric); 32223 32224 // We have multiple items at the same distance from the event. Now sort by smallest 32225 if (nearestItems.length > 1) { 32226 nearestItems.sort(function(a, b) { 32227 var sizeA = a.getArea(); 32228 var sizeB = b.getArea(); 32229 var ret = sizeA - sizeB; 32230 32231 if (ret === 0) { 32232 // if equal sort by dataset index 32233 ret = a._datasetIndex - b._datasetIndex; 32234 } 32235 32236 return ret; 32237 }); 32238 } 32239 32240 // Return only 1 item 32241 return nearestItems.slice(0, 1); 32242 }, 32243 32244 /** 32245 * x mode returns the elements that hit-test at the current x coordinate 32246 * @function Chart.Interaction.modes.x 32247 * @param chart {chart} the chart we are returning items from 32248 * @param e {Event} the event we are find things at 32249 * @param options {IInteractionOptions} options to use 32250 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned 32251 */ 32252 x: function(chart, e, options) { 32253 var position = getRelativePosition(e, chart); 32254 var items = []; 32255 var intersectsItem = false; 32256 32257 parseVisibleItems(chart, function(element) { 32258 if (element.inXRange(position.x)) { 32259 items.push(element); 32260 } 32261 32262 if (element.inRange(position.x, position.y)) { 32263 intersectsItem = true; 32264 } 32265 }); 32266 32267 // If we want to trigger on an intersect and we don't have any items 32268 // that intersect the position, return nothing 32269 if (options.intersect && !intersectsItem) { 32270 items = []; 32271 } 32272 return items; 32273 }, 32274 32275 /** 32276 * y mode returns the elements that hit-test at the current y coordinate 32277 * @function Chart.Interaction.modes.y 32278 * @param chart {chart} the chart we are returning items from 32279 * @param e {Event} the event we are find things at 32280 * @param options {IInteractionOptions} options to use 32281 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned 32282 */ 32283 y: function(chart, e, options) { 32284 var position = getRelativePosition(e, chart); 32285 var items = []; 32286 var intersectsItem = false; 32287 32288 parseVisibleItems(chart, function(element) { 32289 if (element.inYRange(position.y)) { 32290 items.push(element); 32291 } 32292 32293 if (element.inRange(position.x, position.y)) { 32294 intersectsItem = true; 32295 } 32296 }); 32297 32298 // If we want to trigger on an intersect and we don't have any items 32299 // that intersect the position, return nothing 32300 if (options.intersect && !intersectsItem) { 32301 items = []; 32302 } 32303 return items; 32304 } 32305 } 32306}; 32307 32308},{"45":45}],29:[function(require,module,exports){ 32309'use strict'; 32310 32311var defaults = require(25); 32312 32313defaults._set('global', { 32314 responsive: true, 32315 responsiveAnimationDuration: 0, 32316 maintainAspectRatio: true, 32317 events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'], 32318 hover: { 32319 onHover: null, 32320 mode: 'nearest', 32321 intersect: true, 32322 animationDuration: 400 32323 }, 32324 onClick: null, 32325 defaultColor: 'rgba(0,0,0,0.1)', 32326 defaultFontColor: '#666', 32327 defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", 32328 defaultFontSize: 12, 32329 defaultFontStyle: 'normal', 32330 showLines: true, 32331 32332 // Element defaults defined in element extensions 32333 elements: {}, 32334 32335 // Layout options such as padding 32336 layout: { 32337 padding: { 32338 top: 0, 32339 right: 0, 32340 bottom: 0, 32341 left: 0 32342 } 32343 } 32344}); 32345 32346module.exports = function() { 32347 32348 // Occupy the global variable of Chart, and create a simple base class 32349 var Chart = function(item, config) { 32350 this.construct(item, config); 32351 return this; 32352 }; 32353 32354 Chart.Chart = Chart; 32355 32356 return Chart; 32357}; 32358 32359},{"25":25}],30:[function(require,module,exports){ 32360'use strict'; 32361 32362var helpers = require(45); 32363 32364function filterByPosition(array, position) { 32365 return helpers.where(array, function(v) { 32366 return v.position === position; 32367 }); 32368} 32369 32370function sortByWeight(array, reverse) { 32371 array.forEach(function(v, i) { 32372 v._tmpIndex_ = i; 32373 return v; 32374 }); 32375 array.sort(function(a, b) { 32376 var v0 = reverse ? b : a; 32377 var v1 = reverse ? a : b; 32378 return v0.weight === v1.weight ? 32379 v0._tmpIndex_ - v1._tmpIndex_ : 32380 v0.weight - v1.weight; 32381 }); 32382 array.forEach(function(v) { 32383 delete v._tmpIndex_; 32384 }); 32385} 32386 32387/** 32388 * @interface ILayoutItem 32389 * @prop {String} position - The position of the item in the chart layout. Possible values are 32390 * 'left', 'top', 'right', 'bottom', and 'chartArea' 32391 * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area 32392 * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down 32393 * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom) 32394 * @prop {Function} update - Takes two parameters: width and height. Returns size of item 32395 * @prop {Function} getPadding - Returns an object with padding on the edges 32396 * @prop {Number} width - Width of item. Must be valid after update() 32397 * @prop {Number} height - Height of item. Must be valid after update() 32398 * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update 32399 * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update 32400 * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update 32401 * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update 32402 */ 32403 32404// The layout service is very self explanatory. It's responsible for the layout within a chart. 32405// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need 32406// It is this service's responsibility of carrying out that layout. 32407module.exports = { 32408 defaults: {}, 32409 32410 /** 32411 * Register a box to a chart. 32412 * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title. 32413 * @param {Chart} chart - the chart to use 32414 * @param {ILayoutItem} item - the item to add to be layed out 32415 */
32416 addBox: function(chart, item) { 32417 if (!chart.boxes) { 32418 chart.boxes = []; 32419 } 32420 32421 // initialize item with default values 32422 item.fullWidth = item.fullWidth || false; 32423 item.position = item.position || 'top'; 32424 item.weight = item.weight || 0; 32425 32426 chart.boxes.push(item); 32427 }, 32428 32429 /** 32430 * Remove a layoutItem from a chart 32431 * @param {Chart} chart - the chart to remove the box from 32432 * @param {Object} layoutItem - the item to remove from the layout 32433 */ 32434 removeBox: function(chart, layoutItem) { 32435 var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1; 32436 if (index !== -1) { 32437 chart.boxes.splice(index, 1); 32438 } 32439 }, 32440 32441 /** 32442 * Sets (or updates) options on the given `item`. 32443 * @param {Chart} chart - the chart in which the item lives (or will be added to) 32444 * @param {Object} item - the item to configure with the given options 32445 * @param {Object} options - the new item options. 32446 */ 32447 configure: function(chart, item, options) { 32448 var props = ['fullWidth', 'position', 'weight']; 32449 var ilen = props.length; 32450 var i = 0; 32451 var prop; 32452 32453 for (; i < ilen; ++i) { 32454 prop = props[i]; 32455 if (options.hasOwnProperty(prop)) { 32456 item[prop] = options[prop]; 32457 } 32458 } 32459 }, 32460 32461 /** 32462 * Fits boxes of the given chart into the given size by having each box measure itself 32463 * then running a fitting algorithm 32464 * @param {Chart} chart - the chart 32465 * @param {Number} width - the width to fit into 32466 * @param {Number} height - the height to fit into 32467 */ 32468 update: function(chart, width, height) { 32469 if (!chart) { 32470 return; 32471 } 32472 32473 var layoutOptions = chart.options.layout || {}; 32474 var padding = helpers.options.toPadding(layoutOptions.padding); 32475 var leftPadding = padding.left; 32476 var rightPadding = padding.right; 32477 var topPadding = padding.top; 32478 var bottomPadding = padding.bottom; 32479 32480 var leftBoxes = filterByPosition(chart.boxes, 'left'); 32481 var rightBoxes = filterByPosition(chart.boxes, 'right'); 32482 var topBoxes = filterByPosition(chart.boxes, 'top'); 32483 var bottomBoxes = filterByPosition(chart.boxes, 'bottom'); 32484 var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea'); 32485 32486 // Sort boxes by weight. A higher weight is further away from the chart area 32487 sortByWeight(leftBoxes, true); 32488 sortByWeight(rightBoxes, false); 32489 sortByWeight(topBoxes, true); 32490 sortByWeight(bottomBoxes, false); 32491 32492 // Essentially we now have any number of boxes on each of the 4 sides. 32493 // Our canvas looks like the following. 32494 // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and 32495 // B1 is the bottom axis 32496 // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays 32497 // These locations are single-box locations only, when trying to register a chartArea location that is already taken, 32498 // an error will be thrown. 32499 // 32500 // |----------------------------------------------------| 32501 // | T1 (Full Width) | 32502 // |----------------------------------------------------| 32503 // | | | T2 | | 32504 // | |----|-------------------------------------|----| 32505 // | | | C1 | | C2 | | 32506 // | | |----| |----| | 32507 // | | | | | 32508 // | L1 | L2 | ChartArea (C0) | R1 | 32509 // | | | | | 32510 // | | |----| |----| | 32511 // | | | C3 | | C4 | | 32512 // | |----|-------------------------------------|----| 32513 // | | | B1 | | 32514 // |----------------------------------------------------| 32515 // | B2 (Full Width) | 32516 // |----------------------------------------------------| 32517 // 32518 // What we do to find the best sizing, we do the following 32519 // 1. Determine the minimum size of the chart area. 32520 // 2. Split the remaining width equally between each vertical axis 32521 // 3. Split the remaining height equally between each horizontal axis 32522 // 4. Give each layout the maximum size it can be. The layout will return it's minimum size 32523 // 5. Adjust the sizes of each axis based on it's minimum reported size. 32524 // 6. Refit each axis 32525 // 7. Position each axis in the final location 32526 // 8. Tell the chart the final location of the chart area 32527 // 9. Tell any axes that overlay the chart area the positions of the chart area 32528 32529 // Step 1 32530 var chartWidth = width - leftPadding - rightPadding;
32531 var chartHeight = height - topPadding - bottomPadding; 32532 var chartAreaWidth = chartWidth / 2; // min 50% 32533 var chartAreaHeight = chartHeight / 2; // min 50% 32534 32535 // Step 2 32536 var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length); 32537 32538 // Step 3 32539 var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length); 32540 32541 // Step 4 32542 var maxChartAreaWidth = chartWidth; 32543 var maxChartAreaHeight = chartHeight; 32544 var minBoxSizes = []; 32545 32546 function getMinimumBoxSize(box) { 32547 var minSize; 32548 var isHorizontal = box.isHorizontal(); 32549 32550 if (isHorizontal) { 32551 minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight); 32552 maxChartAreaHeight -= minSize.height; 32553 } else { 32554 minSize = box.update(verticalBoxWidth, maxChartAreaHeight); 32555 maxChartAreaWidth -= minSize.width; 32556 } 32557 32558 minBoxSizes.push({ 32559 horizontal: isHorizontal, 32560 minSize: minSize, 32561 box: box, 32562 }); 32563 } 32564 32565 helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize); 32566 32567 // If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478) 32568 var maxHorizontalLeftPadding = 0; 32569 var maxHorizontalRightPadding = 0; 32570 var maxVerticalTopPadding = 0; 32571 var maxVerticalBottomPadding = 0; 32572 32573 helpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) { 32574 if (horizontalBox.getPadding) { 32575 var boxPadding = horizontalBox.getPadding(); 32576 maxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left); 32577 maxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right); 32578 } 32579 }); 32580 32581 helpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) { 32582 if (verticalBox.getPadding) { 32583 var boxPadding = verticalBox.getPadding(); 32584 maxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top); 32585 maxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom); 32586 } 32587 }); 32588 32589 // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could 32590 // be if the axes are drawn at their minimum sizes. 32591 // Steps 5 & 6 32592 var totalLeftBoxesWidth = leftPadding; 32593 var totalRightBoxesWidth = rightPadding; 32594 var totalTopBoxesHeight = topPadding; 32595 var totalBottomBoxesHeight = bottomPadding; 32596 32597 // Function to fit a box 32598 function fitBox(box) { 32599 var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) { 32600 return minBox.box === box; 32601 }); 32602 32603 if (minBoxSize) { 32604 if (box.isHorizontal()) { 32605 var scaleMargin = { 32606 left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding), 32607 right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding), 32608 top: 0, 32609 bottom: 0 32610 }; 32611 32612 // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends 32613 // on the margin. Sometimes they need to increase in size slightly 32614 box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin); 32615 } else { 32616 box.update(minBoxSize.minSize.width, maxChartAreaHeight); 32617 } 32618 } 32619 } 32620 32621 // Update, and calculate the left and right margins for the horizontal boxes 32622 helpers.each(leftBoxes.concat(rightBoxes), fitBox); 32623 32624 helpers.each(leftBoxes, function(box) { 32625 totalLeftBoxesWidth += box.width; 32626 }); 32627 32628 helpers.each(rightBoxes, function(box) { 32629 totalRightBoxesWidth += box.width; 32630 }); 32631 32632 // Set the Left and Right margins for the horizontal boxes 32633 helpers.each(topBoxes.concat(bottomBoxes), fitBox); 32634 32635 // Figure out how much margin is on the top and bottom of the vertical boxes 32636 helpers.each(topBoxes, function(box) { 32637 totalTopBoxesHeight += box.height; 32638 }); 32639 32640 helpers.each(bottomBoxes, function(box) { 32641 totalBottomBoxesHeight += box.height; 32642 }); 32643 32644 function finalFitVerticalBox(box) { 32645 var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) { 32646 return minSize.box === box; 32647 }); 32648 32649 var scaleMargin = { 32650 left: 0, 32651 right: 0, 32652 top: totalTopBoxesHeight, 32653 bottom: totalBottomBoxesHeight 32654 }; 32655 32656 if (minBoxSize) { 32657 box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin); 32658 } 32659 } 32660 32661 // Let the left layout know the final margin 32662 helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox); 32663 32664 // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance) 32665 totalLeftBoxesWidth = leftPadding; 32666 totalRightBoxesWidth = rightPadding;
32667 totalTopBoxesHeight = topPadding; 32668 totalBottomBoxesHeight = bottomPadding; 32669 32670 helpers.each(leftBoxes, function(box) { 32671 totalLeftBoxesWidth += box.width; 32672 }); 32673 32674 helpers.each(rightBoxes, function(box) { 32675 totalRightBoxesWidth += box.width; 32676 }); 32677 32678 helpers.each(topBoxes, function(box) { 32679 totalTopBoxesHeight += box.height; 32680 }); 32681 helpers.each(bottomBoxes, function(box) { 32682 totalBottomBoxesHeight += box.height; 32683 }); 32684 32685 // We may be adding some padding to account for rotated x axis labels 32686 var leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0); 32687 totalLeftBoxesWidth += leftPaddingAddition; 32688 totalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0); 32689 32690 var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0); 32691 totalTopBoxesHeight += topPaddingAddition; 32692 totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0); 32693 32694 // Figure out if our chart area changed. This would occur if the dataset layout label rotation 32695 // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do 32696 // without calling `fit` again 32697 var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight; 32698 var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth; 32699 32700 if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) { 32701 helpers.each(leftBoxes, function(box) { 32702 box.height = newMaxChartAreaHeight; 32703 }); 32704 32705 helpers.each(rightBoxes, function(box) { 32706 box.height = newMaxChartAreaHeight; 32707 }); 32708 32709 helpers.each(topBoxes, function(box) { 32710 if (!box.fullWidth) { 32711 box.width = newMaxChartAreaWidth; 32712 } 32713 }); 32714 32715 helpers.each(bottomBoxes, function(box) { 32716 if (!box.fullWidth) { 32717 box.width = newMaxChartAreaWidth; 32718 } 32719 }); 32720 32721 maxChartAreaHeight = newMaxChartAreaHeight; 32722 maxChartAreaWidth = newMaxChartAreaWidth; 32723 } 32724 32725 // Step 7 - Position the boxes 32726 var left = leftPadding + leftPaddingAddition; 32727 var top = topPadding + topPaddingAddition; 32728 32729 function placeBox(box) { 32730 if (box.isHorizontal()) { 32731 box.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth; 32732 box.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth; 32733 box.top = top; 32734 box.bottom = top + box.height; 32735 32736 // Move to next point 32737 top = box.bottom; 32738 32739 } else { 32740 32741 box.left = left; 32742 box.right = left + box.width;
32743 box.top = totalTopBoxesHeight; 32744 box.bottom = totalTopBoxesHeight + maxChartAreaHeight; 32745 32746 // Move to next point 32747 left = box.right; 32748 } 32749 } 32750 32751 helpers.each(leftBoxes.concat(topBoxes), placeBox); 32752 32753 // Account for chart width and height 32754 left += maxChartAreaWidth; 32755 top += maxChartAreaHeight; 32756 32757 helpers.each(rightBoxes, placeBox); 32758 helpers.each(bottomBoxes, placeBox); 32759 32760 // Step 8 32761 chart.chartArea = { 32762 left: totalLeftBoxesWidth, 32763 top: totalTopBoxesHeight, 32764 right: totalLeftBoxesWidth + maxChartAreaWidth, 32765 bottom: totalTopBoxesHeight + maxChartAreaHeight 32766 }; 32767 32768 // Step 9 32769 helpers.each(chartAreaBoxes, function(box) { 32770 box.left = chart.chartArea.left; 32771 box.top = chart.chartArea.top; 32772 box.right = chart.chartArea.right; 32773 box.bottom = chart.chartArea.bottom; 32774 32775 box.update(maxChartAreaWidth, maxChartAreaHeight); 32776 }); 32777 } 32778}; 32779 32780},{"45":45}],31:[function(require,module,exports){ 32781'use strict'; 32782 32783var defaults = require(25); 32784var helpers = require(45); 32785 32786defaults._set('global', { 32787 plugins: {} 32788}); 32789 32790/** 32791 * The plugin service singleton 32792 * @namespace Chart.plugins 32793 * @since 2.1.0 32794 */ 32795module.exports = { 32796 /** 32797 * Globally registered plugins. 32798 * @private 32799 */ 32800 _plugins: [], 32801 32802 /** 32803 * This identifier is used to invalidate the descriptors cache attached to each chart 32804 * when a global plugin is registered or unregistered. In this case, the cache ID is 32805 * incremented and descriptors are regenerated during following API calls. 32806 * @private 32807 */ 32808 _cacheId: 0, 32809 32810 /** 32811 * Registers the given plugin(s) if not already registered. 32812 * @param {Array|Object} plugins plugin instance(s). 32813 */ 32814 register: function(plugins) { 32815 var p = this._plugins; 32816 ([]).concat(plugins).forEach(function(plugin) { 32817 if (p.indexOf(plugin) === -1) { 32818 p.push(plugin); 32819 } 32820 }); 32821 32822 this._cacheId++; 32823 }, 32824 32825 /** 32826 * Unregisters the given plugin(s) only if registered. 32827 * @param {Array|Object} plugins plugin instance(s). 32828 */ 32829 unregister: function(plugins) { 32830 var p = this._plugins; 32831 ([]).concat(plugins).forEach(function(plugin) { 32832 var idx = p.indexOf(plugin); 32833 if (idx !== -1) { 32834 p.splice(idx, 1); 32835 } 32836 }); 32837 32838 this._cacheId++; 32839 }, 32840 32841 /** 32842 * Remove all registered plugins. 32843 * @since 2.1.5 32844 */ 32845 clear: function() { 32846 this._plugins = []; 32847 this._cacheId++; 32848 }, 32849 32850 /** 32851 * Returns the number of registered plugins? 32852 * @returns {Number} 32853 * @since 2.1.5 32854 */ 32855 count: function() { 32856 return this._plugins.length; 32857 }, 32858 32859 /** 32860 * Returns all registered plugin instances. 32861 * @returns {Array} array of plugin objects. 32862 * @since 2.1.5 32863 */ 32864 getAll: function() { 32865 return this._plugins; 32866 }, 32867 32868 /** 32869 * Calls enabled plugins for `chart` on the specified hook and with the given args. 32870 * This method immediately returns as soon as a plugin explicitly returns false. The 32871 * returned value can be used, for instance, to interrupt the current action. 32872 * @param {Object} chart - The chart instance for which plugins should be called. 32873 * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate'). 32874 * @param {Array} [args] - Extra arguments to apply to the hook call. 32875 * @returns {Boolean} false if any of the plugins return false, else returns true. 32876 */ 32877 notify: function(chart, hook, args) { 32878 var descriptors = this.descriptors(chart); 32879 var ilen = descriptors.length; 32880 var i, descriptor, plugin, params, method; 32881 32882 for (i = 0; i < ilen; ++i) { 32883 descriptor = descriptors[i]; 32884 plugin = descriptor.plugin; 32885 method = plugin[hook]; 32886 if (typeof method === 'function') { 32887 params = [chart].concat(args || []); 32888 params.push(descriptor.options); 32889 if (method.apply(plugin, params) === false) { 32890 return false; 32891 } 32892 } 32893 } 32894 32895 return true; 32896 }, 32897 32898 /** 32899 * Returns descriptors of enabled plugins for the given chart. 32900 * @returns {Array} [{ plugin, options }] 32901 * @private 32902 */ 32903 descriptors: function(chart) { 32904 var cache = chart.$plugins || (chart.$plugins = {}); 32905 if (cache.id === this._cacheId) { 32906 return cache.descriptors; 32907 } 32908 32909 var plugins = []; 32910 var descriptors = []; 32911 var config = (chart && chart.config) || {}; 32912 var options = (config.options && config.options.plugins) || {}; 32913
vendor: 9,411 bytes, lines 32914-33142
32914 this._plugins.concat(config.plugins || []).forEach(function(plugin) { 32915 var idx = plugins.indexOf(plugin); 32916 if (idx !== -1) { 32917 return; 32918 } 32919 32920 var id = plugin.id; 32921 var opts = options[id]; 32922 if (opts === false) { 32923 return; 32924 } 32925 32926 if (opts === true) { 32927 opts = helpers.clone(defaults.global.plugins[id]); 32928 } 32929 32930 plugins.push(plugin); 32931 descriptors.push({ 32932 plugin: plugin, 32933 options: opts || {} 32934 }); 32935 }); 32936 32937 cache.descriptors = descriptors; 32938 cache.id = this._cacheId; 32939 return descriptors; 32940 }, 32941 32942 /** 32943 * Invalidates cache for the given chart: descriptors hold a reference on plugin option, 32944 * but in some cases, this reference can be changed by the user when updating options. 32945 * https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167 32946 * @private 32947 */ 32948 _invalidate: function(chart) { 32949 delete chart.$plugins; 32950 } 32951}; 32952 32953/** 32954 * Plugin extension hooks. 32955 * @interface IPlugin 32956 * @since 2.1.0 32957 */ 32958/** 32959 * @method IPlugin#beforeInit 32960 * @desc Called before initializing `chart`. 32961 * @param {Chart.Controller} chart - The chart instance. 32962 * @param {Object} options - The plugin options. 32963 */ 32964/** 32965 * @method IPlugin#afterInit 32966 * @desc Called after `chart` has been initialized and before the first update. 32967 * @param {Chart.Controller} chart - The chart instance. 32968 * @param {Object} options - The plugin options. 32969 */ 32970/** 32971 * @method IPlugin#beforeUpdate 32972 * @desc Called before updating `chart`. If any plugin returns `false`, the update 32973 * is cancelled (and thus subsequent render(s)) until another `update` is triggered. 32974 * @param {Chart.Controller} chart - The chart instance. 32975 * @param {Object} options - The plugin options. 32976 * @returns {Boolean} `false` to cancel the chart update. 32977 */ 32978/** 32979 * @method IPlugin#afterUpdate 32980 * @desc Called after `chart` has been updated and before rendering. Note that this 32981 * hook will not be called if the chart update has been previously cancelled. 32982 * @param {Chart.Controller} chart - The chart instance. 32983 * @param {Object} options - The plugin options. 32984 */ 32985/** 32986 * @method IPlugin#beforeDatasetsUpdate 32987 * @desc Called before updating the `chart` datasets. If any plugin returns `false`, 32988 * the datasets update is cancelled until another `update` is triggered. 32989 * @param {Chart.Controller} chart - The chart instance. 32990 * @param {Object} options - The plugin options. 32991 * @returns {Boolean} false to cancel the datasets update. 32992 * @since version 2.1.5 32993*/ 32994/** 32995 * @method IPlugin#afterDatasetsUpdate 32996 * @desc Called after the `chart` datasets have been updated. Note that this hook 32997 * will not be called if the datasets update has been previously cancelled. 32998 * @param {Chart.Controller} chart - The chart instance. 32999 * @param {Object} options - The plugin options. 33000 * @since version 2.1.5 33001 */ 33002/** 33003 * @method IPlugin#beforeDatasetUpdate 33004 * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin 33005 * returns `false`, the datasets update is cancelled until another `update` is triggered. 33006 * @param {Chart} chart - The chart instance. 33007 * @param {Object} args - The call arguments. 33008 * @param {Number} args.index - The dataset index. 33009 * @param {Object} args.meta - The dataset metadata. 33010 * @param {Object} options - The plugin options. 33011 * @returns {Boolean} `false` to cancel the chart datasets drawing. 33012 */ 33013/** 33014 * @method IPlugin#afterDatasetUpdate 33015 * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note 33016 * that this hook will not be called if the datasets update has been previously cancelled. 33017 * @param {Chart} chart - The chart instance. 33018 * @param {Object} args - The call arguments. 33019 * @param {Number} args.index - The dataset index. 33020 * @param {Object} args.meta - The dataset metadata. 33021 * @param {Object} options - The plugin options. 33022 */ 33023/** 33024 * @method IPlugin#beforeLayout 33025 * @desc Called before laying out `chart`. If any plugin returns `false`, 33026 * the layout update is cancelled until another `update` is triggered. 33027 * @param {Chart.Controller} chart - The chart instance. 33028 * @param {Object} options - The plugin options. 33029 * @returns {Boolean} `false` to cancel the chart layout. 33030 */ 33031/** 33032 * @method IPlugin#afterLayout 33033 * @desc Called after the `chart` has been layed out. Note that this hook will not 33034 * be called if the layout update has been previously cancelled. 33035 * @param {Chart.Controller} chart - The chart instance. 33036 * @param {Object} options - The plugin options. 33037 */ 33038/** 33039 * @method IPlugin#beforeRender 33040 * @desc Called before rendering `chart`. If any plugin returns `false`, 33041 * the rendering is cancelled until another `render` is triggered. 33042 * @param {Chart.Controller} chart - The chart instance. 33043 * @param {Object} options - The plugin options. 33044 * @returns {Boolean} `false` to cancel the chart rendering. 33045 */ 33046/** 33047 * @method IPlugin#afterRender 33048 * @desc Called after the `chart` has been fully rendered (and animation completed). Note 33049 * that this hook will not be called if the rendering has been previously cancelled. 33050 * @param {Chart.Controller} chart - The chart instance. 33051 * @param {Object} options - The plugin options. 33052 */ 33053/** 33054 * @method IPlugin#beforeDraw 33055 * @desc Called before drawing `chart` at every animation frame specified by the given 33056 * easing value. If any plugin returns `false`, the frame drawing is cancelled until 33057 * another `render` is triggered. 33058 * @param {Chart.Controller} chart - The chart instance. 33059 * @param {Number} easingValue - The current animation value, between 0.0 and 1.0. 33060 * @param {Object} options - The plugin options. 33061 * @returns {Boolean} `false` to cancel the chart drawing. 33062 */ 33063/** 33064 * @method IPlugin#afterDraw 33065 * @desc Called after the `chart` has been drawn for the specific easing value. Note 33066 * that this hook will not be called if the drawing has been previously cancelled. 33067 * @param {Chart.Controller} chart - The chart instance. 33068 * @param {Number} easingValue - The current animation value, between 0.0 and 1.0. 33069 * @param {Object} options - The plugin options. 33070 */ 33071/** 33072 * @method IPlugin#beforeDatasetsDraw 33073 * @desc Called before drawing the `chart` datasets. If any plugin returns `false`, 33074 * the datasets drawing is cancelled until another `render` is triggered. 33075 * @param {Chart.Controller} chart - The chart instance. 33076 * @param {Number} easingValue - The current animation value, between 0.0 and 1.0. 33077 * @param {Object} options - The plugin options. 33078 * @returns {Boolean} `false` to cancel the chart datasets drawing. 33079 */ 33080/** 33081 * @method IPlugin#afterDatasetsDraw 33082 * @desc Called after the `chart` datasets have been drawn. Note that this hook 33083 * will not be called if the datasets drawing has been previously cancelled. 33084 * @param {Chart.Controller} chart - The chart instance. 33085 * @param {Number} easingValue - The current animation value, between 0.0 and 1.0. 33086 * @param {Object} options - The plugin options. 33087 */ 33088/** 33089 * @method IPlugin#beforeDatasetDraw 33090 * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets 33091 * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing 33092 * is cancelled until another `render` is triggered. 33093 * @param {Chart} chart - The chart instance. 33094 * @param {Object} args - The call arguments. 33095 * @param {Number} args.index - The dataset index. 33096 * @param {Object} args.meta - The dataset metadata. 33097 * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0. 33098 * @param {Object} options - The plugin options. 33099 * @returns {Boolean} `false` to cancel the chart datasets drawing. 33100 */ 33101/** 33102 * @method IPlugin#afterDatasetDraw 33103 * @desc Called after the `chart` datasets at the given `args.index` have been drawn 33104 * (datasets are drawn in the reverse order). Note that this hook will not be called 33105 * if the datasets drawing has been previously cancelled. 33106 * @param {Chart} chart - The chart instance. 33107 * @param {Object} args - The call arguments. 33108 * @param {Number} args.index - The dataset index. 33109 * @param {Object} args.meta - The dataset metadata. 33110 * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0. 33111 * @param {Object} options - The plugin options. 33112 */ 33113/** 33114 * @method IPlugin#beforeTooltipDraw 33115 * @desc Called before drawing the `tooltip`. If any plugin returns `false`, 33116 * the tooltip drawing is cancelled until another `render` is triggered. 33117 * @param {Chart} chart - The chart instance. 33118 * @param {Object} args - The call arguments. 33119 * @param {Object} args.tooltip - The tooltip. 33120 * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0. 33121 * @param {Object} options - The plugin options. 33122 * @returns {Boolean} `false` to cancel the chart tooltip drawing. 33123 */ 33124/** 33125 * @method IPlugin#afterTooltipDraw 33126 * @desc Called after drawing the `tooltip`. Note that this hook will not 33127 * be called if the tooltip drawing has been previously cancelled. 33128 * @param {Chart} chart - The chart instance. 33129 * @param {Object} args - The call arguments. 33130 * @param {Object} args.tooltip - The tooltip. 33131 * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0. 33132 * @param {Object} options - The plugin options. 33133 */ 33134/** 33135 * @method IPlugin#beforeEvent 33136 * @desc Called before processing the specified `event`. If any plugin returns `false`, 33137 * the event will be discarded. 33138 * @param {Chart.Controller} chart - The chart instance. 33139 * @param {IEvent} event - The event object. 33140 * @param {Object} options - The plugin options. 33141 */ 33142/**
33143 * @method IPlugin#afterEvent 33144 * @desc Called after the `event` has been consumed. Note that this hook 33145 * will not be called if the `event` has been previously discarded. 33146 * @param {Chart.Controller} chart - The chart instance. 33147 * @param {IEvent} event - The event object. 33148 * @param {Object} options - The plugin options. 33149 */ 33150/** 33151 * @method IPlugin#resize 33152 * @desc Called after the chart as been resized. 33153 * @param {Chart.Controller} chart - The chart instance. 33154 * @param {Number} size - The new canvas display size (eq. canvas.style width & height). 33155 * @param {Object} options - The plugin options. 33156 */ 33157/** 33158 * @method IPlugin#destroy 33159 * @desc Called after the chart as been destroyed. 33160 * @param {Chart.Controller} chart - The chart instance. 33161 * @param {Object} options - The plugin options. 33162 */ 33163 33164},{"25":25,"45":45}],32:[function(require,module,exports){ 33165'use strict'; 33166 33167var defaults = require(25); 33168var Element = require(26); 33169var helpers = require(45); 33170var Ticks = require(34); 33171 33172defaults._set('scale', { 33173 display: true, 33174 position: 'left', 33175 offset: false, 33176 33177 // grid line settings 33178 gridLines: { 33179 display: true, 33180 color: 'rgba(0, 0, 0, 0.1)', 33181 lineWidth: 1, 33182 drawBorder: true, 33183 drawOnChartArea: true, 33184 drawTicks: true, 33185 tickMarkLength: 10, 33186 zeroLineWidth: 1, 33187 zeroLineColor: 'rgba(0,0,0,0.25)', 33188 zeroLineBorderDash: [], 33189 zeroLineBorderDashOffset: 0.0, 33190 offsetGridLines: false, 33191 borderDash: [], 33192 borderDashOffset: 0.0 33193 }, 33194 33195 // scale label 33196 scaleLabel: { 33197 // display property 33198 display: false, 33199 33200 // actual label 33201 labelString: '', 33202 33203 // line height 33204 lineHeight: 1.2, 33205 33206 // top/bottom padding 33207 padding: { 33208 top: 4, 33209 bottom: 4 33210 } 33211 }, 33212 33213 // label settings 33214 ticks: { 33215 beginAtZero: false, 33216 minRotation: 0, 33217 maxRotation: 50, 33218 mirror: false, 33219 padding: 0, 33220 reverse: false, 33221 display: true, 33222 autoSkip: true, 33223 autoSkipPadding: 0, 33224 labelOffset: 0, 33225 // We pass through arrays to be rendered as multiline labels, we convert Others to strings here. 33226 callback: Ticks.formatters.values, 33227 minor: {}, 33228 major: {} 33229 } 33230}); 33231 33232function labelsFromTicks(ticks) { 33233 var labels = []; 33234 var i, ilen; 33235 33236 for (i = 0, ilen = ticks.length; i < ilen; ++i) { 33237 labels.push(ticks[i].label); 33238 } 33239 33240 return labels; 33241} 33242 33243function getLineValue(scale, index, offsetGridLines) { 33244 var lineValue = scale.getPixelForTick(index); 33245 33246 if (offsetGridLines) { 33247 if (index === 0) { 33248 lineValue -= (scale.getPixelForTick(1) - lineValue) / 2; 33249 } else { 33250 lineValue -= (lineValue - scale.getPixelForTick(index - 1)) / 2; 33251 } 33252 } 33253 return lineValue; 33254} 33255 33256module.exports = function(Chart) { 33257 33258 function computeTextSize(context, tick, font) { 33259 return helpers.isArray(tick) ? 33260 helpers.longestText(context, font, tick) : 33261 context.measureText(tick).width; 33262 } 33263 33264 function parseFontOptions(options) { 33265 var valueOrDefault = helpers.valueOrDefault; 33266 var globalDefaults = defaults.global; 33267 var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize); 33268 var style = valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle); 33269 var family = valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily); 33270 33271 return { 33272 size: size, 33273 style: style, 33274 family: family, 33275 font: helpers.fontString(size, style, family) 33276 }; 33277 } 33278 33279 function parseLineHeight(options) { 33280 return helpers.options.toLineHeight( 33281 helpers.valueOrDefault(options.lineHeight, 1.2), 33282 helpers.valueOrDefault(options.fontSize, defaults.global.defaultFontSize)); 33283 } 33284 33285 Chart.Scale = Element.extend({ 33286 /** 33287 * Get the padding needed for the scale 33288 * @method getPadding 33289 * @private 33290 * @returns {Padding} the necessary padding 33291 */ 33292 getPadding: function() { 33293 var me = this; 33294 return { 33295 left: me.paddingLeft || 0, 33296 top: me.paddingTop || 0, 33297 right: me.paddingRight || 0, 33298 bottom: me.paddingBottom || 0 33299 }; 33300 }, 33301 33302 /** 33303 * Returns the scale tick objects ({label, major}) 33304 * @since 2.7 33305 */ 33306 getTicks: function() { 33307 return this._ticks; 33308 }, 33309 33310 // These methods are ordered by lifecyle. Utilities then follow. 33311 // Any function defined here is inherited by all scale types. 33312 // Any function can be extended by the scale type 33313 33314 mergeTicksOptions: function() { 33315 var ticks = this.options.ticks; 33316 if (ticks.minor === false) { 33317 ticks.minor = { 33318 display: false 33319 }; 33320 } 33321 if (ticks.major === false) { 33322 ticks.major = { 33323 display: false 33324 }; 33325 } 33326 for (var key in ticks) { 33327 if (key !== 'major' && key !== 'minor') { 33328 if (typeof ticks.minor[key] === 'undefined') { 33329 ticks.minor[key] = ticks[key]; 33330 } 33331 if (typeof ticks.major[key] === 'undefined') { 33332 ticks.major[key] = ticks[key]; 33333 } 33334 } 33335 } 33336 }, 33337 beforeUpdate: function() { 33338 helpers.callback(this.options.beforeUpdate, [this]); 33339 }, 33340 update: function(maxWidth, maxHeight, margins) { 33341 var me = this; 33342 var i, ilen, labels, label, ticks, tick; 33343 33344 // Update Lifecycle - Probably don't want to ever extend or over
33344write this function ;) 33345 me.beforeUpdate(); 33346 33347 // Absorb the master measurements 33348 me.maxWidth = maxWidth; 33349 me.maxHeight = maxHeight; 33350 me.margins = helpers.extend({ 33351 left: 0, 33352 right: 0, 33353 top: 0, 33354 bottom: 0 33355 }, margins); 33356 me.longestTextCache = me.longestTextCache || {}; 33357 33358 // Dimensions 33359 me.beforeSetDimensions(); 33360 me.setDimensions(); 33361 me.afterSetDimensions(); 33362 33363 // Data min/max 33364 me.beforeDataLimits(); 33365 me.determineDataLimits(); 33366 me.afterDataLimits(); 33367 33368 // Ticks - `this.ticks` is now DEPRECATED! 33369 // Internal ticks are now stored as objects in the PRIVATE `this._ticks` member 33370 // and must not be accessed directly from outside this class. `this.ticks` being 33371 // around for long time and not marked as private, we can't change its structure 33372 // without unexpected breaking changes. If you need to access the scale ticks, 33373 // use scale.getTicks() instead. 33374 33375 me.beforeBuildTicks(); 33376 33377 // New implementations should return an array of objects but for BACKWARD COMPAT, 33378 // we still support no return (`this.ticks` internally set by calling this method). 33379 ticks = me.buildTicks() || []; 33380 33381 me.afterBuildTicks(); 33382 33383 me.beforeTickToLabelConversion(); 33384 33385 // New implementations should return the formatted tick labels but for BACKWARD 33386 // COMPAT, we still support no return (`this.ticks` internally changed by calling 33387 // this method and supposed to contain only string values). 33388 labels = me.convertTicksToLabels(ticks) || me.ticks; 33389 33390 me.afterTickToLabelConversion(); 33391 33392 me.ticks = labels; // BACKWARD COMPATIBILITY 33393 33394 // IMPORTANT: from this point, we consider that `this.ticks` will NEVER change! 33395 33396 // BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`) 33397 for (i = 0, ilen = labels.length; i < ilen; ++i) { 33398 label = labels[i]; 33399 tick = ticks[i]; 33400 if (!tick) { 33401 ticks.push(tick = { 33402 label: label, 33403 major: false 33404 }); 33405 } else { 33406 tick.label = label; 33407 } 33408 } 33409 33410 me._ticks = ticks; 33411 33412 // Tick Rotation 33413 me.beforeCalculateTickRotation(); 33414 me.calculateTickRotation(); 33415 me.afterCalculateTickRotation(); 33416 // Fit 33417 me.beforeFit(); 33418 me.fit(); 33419 me.afterFit(); 33420 // 33421 me.afterUpdate(); 33422 33423 return me.minSize; 33424 33425 }, 33426 afterUpdate: function() { 33427 helpers.callback(this.options.afterUpdate, [this]); 33428 }, 33429 33430 // 33431 33432 beforeSetDimensions: function() { 33433 helpers.callback(this.options.beforeSetDimensions, [this]); 33434 }, 33435 setDimensions: function() { 33436 var me = this; 33437 // Set the unconstrained dimension before label rotation 33438 if (me.isHorizontal()) { 33439 // Reset position before calculating rotation 33440 me.width = me.maxWidth; 33441 me.left = 0; 33442 me.right = me.width; 33443 } else { 33444 me.height = me.maxHeight; 33445 33446 // Reset position before calculating rotation 33447 me.top = 0; 33448 me.bottom = me.height; 33449 } 33450 33451 // Reset padding 33452 me.paddingLeft = 0; 33453 me.paddingTop = 0; 33454 me.paddingRight = 0; 33455 me.paddingBottom = 0; 33456 }, 33457 afterSetDimensions: function() { 33458 helpers.callback(this.options.afterSetDimensions, [this]); 33459 }, 33460 33461 // Data limits 33462 beforeDataLimits: function() { 33463 helpers.callback(this.options.beforeDataLimits, [this]); 33464 }, 33465 determineDataLimits: helpers.noop, 33466 afterDataLimits: function() { 33467 helpers.callback(this.options.afterDataLimits, [this]); 33468 }, 33469 33470 // 33471 beforeBuildTicks: function() { 33472 helpers.callback(this.options.beforeBuildTicks, [this]); 33473 }, 33474 buildTicks: helpers.noop, 33475 afterBuildTicks: function() { 33476 helpers.callback(this.options.afterBuildTicks, [this]); 33477 }, 33478 33479 beforeTickToLabelConversion: function() { 33480 helpers.callback(this.options.beforeTickToLabelConversion, [this]); 33481 }, 33482 convertTicksToLabels: function() { 33483 var me = this; 33484 // Convert ticks to strings 33485 var tickOpts = me.options.ticks; 33486 me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback, this); 33487 }, 33488 afterTickToLabelConversion: function() { 33489 helpers.callback(this.options.afterTickToLabelConversion, [this]); 33490 }, 33491 33492 // 33493 33494 beforeCalculateTickRotation: function() { 33495 helpers.callback(this.options.beforeCalculateTickRotation, [this]); 33496 }, 33497 calculateTickRotation: function() { 33498 var me = this; 33499 var context = me.ctx; 33500 var tickOpts = me.options.ticks; 33501 var labels = labelsFromTicks(me._ticks); 33502 33503 // Get the width of each grid by calculating the difference 33504 // between x offsets between 0 and 1.
33505 var tickFont = parseFontOptions(tickOpts); 33506 context.font = tickFont.font; 33507 33508 var labelRotation = tickOpts.minRotation || 0; 33509 33510 if (labels.length && me.options.display && me.isHorizontal()) { 33511 var originalLabelWidth = helpers.longestText(context, tickFont.font, labels, me.longestTextCache); 33512 var labelWidth = originalLabelWidth; 33513 var cosRotation, sinRotation; 33514 33515 // Allow 3 pixels x2 padding either side for label readability 33516 var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6; 33517 33518 // Max label rotation can be set or default to 90 - also act as a loop counter 33519 while (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) { 33520 var angleRadians = helpers.toRadians(labelRotation); 33521 cosRotation = Math.cos(angleRadians); 33522 sinRotation = Math.sin(angleRadians); 33523 33524 if (sinRotation * originalLabelWidth > me.maxHeight) { 33525 // go back one step 33526 labelRotation--; 33527 break; 33528 } 33529 33530 labelRotation++; 33531 labelWidth = cosRotation * originalLabelWidth; 33532 } 33533 } 33534 33535 me.labelRotation = labelRotation; 33536 }, 33537 afterCalculateTickRotation: function() { 33538 helpers.callback(this.options.afterCalculateTickRotation, [this]); 33539 }, 33540 33541 // 33542 33543 beforeFit: function() { 33544 helpers.callback(this.options.beforeFit, [this]); 33545 }, 33546 fit: function() { 33547 var me = this; 33548 // Reset 33549 var minSize = me.minSize = { 33550 width: 0, 33551 height: 0 33552 }; 33553 33554 var labels = labelsFromTicks(me._ticks); 33555 33556 var opts = me.options; 33557 var tickOpts = opts.ticks; 33558 var scaleLabelOpts = opts.scaleLabel; 33559 var gridLineOpts = opts.gridLines; 33560 var display = opts.display; 33561 var isHorizontal = me.isHorizontal(); 33562 33563 var tickFont = parseFontOptions(tickOpts); 33564 var tickMarkLength = opts.gridLines.tickMarkLength; 33565 33566 // Width 33567 if (isHorizontal) { 33568 // subtract the margins to line up with the chartArea if we are a full width scale 33569 minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth; 33570 } else { 33571 minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0; 33572 } 33573 33574 // height 33575 if (isHorizontal) { 33576 minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0; 33577 } else { 33578 minSize.height = me.maxHeight; // fill all the height 33579 } 33580 33581 // Are we showing a title for the scale? 33582 if (scaleLabelOpts.display && display) { 33583 var scaleLabelLineHeight = parseLineHeight(scaleLabelOpts); 33584 var scaleLabelPadding = helpers.options.toPadding(scaleLabelOpts.padding); 33585 var deltaHeight = scaleLabelLineHeight + scaleLabelPadding.height; 33586 33587 if (isHorizontal) { 33588 minSize.height += deltaHeight; 33589 } else { 33590 minSize.width += deltaHeight; 33591 } 33592 } 33593 33594 // Don't bother fitting the ticks if we are not showing them 33595 if (tickOpts.display && display) { 33596 var largestTextWidth = helpers.longestText(me.ctx, tickFont.font, labels, me.longestTextCache); 33597 var tallestLabelHeightInLines = helpers.numberOfLabelLines(labels); 33598 var lineSpace = tickFont.size * 0.5; 33599 var tickPadding = me.options.ticks.padding; 33600 33601 if (isHorizontal) { 33602 // A horizontal axis is more constrained by the height. 33603 me.longestLabelWidth = largestTextWidth; 33604 33605 var angleRadians = helpers.toRadians(me.labelRotation); 33606 var cosRotation = Math.cos(angleRadians); 33607 var sinRotation = Math.sin(angleRadians); 33608 33609 // TODO - improve this calculation 33610 var labelHeight = (sinRotation * largestTextWidth) 33611 + (tickFont.size * tallestLabelHeightInLines) 33612 + (lineSpace * (tallestLabelHeightInLines - 1)) 33613 + lineSpace; // padding 33614 33615 minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding); 33616 33617 me.ctx.font = tickFont.font; 33618 var firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.font); 33619 var lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.font); 33620 33621 // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned 33622 // which means that the right padding is dominated by the font height 33623 if (me.labelRotation !== 0) { 33624 me.paddingLeft = opts.position === 'bottom' ? (cosRotation * firstLabelWidth) + 3 : (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges 33625 me.paddingRight = opts.position === 'bottom' ? (cosRotation * lineSpace) + 3 : (cosRotation * lastLabelWidth) + 3; 33626 } else {
33627 me.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges 33628 me.paddingRight = lastLabelWidth / 2 + 3; 33629 } 33630 } else { 33631 // A vertical axis is more constrained by the width. Labels are the 33632 // dominant factor here, so get that length first and account for padding 33633 if (tickOpts.mirror) { 33634 largestTextWidth = 0; 33635 } else { 33636 // use lineSpace for consistency with horizontal axis 33637 // tickPadding is not implemented for horizontal 33638 largestTextWidth += tickPadding + lineSpace; 33639 } 33640 33641 minSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth); 33642 33643 me.paddingTop = tickFont.size / 2; 33644 me.paddingBottom = tickFont.size / 2; 33645 } 33646 } 33647 33648 me.handleMargins(); 33649 33650 me.width = minSize.width; 33651 me.height = minSize.height; 33652 }, 33653 33654 /** 33655 * Handle margins and padding interactions 33656 * @private 33657 */ 33658 handleMargins: function() { 33659 var me = this; 33660 if (me.margins) { 33661 me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0); 33662 me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0); 33663 me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0); 33664 me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0); 33665 } 33666 }, 33667 33668 afterFit: function() { 33669 helpers.callback(this.options.afterFit, [this]); 33670 }, 33671 33672 // Shared Methods 33673 isHorizontal: function() { 33674 return this.options.position === 'top' || this.options.position === 'bottom'; 33675 }, 33676 isFullWidth: function() { 33677 return (this.options.fullWidth); 33678 }, 33679 33680 // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not 33681 getRightValue: function(rawValue) { 33682 // Null and undefined values first 33683 if (helpers.isNullOrUndef(rawValue)) { 33684 return NaN; 33685 } 33686 // isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values 33687 if (typeof rawValue === 'number' && !isFinite(rawValue)) { 33688 return NaN; 33689 } 33690 // If it is in fact an object, dive in one more level 33691 if (rawValue) { 33692 if (this.isHorizontal()) { 33693 if (rawValue.x !== undefined) { 33694 return this.getRightValue(rawValue.x); 33695 } 33696 } else if (rawValue.y !== undefined) { 33697 return this.getRightValue(rawValue.y); 33698 } 33699 } 33700 33701 // Value is good, return it 33702 return rawValue; 33703 }, 33704 33705 /** 33706 * Used to get the value to display in the tooltip for the data at the given index 33707 * @param index 33708 * @param datasetIndex 33709 */ 33710 getLabelForIndex: helpers.noop, 33711 33712 /** 33713 * Returns the location of the given data point. Value can either be an index or a numerical value 33714 * The coordinate (0, 0) is at the upper-left corner of the canvas 33715 * @param value 33716 * @param index 33717 * @param datasetIndex 33718 */ 33719 getPixelForValue: helpers.noop, 33720 33721 /** 33722 * Used to get the data value from a given pixel. This is the inverse of getPixelForValue 33723 * The coordinate (0, 0) is at the upper-left corner of the canvas 33724 * @param pixel 33725 */ 33726 getValueForPixel: helpers.noop, 33727 33728 /** 33729 * Returns the location of the tick at the given index 33730 * The coordinate (0, 0) is at the upper-left corner of the canvas 33731 */ 33732 getPixelForTick: function(index) { 33733 var me = this; 33734 var offset = me.options.offset; 33735 if (me.isHorizontal()) { 33736 var innerWidth = me.width - (me.paddingLeft + me.paddingRight); 33737 var tickWidth = innerWidth / Math.max((me._ticks.length - (offset ? 0 : 1)), 1); 33738 var pixel = (tickWidth * index) + me.paddingLeft; 33739 33740 if (offset) { 33741 pixel += tickWidth / 2; 33742 } 33743 33744 var finalVal = me.left + Math.round(pixel); 33745 finalVal += me.isFullWidth() ? me.margins.left : 0; 33746 return finalVal; 33747 } 33748 var innerHeight = me.height - (me.paddingTop + me.paddingBottom); 33749 return me.top + (index * (innerHeight / (me._ticks.length - 1))); 33750 }, 33751 33752 /** 33753 * Utility for getting the pixel location of a percentage of scale 33754 * The coordinate (0, 0) is at the upper-left corner of the canvas 33755 */ 33756 getPixelForDecimal: function(decimal) { 33757 var me = this; 33758 if (me.isHorizontal()) { 33759 var innerWidth = me.width - (me.paddingLeft + me.paddingRight); 33760 var valueOffset = (innerWidth * decimal) + me.paddingLeft; 33761 33762 var finalVal = me.left + Math.round(valueOffset); 33763 finalVal += me.isFullWidth() ? me.margins.left : 0; 33764 return finalVal; 33765 } 33766 return me.top + (decimal * me.height); 33767 }, 33768 33769 /** 33770 * Returns the pixel for the minimum chart value 33771 * The coordinate (0, 0) is at the upper-left corner of the canvas 33772 */ 33773 getBasePixel: function() { 33774 return this.getPixelForValue(this.getBaseValue()); 33775 }, 33776 33777 getBaseValue: function() { 33778 var me = this; 33779 var min = me.min; 33780 var max = me.max; 33781 33782 return me.beginAtZero ? 0 : 33783 min < 0 && max < 0 ? max : 33784 min > 0 && max > 0 ? min : 33785 0; 33786 }, 33787 33788 /** 33789 * Returns a subset of ticks to be plotted to avoid overlapping labels. 33790 * @private 33791 */ 33792 _autoSkip: function(ticks) { 33793 var skipRatio; 33794 var me = this; 33795 var isHorizontal = me.isHorizontal(); 33796 var optionTicks = me.options.ticks.minor; 33797 var tickCount = ticks.length; 33798 var labelRotationRadians = helpers.toRadians(me.labelRotation); 33799 var cosRotation = Math.cos(labelRotationRadians); 33800 var longestRotatedLabel = me.longestLabelWidth * cosRotation; 33801 var result = []; 33802 var i, tick, shouldSkip; 33803
33804 // figure out the maximum number of gridlines to show 33805 var maxTicks; 33806 if (optionTicks.maxTicksLimit) { 33807 maxTicks = optionTicks.maxTicksLimit; 33808 } 33809 33810 if (isHorizontal) { 33811 skipRatio = false; 33812 33813 if ((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount > (me.width - (me.paddingLeft + me.paddingRight))) { 33814 skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount) / (me.width - (me.paddingLeft + me.paddingRight))); 33815 } 33816 33817 // if they defined a max number of optionTicks, 33818 // increase skipRatio until that number is met 33819 if (maxTicks && tickCount > maxTicks) { 33820 skipRatio = Math.max(skipRatio, Math.floor(tickCount / maxTicks)); 33821 } 33822 } 33823 33824 for (i = 0; i < tickCount; i++) { 33825 tick = ticks[i]; 33826 33827 // Since we always show the last tick,we need may need to hide the last shown one before 33828 shouldSkip = (skipRatio > 1 && i % skipRatio > 0) || (i % skipRatio === 0 && i + skipRatio >= tickCount); 33829 if (shouldSkip && i !== tickCount - 1) { 33830 // leave tick in place but make sure it's not displayed (#4635) 33831 delete tick.label; 33832 } 33833 result.push(tick); 33834 } 33835 return result; 33836 }, 33837 33838 // Actually draw the scale on the canvas 33839 // @param {rectangle} chartArea : the area of the chart to draw full grid lines on 33840 draw: function(chartArea) { 33841 var me = this; 33842 var options = me.options; 33843 if (!options.display) { 33844 return; 33845 } 33846 33847 var context = me.ctx; 33848 var globalDefaults = defaults.global; 33849 var optionTicks = options.ticks.minor; 33850 var optionMajorTicks = options.ticks.major || optionTicks; 33851 var gridLines = options.gridLines; 33852 var scaleLabel = options.scaleLabel; 33853 33854 var isRotated = me.labelRotation !== 0; 33855 var isHorizontal = me.isHorizontal(); 33856 33857 var ticks = optionTicks.autoSkip ? me._autoSkip(me.getTicks()) : me.getTicks(); 33858 var tickFontColor = helpers.valueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor); 33859 var tickFont = parseFontOptions(optionTicks); 33860 var majorTickFontColor = helpers.valueOrDefault(optionMajorTicks.fontColor, globalDefaults.defaultFontColor); 33861 var majorTickFont = parseFontOptions(optionMajorTicks); 33862 33863 var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0; 33864 33865 var scaleLabelFontColor = helpers.valueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor); 33866 var scaleLabelFont = parseFontOptions(scaleLabel); 33867 var scaleLabelPadding = helpers.options.toPadding(scaleLabel.padding); 33868 var labelRotationRadians = helpers.toRadians(me.labelRotation); 33869 33870 var itemsToDraw = []; 33871 33872 var axisWidth = me.options.gridLines.lineWidth; 33873 var xTickStart = options.position === 'right' ? me.right : me.right - axisWidth - tl; 33874 var xTickEnd = options.position === 'right' ? me.right + tl : me.right; 33875 var yTickStart = options.position === 'bottom' ? me.top + axisWidth : me.bottom - tl - axisWidth; 33876 var yTickEnd = options.position === 'bottom' ? me.top + axisWidth + tl : me.bottom + axisWidth; 33877 33878 helpers.each(ticks, function(tick, index) { 33879 // autoskipper skipped this tick (#4635) 33880 if (helpers.isNullOrUndef(tick.label)) { 33881 return; 33882 } 33883 33884 var label = tick.label; 33885 var lineWidth, lineColor, borderDash, borderDashOffset; 33886 if (index === me.zeroLineIndex && options.offset === gridLines.offsetGridLines) { 33887 // Draw the first index specially 33888 lineWidth = gridLines.zeroLineWidth; 33889 lineColor = gridLines.zeroLineColor; 33890 borderDash = gridLines.zeroLineBorderDash; 33891 borderDashOffset = gridLines.zeroLineBorderDashOffset; 33892 } else { 33893 lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, index); 33894 lineColor = helpers.valueAtIndexOrDefault(gridLines.color, index); 33895 borderDash = helpers.valueOrDefault(gridLines.borderDash, globalDefaults.borderDash); 33896 borderDashOffset = helpers.valueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset); 33897 } 33898 33899 // Common properties 33900 var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY; 33901 var textAlign = 'middle'; 33902 var textBaseline = 'middle'; 33903 var tickPadding = optionTicks.padding; 33904 33905 if (isHorizontal) { 33906 var labelYOffset = tl + tickPadding; 33907 33908 if (options.position === 'bottom') { 33909 // bottom 33910 textBaseline = !isRotated ? 'top' : 'middle'; 33911 textAlign = !isRotated ? 'center' : 'right'; 33912 labelY = me.top + labelYOffset; 33913 } else { 33914 // top 33915 textBaseline = !isRotated ? 'bottom' : 'middle'; 33916 textAlign = !isRotated ? 'center' : 'left'; 33917 labelY = me.bottom - labelYOffset; 33918 } 33919 33920 var xLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1); 33921 if (xLineValue < me.left) { 33922 lineColor = 'rgba(0,0,0,0)'; 33923 } 33924 xLineValue += helpers.aliasPixel(lineWidth); 33925 33926 labelX = me.getPixelForTick(index) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option) 33927 33928 tx1 = tx2 = x1 = x2 = xLineValue; 33929 ty1 = yTickStart; 33930 ty2 = yTickEnd; 33931 y1 = chartArea.top; 33932 y2 = chartArea.bottom + axisWidth; 33933 } else { 33934 var isLeft = options.position === 'left'; 33935 var labelXOffset; 33936 33937 if (optionTicks.mirror) { 33938 textAlign = isLeft ? 'left' : 'right'; 33939 labelXOffset = tickPadding; 33940 } else { 33941 textAlign = isLeft ? 'right' : 'left'; 33942 labelXOffset = tl + tickPadding; 33943 } 33944 33945 labelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset; 33946 33947 var yLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1); 33948 if (yLineValue < me.top) { 33949 lineColor = 'rgba(0,0,0,0)'; 33950 } 33951 yLineValue += helpers.aliasPixel(lineWidth); 33952 33953 labelY = me.getPixelForTick(index) + optionTicks.labelOffset; 33954 33955 tx1 = xTickStart; 33956 tx2 = xTickEnd; 33957 x1 = chartArea.left; 33958 x2 = chartArea.right + axisWidth; 33959 ty1 = ty2 = y1 = y2 = yLineValue; 33960 } 33961 33962 itemsToDraw.push({ 33963 tx1: tx1, 33964 ty1: ty1, 33965 tx2: tx2, 33966 ty2: ty2, 33967 x1: x1, 33968 y1: y1, 33969 x2: x2, 33970 y2: y2, 33971 labelX: labelX, 33972 labelY: labelY, 33973 glWidth: lineWidth, 33974 glColor: lineColor, 33975 glBorderDash: borderDash, 33976 glBorderDashOffset: borderDashOffset, 33977 rotation: -1 * labelRotationRadians, 33978 label: label, 33979 major: tick.major, 33980 textBaseline: textBaseline, 33981 textAlign: textAlign 33982 }); 33983 }); 33984 33985 // Draw all of the tick labels, tick marks, and grid lines at the correct places 33986 helpers.each(itemsToDraw, function(itemToDraw) { 33987 if (gridLines.display) { 33988 context.save(); 33989 context.lineWidth = itemToDraw.glWidth; 33990 context.strokeStyle = itemToDraw.glColor; 33991 if (context.setLineDash) { 33992 context.setLineDash(itemToDraw.glBorderDash); 33993 context.lineDashOffset = itemToDraw.glBorderDashOffset; 33994 } 33995 33996 context.beginPath(); 33997 33998 if (gridLines.drawTicks) { 33999 context.moveTo(itemToDraw.tx1, itemToDraw.ty1); 34000 context.lineTo(itemToDraw.tx2, itemToDraw.ty2); 34001 } 34002 34003 if (gridLines.drawOnChartArea) { 34004 context.moveTo(itemToDraw.x1, itemToDraw.y1); 34005 context.lineTo(itemToDraw.x2, itemToDraw.y2); 34006 } 34007 34008 context.stroke();
34009 context.restore(); 34010 } 34011 34012 if (optionTicks.display) { 34013 // Make sure we draw text in the correct color and font 34014 context.save(); 34015 context.translate(itemToDraw.labelX, itemToDraw.labelY); 34016 context.rotate(itemToDraw.rotation); 34017 context.font = itemToDraw.major ? majorTickFont.font : tickFont.font; 34018 context.fillStyle = itemToDraw.major ? majorTickFontColor : tickFontColor; 34019 context.textBaseline = itemToDraw.textBaseline; 34020 context.textAlign = itemToDraw.textAlign; 34021 34022 var label = itemToDraw.label; 34023 if (helpers.isArray(label)) { 34024 var lineCount = label.length; 34025 var lineHeight = tickFont.size * 1.5; 34026 var y = me.isHorizontal() ? 0 : -lineHeight * (lineCount - 1) / 2; 34027 34028 for (var i = 0; i < lineCount; ++i) { 34029 // We just make sure the multiline element is a string here.. 34030 context.fillText('' + label[i], 0, y); 34031 // apply same lineSpacing as calculated @ L#320 34032 y += lineHeight; 34033 } 34034 } else { 34035 context.fillText(label, 0, 0); 34036 } 34037 context.restore(); 34038 } 34039 }); 34040 34041 if (scaleLabel.display) { 34042 // Draw the scale label 34043 var scaleLabelX; 34044 var scaleLabelY; 34045 var rotation = 0; 34046 var halfLineHeight = parseLineHeight(scaleLabel) / 2; 34047 34048 if (isHorizontal) { 34049 scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width 34050 scaleLabelY = options.position === 'bottom' 34051 ? me.bottom - halfLineHeight - scaleLabelPadding.bottom 34052 : me.top + halfLineHeight + scaleLabelPadding.top; 34053 } else { 34054 var isLeft = options.position === 'left'; 34055 scaleLabelX = isLeft 34056 ? me.left + halfLineHeight + scaleLabelPadding.top 34057 : me.right - halfLineHeight - scaleLabelPadding.top; 34058 scaleLabelY = me.top + ((me.bottom - me.top) / 2); 34059 rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI; 34060 } 34061 34062 context.save(); 34063 context.translate(scaleLabelX, scaleLabelY); 34064 context.rotate(rotation); 34065 context.textAlign = 'center'; 34066 context.textBaseline = 'middle'; 34067 context.fillStyle = scaleLabelFontColor; // render in correct colour 34068 context.font = scaleLabelFont.font;
34069 context.fillText(scaleLabel.labelString, 0, 0); 34070 context.restore(); 34071 } 34072 34073 if (gridLines.drawBorder) { 34074 // Draw the line at the edge of the axis 34075 context.lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, 0); 34076 context.strokeStyle = helpers.valueAtIndexOrDefault(gridLines.color, 0); 34077 var x1 = me.left; 34078 var x2 = me.right + axisWidth; 34079 var y1 = me.top; 34080 var y2 = me.bottom + axisWidth; 34081 34082 var aliasPixel = helpers.aliasPixel(context.lineWidth); 34083 if (isHorizontal) { 34084 y1 = y2 = options.position === 'top' ? me.bottom : me.top; 34085 y1 += aliasPixel; 34086 y2 += aliasPixel; 34087 } else { 34088 x1 = x2 = options.position === 'left' ? me.right : me.left; 34089 x1 += aliasPixel; 34090 x2 += aliasPixel; 34091 } 34092 34093 context.beginPath(); 34094 context.moveTo(x1, y1); 34095 context.lineTo(x2, y2); 34096 context.stroke(); 34097 } 34098 } 34099 }); 34100}; 34101 34102},{"25":25,"26":26,"34":34,"45":45}],33:[function(require,module,exports){ 34103'use strict'; 34104 34105var defaults = require(25); 34106var helpers = require(45); 34107var layouts = require(30); 34108 34109module.exports = function(Chart) { 34110 34111 Chart.scaleService = { 34112 // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then 34113 // use the new chart options to grab the correct scale 34114 constructors: {}, 34115 // Use a registration function so that we can move to an ES6 map when we no longer need to support 34116 // old browsers 34117 34118 // Scale config defaults 34119 defaults: {}, 34120 registerScaleType: function(type, scaleConstructor, scaleDefaults) { 34121 this.constructors[type] = scaleConstructor; 34122 this.defaults[type] = helpers.clone(scaleDefaults); 34123 }, 34124 getScaleConstructor: function(type) { 34125 return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined; 34126 }, 34127 getScaleDefaults: function(type) { 34128 // Return the scale defaults merged with the global settings so that we always use the latest ones 34129 return this.defaults.hasOwnProperty(type) ? helpers.merge({}, [defaults.scale, this.defaults[type]]) : {}; 34130 }, 34131 updateScaleDefaults: function(type, additions) { 34132 var me = this; 34133 if (me.defaults.hasOwnProperty(type)) { 34134 me.defaults[type] = helpers.extend(me.defaults[type], additions); 34135 } 34136 }, 34137 addScalesToLayout: function(chart) { 34138 // Adds each scale to the chart.boxes array to be sized accordingly 34139 helpers.each(chart.scales, function(scale) { 34140 // Set ILayoutItem parameters for backwards compatibility 34141 scale.fullWidth = scale.options.fullWidth; 34142 scale.position = scale.options.position; 34143 scale.weight = scale.options.weight; 34144 layouts.addBox(chart, scale); 34145 }); 34146 } 34147 }; 34148}; 34149 34150},{"25":25,"30":30,"45":45}],34:[function(require,module,exports){ 34151'use strict'; 34152 34153var helpers = require(45); 34154 34155/** 34156 * Namespace to hold static tick generation functions 34157 * @namespace Chart.Ticks 34158 */ 34159module.exports = { 34160 /** 34161 * Namespace to hold formatters for different types of ticks 34162 * @namespace Chart.Ticks.formatters 34163 */ 34164 formatters: { 34165 /** 34166 * Formatter for value labels 34167 * @method Chart.Ticks.formatters.values 34168 * @param value the value to display 34169 * @return {String|Array} the label to display 34170 */ 34171 values: function(value) { 34172 return helpers.isArray(value) ? value : '' + value; 34173 }, 34174 34175 /** 34176 * Formatter for linear numeric ticks 34177 * @method Chart.Ticks.formatters.linear 34178 * @param tickValue {Number} the value to be formatted 34179 * @param index {Number} the position of the tickValue parameter in the ticks array 34180 * @param ticks {Array<Number>} the list of ticks being converted 34181 * @return {String} string representation of the tickValue parameter 34182 */ 34183 linear: function(tickValue, index, ticks) { 34184 // If we have lots of ticks, don't use the ones 34185 var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0]; 34186 34187 // If we have a number like 2.5 as the delta, figure out how many decimal places we need 34188 if (Math.abs(delta) > 1) { 34189 if (tickValue !== Math.floor(tickValue)) { 34190 // not an integer 34191 delta = tickValue - Math.floor(tickValue); 34192 } 34193 } 34194 34195 var logDelta = helpers.log10(Math.abs(delta)); 34196 var tickString = ''; 34197 34198 if (tickValue !== 0) { 34199 var numDecimal = -1 * Math.floor(logDelta); 34200 numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places 34201 tickString = tickValue.toFixed(numDecimal); 34202 } else { 34203 tickString = '0'; // never show decimal places for 0 34204 } 34205 34206 return tickString; 34207 }, 34208 34209 logarithmic: function(tickValue, index, ticks) { 34210 var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue)))); 34211 34212 if (tickValue === 0) { 34213 return '0'; 34214 } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) { 34215 return tickValue.toExponential(); 34216 } 34217 return ''; 34218 } 34219 } 34220}; 34221 34222},{"45":45}],35:[function(require,module,exports){ 34223'use strict'; 34224 34225var defaults = require(25); 34226var Element = require(26); 34227var helpers = require(45); 34228 34229defaults._set('global', { 34230 tooltips: { 34231 enabled: true, 34232 custom: null, 34233 mode: 'nearest', 34234 position: 'average', 34235 intersect: true, 34236 backgroundColor: 'rgba(0,0,0,0.8)', 34237 titleFontStyle: 'bold', 34238 titleSpacing: 2, 34239 titleMarginBottom: 6, 34240 titleFontColor: '#fff', 34241 titleAlign: 'left', 34242 bodySpacing: 2, 34243 bodyFontColor: '#fff', 34244 bodyAlign: 'left', 34245 footerFontStyle: 'bold', 34246 footerSpacing: 2, 34247 footerMarginTop: 6, 34248 footerFontColor: '#fff', 34249 footerAlign: 'left', 34250 yPadding: 6, 34251 xPadding: 6, 34252 caretPadding: 2, 34253 caretSize: 5, 34254 cornerRadius: 6,
34255 multiKeyBackground: '#fff', 34256 displayColors: true, 34257 borderColor: 'rgba(0,0,0,0)', 34258 borderWidth: 0, 34259 callbacks: { 34260 // Args are: (tooltipItems, data) 34261 beforeTitle: helpers.noop, 34262 title: function(tooltipItems, data) { 34263 // Pick first xLabel for now 34264 var title = ''; 34265 var labels = data.labels; 34266 var labelCount = labels ? labels.length : 0; 34267 34268 if (tooltipItems.length > 0) { 34269 var item = tooltipItems[0]; 34270 34271 if (item.xLabel) { 34272 title = item.xLabel; 34273 } else if (labelCount > 0 && item.index < labelCount) { 34274 title = labels[item.index]; 34275 } 34276 } 34277 34278 return title; 34279 }, 34280 afterTitle: helpers.noop, 34281 34282 // Args are: (tooltipItems, data) 34283 beforeBody: helpers.noop, 34284 34285 // Args are: (tooltipItem, data) 34286 beforeLabel: helpers.noop, 34287 label: function(tooltipItem, data) { 34288 var label = data.datasets[tooltipItem.datasetIndex].label || ''; 34289 34290 if (label) { 34291 label += ': '; 34292 } 34293 label += tooltipItem.yLabel; 34294 return label; 34295 }, 34296 labelColor: function(tooltipItem, chart) { 34297 var meta = chart.getDatasetMeta(tooltipItem.datasetIndex); 34298 var activeElement = meta.data[tooltipItem.index]; 34299 var view = activeElement._view; 34300 return { 34301 borderColor: view.borderColor, 34302 backgroundColor: view.backgroundColor 34303 }; 34304 }, 34305 labelTextColor: function() { 34306 return this._options.bodyFontColor; 34307 }, 34308 afterLabel: helpers.noop, 34309 34310 // Args are: (tooltipItems, data) 34311 afterBody: helpers.noop, 34312 34313 // Args are: (tooltipItems, data) 34314 beforeFooter: helpers.noop, 34315 footer: helpers.noop, 34316 afterFooter: helpers.noop 34317 } 34318 } 34319}); 34320 34321module.exports = function(Chart) { 34322 34323 /** 34324 * Helper method to merge the opacity into a color 34325 */
vendor: 9,332 bytes, lines 34326-34629
34326 function mergeOpacity(colorString, opacity) { 34327 var color = helpers.color(colorString); 34328 return color.alpha(opacity * color.alpha()).rgbaString(); 34329 } 34330 34331 // Helper to push or concat based on if the 2nd parameter is an array or not 34332 function pushOrConcat(base, toPush) { 34333 if (toPush) { 34334 if (helpers.isArray(toPush)) { 34335 // base = base.concat(toPush); 34336 Array.prototype.push.apply(base, toPush); 34337 } else { 34338 base.push(toPush); 34339 } 34340 } 34341 34342 return base; 34343 } 34344 34345 // Private helper to create a tooltip item model 34346 // @param element : the chart element (point, arc, bar) to create the tooltip item for 34347 // @return : new tooltip item 34348 function createTooltipItem(element) { 34349 var xScale = element._xScale; 34350 var yScale = element._yScale || element._scale; // handle radar || polarArea charts 34351 var index = element._index; 34352 var datasetIndex = element._datasetIndex; 34353 34354 return { 34355 xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '', 34356 yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '', 34357 index: index, 34358 datasetIndex: datasetIndex, 34359 x: element._model.x, 34360 y: element._model.y 34361 }; 34362 } 34363 34364 /** 34365 * Helper to get the reset model for the tooltip 34366 * @param tooltipOpts {Object} the tooltip options 34367 */ 34368 function getBaseModel(tooltipOpts) { 34369 var globalDefaults = defaults.global; 34370 var valueOrDefault = helpers.valueOrDefault; 34371 34372 return { 34373 // Positioning 34374 xPadding: tooltipOpts.xPadding, 34375 yPadding: tooltipOpts.yPadding, 34376 xAlign: tooltipOpts.xAlign, 34377 yAlign: tooltipOpts.yAlign, 34378 34379 // Body 34380 bodyFontColor: tooltipOpts.bodyFontColor, 34381 _bodyFontFamily: valueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily), 34382 _bodyFontStyle: valueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle), 34383 _bodyAlign: tooltipOpts.bodyAlign, 34384 bodyFontSize: valueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize), 34385 bodySpacing: tooltipOpts.bodySpacing, 34386 34387 // Title 34388 titleFontColor: tooltipOpts.titleFontColor, 34389 _titleFontFamily: valueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily), 34390 _titleFontStyle: valueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle), 34391 titleFontSize: valueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize), 34392 _titleAlign: tooltipOpts.titleAlign, 34393 titleSpacing: tooltipOpts.titleSpacing, 34394 titleMarginBottom: tooltipOpts.titleMarginBottom, 34395 34396 // Footer 34397 footerFontColor: tooltipOpts.footerFontColor, 34398 _footerFontFamily: valueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily), 34399 _footerFontStyle: valueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle), 34400 footerFontSize: valueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize), 34401 _footerAlign: tooltipOpts.footerAlign, 34402 footerSpacing: tooltipOpts.footerSpacing, 34403 footerMarginTop: tooltipOpts.footerMarginTop, 34404 34405 // Appearance 34406 caretSize: tooltipOpts.caretSize, 34407 cornerRadius: tooltipOpts.cornerRadius, 34408 backgroundColor: tooltipOpts.backgroundColor, 34409 opacity: 0, 34410 legendColorBackground: tooltipOpts.multiKeyBackground, 34411 displayColors: tooltipOpts.displayColors, 34412 borderColor: tooltipOpts.borderColor, 34413 borderWidth: tooltipOpts.borderWidth 34414 }; 34415 } 34416 34417 /** 34418 * Get the size of the tooltip 34419 */ 34420 function getTooltipSize(tooltip, model) { 34421 var ctx = tooltip._chart.ctx; 34422 34423 var height = model.yPadding * 2; // Tooltip Padding 34424 var width = 0; 34425 34426 // Count of all lines in the body 34427 var body = model.body; 34428 var combinedBodyLength = body.reduce(function(count, bodyItem) { 34429 return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length; 34430 }, 0); 34431 combinedBodyLength += model.beforeBody.length + model.afterBody.length; 34432 34433 var titleLineCount = model.title.length; 34434 var footerLineCount = model.footer.length; 34435 var titleFontSize = model.titleFontSize; 34436 var bodyFontSize = model.bodyFontSize; 34437 var footerFontSize = model.footerFontSize; 34438 34439 height += titleLineCount * titleFontSize; // Title Lines 34440 height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing 34441 height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin 34442 height += combinedBodyLength * bodyFontSize; // Body Lines 34443 height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing 34444 height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin 34445 height += footerLineCount * (footerFontSize); // Footer Lines 34446 height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing 34447 34448 // Title width 34449 var widthPadding = 0; 34450 var maxLineWidth = function(line) { 34451 width = Math.max(width, ctx.measureText(line).width + widthPadding); 34452 }; 34453 34454 ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily); 34455 helpers.each(model.title, maxLineWidth); 34456 34457 // Body width 34458 ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily); 34459 helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth); 34460 34461 // Body lines may include some extra width due to the color box 34462 widthPadding = model.displayColors ? (bodyFontSize + 2) : 0; 34463 helpers.each(body, function(bodyItem) { 34464 helpers.each(bodyItem.before, maxLineWidth); 34465 helpers.each(bodyItem.lines, maxLineWidth); 34466 helpers.each(bodyItem.after, maxLineWidth); 34467 }); 34468 34469 // Reset back to 0 34470 widthPadding = 0; 34471 34472 // Footer width 34473 ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily); 34474 helpers.each(model.footer, maxLineWidth); 34475 34476 // Add padding 34477 width += 2 * model.xPadding; 34478 34479 return { 34480 width: width, 34481 height: height 34482 }; 34483 } 34484 34485 /** 34486 * Helper to get the alignment of a tooltip given the size 34487 */ 34488 function determineAlignment(tooltip, size) { 34489 var model = tooltip._model; 34490 var chart = tooltip._chart; 34491 var chartArea = tooltip._chart.chartArea; 34492 var xAlign = 'center'; 34493 var yAlign = 'center'; 34494 34495 if (model.y < size.height) { 34496 yAlign = 'top'; 34497 } else if (model.y > (chart.height - size.height)) { 34498 yAlign = 'bottom'; 34499 } 34500 34501 var lf, rf; // functions to determine left, right alignment 34502 var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart 34503 var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges 34504 var midX = (chartArea.left + chartArea.right) / 2; 34505 var midY = (chartArea.top + chartArea.bottom) / 2; 34506 34507 if (yAlign === 'center') { 34508 lf = function(x) { 34509 return x <= midX; 34510 }; 34511 rf = function(x) { 34512 return x > midX; 34513 }; 34514 } else { 34515 lf = function(x) { 34516 return x <= (size.width / 2); 34517 }; 34518 rf = function(x) { 34519 return x >= (chart.width - (size.width / 2)); 34520 }; 34521 } 34522 34523 olf = function(x) { 34524 return x + size.width + model.caretSize + model.caretPadding > chart.width; 34525 }; 34526 orf = function(x) { 34527 return x - size.width - model.caretSize - model.caretPadding < 0; 34528 }; 34529 yf = function(y) { 34530 return y <= midY ? 'top' : 'bottom'; 34531 }; 34532 34533 if (lf(model.x)) { 34534 xAlign = 'left'; 34535 34536 // Is tooltip too wide and goes over the right side of the chart.? 34537 if (olf(model.x)) { 34538 xAlign = 'center'; 34539 yAlign = yf(model.y); 34540 } 34541 } else if (rf(model.x)) { 34542 xAlign = 'right'; 34543 34544 // Is tooltip too wide and goes outside left edge of canvas? 34545 if (orf(model.x)) { 34546 xAlign = 'center'; 34547 yAlign = yf(model.y); 34548 } 34549 } 34550 34551 var opts = tooltip._options; 34552 return { 34553 xAlign: opts.xAlign ? opts.xAlign : xAlign, 34554 yAlign: opts.yAlign ? opts.yAlign : yAlign 34555 }; 34556 } 34557 34558 /** 34559 * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment 34560 */ 34561 function getBackgroundPoint(vm, size, alignment, chart) { 34562 // Background Position 34563 var x = vm.x; 34564 var y = vm.y; 34565 34566 var caretSize = vm.caretSize; 34567 var caretPadding = vm.caretPadding; 34568 var cornerRadius = vm.cornerRadius; 34569 var xAlign = alignment.xAlign; 34570 var yAlign = alignment.yAlign; 34571 var paddingAndSize = caretSize + caretPadding; 34572 var radiusAndPadding = cornerRadius + caretPadding; 34573 34574 if (xAlign === 'right') { 34575 x -= size.width; 34576 } else if (xAlign === 'center') { 34577 x -= (size.width / 2); 34578 if (x + size.width > chart.width) { 34579 x = chart.width - size.width; 34580 } 34581 if (x < 0) { 34582 x = 0; 34583 } 34584 } 34585 34586 if (yAlign === 'top') { 34587 y += paddingAndSize; 34588 } else if (yAlign === 'bottom') { 34589 y -= size.height + paddingAndSize; 34590 } else { 34591 y -= (size.height / 2); 34592 } 34593 34594 if (yAlign === 'center') { 34595 if (xAlign === 'left') { 34596 x += paddingAndSize; 34597 } else if (xAlign === 'right') { 34598 x -= paddingAndSize; 34599 } 34600 } else if (xAlign === 'left') { 34601 x -= radiusAndPadding; 34602 } else if (xAlign === 'right') { 34603 x += radiusAndPadding; 34604 } 34605 34606 return { 34607 x: x, 34608 y: y 34609 }; 34610 } 34611 34612 Chart.Tooltip = Element.extend({ 34613 initialize: function() { 34614 this._model = getBaseModel(this._options); 34615 this._lastActive = []; 34616 }, 34617 34618 // Get the title 34619 // Args are: (tooltipItem, data) 34620 getTitle: function() { 34621 var me = this; 34622 var opts = me._options; 34623 var callbacks = opts.callbacks; 34624 34625 var beforeTitle = callbacks.beforeTitle.apply(me, arguments); 34626 var title = callbacks.title.apply(me, arguments); 34627 var afterTitle = callbacks.afterTitle.apply(me, arguments); 34628 34629 var lines = [];
34630 lines = pushOrConcat(lines, beforeTitle); 34631 lines = pushOrConcat(lines, title); 34632 lines = pushOrConcat(lines, afterTitle); 34633 34634 return lines; 34635 }, 34636 34637 // Args are: (tooltipItem, data) 34638 getBeforeBody: function() { 34639 var lines = this._options.callbacks.beforeBody.apply(this, arguments); 34640 return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : []; 34641 }, 34642 34643 // Args are: (tooltipItem, data) 34644 getBody: function(tooltipItems, data) { 34645 var me = this; 34646 var callbacks = me._options.callbacks; 34647 var bodyItems = []; 34648 34649 helpers.each(tooltipItems, function(tooltipItem) { 34650 var bodyItem = { 34651 before: [], 34652 lines: [], 34653 after: [] 34654 }; 34655 pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data)); 34656 pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data)); 34657 pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data)); 34658 34659 bodyItems.push(bodyItem); 34660 }); 34661 34662 return bodyItems; 34663 }, 34664 34665 // Args are: (tooltipItem, data) 34666 getAfterBody: function() { 34667 var lines = this._options.callbacks.afterBody.apply(this, arguments); 34668 return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : []; 34669 }, 34670 34671 // Get the footer and beforeFooter and afterFooter lines 34672 // Args are: (tooltipItem, data) 34673 getFooter: function() { 34674 var me = this; 34675 var callbacks = me._options.callbacks; 34676 34677 var beforeFooter = callbacks.beforeFooter.apply(me, arguments); 34678 var footer = callbacks.footer.apply(me, arguments); 34679 var afterFooter = callbacks.afterFooter.apply(me, arguments); 34680 34681 var lines = []; 34682 lines = pushOrConcat(lines, beforeFooter); 34683 lines = pushOrConcat(lines, footer); 34684 lines = pushOrConcat(lines, afterFooter); 34685 34686 return lines; 34687 }, 34688 34689 update: function(changed) { 34690 var me = this; 34691 var opts = me._options; 34692 34693 // Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition 34694 // that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time 34695 // which breaks any animations. 34696 var existingModel = me._model; 34697 var model = me._model = getBaseModel(opts); 34698 var active = me._active; 34699 34700 var data = me._data; 34701 34702 // In the case where active.length === 0 we need to keep these at existing values for good animations 34703 var alignment = { 34704 xAlign: existingModel.xAlign, 34705 yAlign: existingModel.yAlign 34706 }; 34707 var backgroundPoint = { 34708 x: existingModel.x, 34709 y: existingModel.y 34710 }; 34711 var tooltipSize = { 34712 width: existingModel.width, 34713 height: existingModel.height 34714 }; 34715 var tooltipPosition = { 34716 x: existingModel.caretX, 34717 y: existingModel.caretY 34718 }; 34719 34720 var i, len; 34721 34722 if (active.length) { 34723 model.opacity = 1; 34724 34725 var labelColors = []; 34726 var labelTextColors = []; 34727 tooltipPosition = Chart.Tooltip.positioners[opts.position].call(me, active, me._eventPosition); 34728 34729 var tooltipItems = []; 34730 for (i = 0, len = active.length; i < len; ++i) { 34731 tooltipItems.push(createTooltipItem(active[i])); 34732 } 34733 34734 // If the user provided a filter function, use it to modify the tooltip items 34735 if (opts.filter) { 34736 tooltipItems = tooltipItems.filter(function(a) { 34737 return opts.filter(a, data); 34738 }); 34739 } 34740 34741 // If the user provided a sorting function, use it to modify the tooltip items 34742 if (opts.itemSort) { 34743 tooltipItems = tooltipItems.sort(function(a, b) { 34744 return opts.itemSort(a, b, data); 34745 }); 34746 } 34747 34748 // Determine colors for boxes 34749 helpers.each(tooltipItems, function(tooltipItem) { 34750 labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart)); 34751 labelTextColors.push(opts.callbacks.labelTextColor.call(me, tooltipItem, me._chart)); 34752 }); 34753 34754 34755 // Build the Text Lines 34756 model.title = me.getTitle(tooltipItems, data); 34757 model.beforeBody = me.getBeforeBody(tooltipItems, data); 34758 model.body = me.getBody(tooltipItems, data); 34759 model.afterBody = me.getAfterBody(tooltipItems, data); 34760 model.footer = me.getFooter(tooltipItems, data); 34761 34762 // Initial positioning and colors 34763 model.x = Math.round(tooltipPosition.x); 34764 model.y = Math.round(tooltipPosition.y); 34765 model.caretPadding = opts.caretPadding; 34766 model.labelColors = labelColors; 34767 model.labelTextColors = labelTextColors; 34768 34769 // data points 34770 model.dataPoints = tooltipItems; 34771 34772 // We need to determine alignment of the tooltip 34773 tooltipSize = getTooltipSize(this, model); 34774 alignment = determineAlignment(this, tooltipSize); 34775 // Final Size and Position
34776 backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment, me._chart); 34777 } else { 34778 model.opacity = 0; 34779 } 34780 34781 model.xAlign = alignment.xAlign; 34782 model.yAlign = alignment.yAlign; 34783 model.x = backgroundPoint.x; 34784 model.y = backgroundPoint.y; 34785 model.width = tooltipSize.width; 34786 model.height = tooltipSize.height; 34787 34788 // Point where the caret on the tooltip points to 34789 model.caretX = tooltipPosition.x; 34790 model.caretY = tooltipPosition.y; 34791 34792 me._model = model; 34793 34794 if (changed && opts.custom) { 34795 opts.custom.call(me, model); 34796 } 34797 34798 return me; 34799 }, 34800 drawCaret: function(tooltipPoint, size) { 34801 var ctx = this._chart.ctx; 34802 var vm = this._view; 34803 var caretPosition = this.getCaretPosition(tooltipPoint, size, vm); 34804 34805 ctx.lineTo(caretPosition.x1, caretPosition.y1); 34806 ctx.lineTo(caretPosition.x2, caretPosition.y2); 34807 ctx.lineTo(caretPosition.x3, caretPosition.y3); 34808 }, 34809 getCaretPosition: function(tooltipPoint, size, vm) { 34810 var x1, x2, x3, y1, y2, y3; 34811 var caretSize = vm.caretSize; 34812 var cornerRadius = vm.cornerRadius; 34813 var xAlign = vm.xAlign; 34814 var yAlign = vm.yAlign; 34815 var ptX = tooltipPoint.x; 34816 var ptY = tooltipPoint.y; 34817 var width = size.width; 34818 var height = size.height; 34819 34820 if (yAlign === 'center') { 34821 y2 = ptY + (height / 2); 34822 34823 if (xAlign === 'left') { 34824 x1 = ptX; 34825 x2 = x1 - caretSize; 34826 x3 = x1; 34827 34828 y1 = y2 + caretSize; 34829 y3 = y2 - caretSize; 34830 } else { 34831 x1 = ptX + width; 34832 x2 = x1 + caretSize; 34833 x3 = x1; 34834 34835 y1 = y2 - caretSize; 34836 y3 = y2 + caretSize; 34837 } 34838 } else { 34839 if (xAlign === 'left') { 34840 x2 = ptX + cornerRadius + (caretSize); 34841 x1 = x2 - caretSize; 34842 x3 = x2 + caretSize; 34843 } else if (xAlign === 'right') { 34844 x2 = ptX + width - cornerRadius - caretSize; 34845 x1 = x2 - caretSize; 34846 x3 = x2 + caretSize; 34847 } else { 34848 x2 = vm.caretX; 34849 x1 = x2 - caretSize; 34850 x3 = x2 + caretSize; 34851 } 34852 if (yAlign === 'top') { 34853 y1 = ptY; 34854 y2 = y1 - caretSize; 34855 y3 = y1; 34856 } else { 34857 y1 = ptY + height; 34858 y2 = y1 + caretSize; 34859 y3 = y1; 34860 // invert drawing order 34861 var tmp = x3; 34862 x3 = x1; 34863 x1 = tmp; 34864 } 34865 } 34866 return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3}; 34867 }, 34868 drawTitle: function(pt, vm, ctx, opacity) { 34869 var title = vm.title; 34870 34871 if (title.length) { 34872 ctx.textAlign = vm._titleAlign; 34873 ctx.textBaseline = 'top'; 34874 34875 var titleFontSize = vm.titleFontSize; 34876 var titleSpacing = vm.titleSpacing; 34877 34878 ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity); 34879 ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily); 34880 34881 var i, len; 34882 for (i = 0, len = title.length; i < len; ++i) { 34883 ctx.fillText(title[i], pt.x, pt.y); 34884 pt.y += titleFontSize + titleSpacing; // Line Height and spacing 34885 34886 if (i + 1 === title.length) { 34887 pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing 34888 } 34889 } 34890 } 34891 }, 34892 drawBody: function(pt, vm, ctx, opacity) { 34893 var bodyFontSize = vm.bodyFontSize; 34894 var bodySpacing = vm.bodySpacing; 34895 var body = vm.body; 34896 34897 ctx.textAlign = vm._bodyAlign; 34898 ctx.textBaseline = 'top'; 34899 ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily); 34900 34901 // Before Body 34902 var xLinePadding = 0; 34903 var fillLineOfText = function(line) { 34904 ctx.fillText(line, pt.x + xLinePadding, pt.y); 34905 pt.y += bodyFontSize + bodySpacing; 34906 }; 34907 34908 // Before body lines 34909 ctx.fillStyle = mergeOpacity(vm.bodyFontColor, opacity); 34910 helpers.each(vm.beforeBody, fillLineOfText); 34911 34912 var drawColorBoxes = vm.displayColors; 34913 xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0; 34914 34915 // Draw body lines now 34916 helpers.each(body, function(bodyItem, i) { 34917 var textColor = mergeOpacity(vm.labelTextColors[i], opacity); 34918 ctx.fillStyle = textColor; 34919 helpers.each(bodyItem.before, fillLineOfText); 34920 34921 helpers.each(bodyItem.lines, function(line) { 34922 // Draw Legend-like boxes if needed 34923 if (drawColorBoxes) { 34924 // Fill a white rect so that colours merge nicely if the opacity is < 1
34925 ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity); 34926 ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize); 34927 34928 // Border 34929 ctx.lineWidth = 1; 34930 ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity); 34931 ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize); 34932 34933 // Inner square 34934 ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity); 34935 ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2); 34936 ctx.fillStyle = textColor; 34937 } 34938 34939 fillLineOfText(line); 34940 }); 34941 34942 helpers.each(bodyItem.after, fillLineOfText); 34943 }); 34944 34945 // Reset back to 0 for after body 34946 xLinePadding = 0; 34947 34948 // After body lines 34949 helpers.each(vm.afterBody, fillLineOfText); 34950 pt.y -= bodySpacing; // Remove last body spacing 34951 }, 34952 drawFooter: function(pt, vm, ctx, opacity) { 34953 var footer = vm.footer; 34954 34955 if (footer.length) { 34956 pt.y += vm.footerMarginTop; 34957 34958 ctx.textAlign = vm._footerAlign; 34959 ctx.textBaseline = 'top'; 34960 34961 ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity); 34962 ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily); 34963 34964 helpers.each(footer, function(line) { 34965 ctx.fillText(line, pt.x, pt.y); 34966 pt.y += vm.footerFontSize + vm.footerSpacing; 34967 }); 34968 } 34969 }, 34970 drawBackground: function(pt, vm, ctx, tooltipSize, opacity) { 34971 ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity); 34972 ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity); 34973 ctx.lineWidth = vm.borderWidth; 34974 var xAlign = vm.xAlign; 34975 var yAlign = vm.yAlign; 34976 var x = pt.x; 34977 var y = pt.y; 34978 var width = tooltipSize.width; 34979 var height = tooltipSize.height; 34980 var radius = vm.cornerRadius; 34981 34982 ctx.beginPath(); 34983 ctx.moveTo(x + radius, y); 34984 if (yAlign === 'top') { 34985 this.drawCaret(pt, tooltipSize); 34986 } 34987 ctx.lineTo(x + width - radius, y); 34988 ctx.quadraticCurveTo(x + width, y, x + width, y + radius); 34989 if (yAlign === 'center' && xAlign === 'right') { 34990 this.drawCaret(pt, tooltipSize); 34991 } 34992 ctx.lineTo(x + width, y + height - radius); 34993 ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); 34994 if (yAlign === 'bottom') { 34995 this.drawCaret(pt, tooltipSize); 34996 } 34997 ctx.lineTo(x + radius, y + height); 34998 ctx.quadraticCurveTo(x, y + height, x, y + height - radius); 34999 if (yAlign === 'center' && xAlign === 'left') { 35000 this.drawCaret(pt, tooltipSize); 35001 } 35002 ctx.lineTo(x, y + radius); 35003 ctx.quadraticCurveTo(x, y, x + radius, y); 35004 ctx.closePath(); 35005 35006 ctx.fill(); 35007 35008 if (vm.borderWidth > 0) { 35009 ctx.stroke(); 35010 } 35011 }, 35012 draw: function() { 35013 var ctx = this._chart.ctx; 35014 var vm = this._view; 35015 35016 if (vm.opacity === 0) { 35017 return; 35018 } 35019 35020 var tooltipSize = { 35021 width: vm.width, 35022 height: vm.height 35023 }; 35024 var pt = { 35025 x: vm.x, 35026 y: vm.y 35027 }; 35028 35029 // IE11/Edge does not like very small opacities, so snap to 0 35030 var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity; 35031 35032 // Truthy/falsey value for empty tooltip 35033 var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length; 35034 35035 if (this._options.enabled && hasTooltipContent) { 35036 // Draw Background 35037 this.drawBackground(pt, vm, ctx, tooltipSize, opacity); 35038 35039 // Draw Title, Body, and Footer 35040 pt.x += vm.xPadding; 35041 pt.y += vm.yPadding; 35042 35043 // Titles 35044 this.drawTitle(pt, vm, ctx, opacity); 35045 35046 // Body 35047 this.drawBody(pt, vm, ctx, opacity); 35048 35049 // Footer 35050 this.drawFooter(pt, vm, ctx, opacity); 35051 } 35052 }, 35053 35054 /** 35055 * Handle an event 35056 * @private 35057 * @param {IEvent} event - The event to handle 35058 * @returns {Boolean} true if the tooltip changed 35059 */ 35060 handleEvent: function(e) { 35061 var me = this; 35062 var options = me._options; 35063 var changed = false; 35064 35065 me._lastActive = me._lastActive || []; 35066 35067 // Find Active Elements for tooltips 35068 if (e.type === 'mouseout') { 35069 me._active = []; 35070 } else { 35071 me._active = me._chart.getElementsAtEventForMode(e, options.mode, options); 35072 } 35073 35074 // Remember Last Actives 35075 changed = !helpers.arrayEquals(me._active, me._lastActive); 35076 35077 // Only handle target event on tooltip change 35078 if (changed) { 35079 me._lastActive = me._active; 35080 35081 if (options.enabled || options.custom) { 35082 me._eventPosition = { 35083 x: e.x, 35084 y: e.y 35085 }; 35086 35087 me.update(true); 35088 me.pivot(); 35089 } 35090 } 35091 35092 return changed; 35093 } 35094 }); 35095 35096 /** 35097 * @namespace Chart.Tooltip.positioners 35098 */ 35099 Chart.Tooltip.positioners = { 35100 /** 35101 * Average mode places the tooltip at the average position of the elements shown 35102 * @function Chart.Tooltip.positioners.average 35103 * @param elements {ChartElement[]} the elements being displayed in the tooltip 35104 * @returns {Point} tooltip position 35105 */ 35106 average: function(elements) { 35107 if (!elements.length) { 35108 return false;
35109 } 35110 35111 var i, len; 35112 var x = 0; 35113 var y = 0; 35114 var count = 0; 35115 35116 for (i = 0, len = elements.length; i < len; ++i) { 35117 var el = elements[i]; 35118 if (el && el.hasValue()) { 35119 var pos = el.tooltipPosition(); 35120 x += pos.x; 35121 y += pos.y; 35122 ++count; 35123 } 35124 } 35125 35126 return { 35127 x: Math.round(x / count), 35128 y: Math.round(y / count) 35129 }; 35130 }, 35131 35132 /** 35133 * Gets the tooltip position nearest of the item nearest to the event position 35134 * @function Chart.Tooltip.positioners.nearest 35135 * @param elements {Chart.Element[]} the tooltip elements 35136 * @param eventPosition {Point} the position of the event in canvas coordinates 35137 * @returns {Point} the tooltip position 35138 */ 35139 nearest: function(elements, eventPosition) { 35140 var x = eventPosition.x; 35141 var y = eventPosition.y; 35142 var minDistance = Number.POSITIVE_INFINITY; 35143 var i, len, nearestElement; 35144 35145 for (i = 0, len = elements.length; i < len; ++i) { 35146 var el = elements[i]; 35147 if (el && el.hasValue()) { 35148 var center = el.getCenterPoint(); 35149 var d = helpers.distanceBetweenPoints(eventPosition, center); 35150 35151 if (d < minDistance) { 35152 minDistance = d; 35153 nearestElement = el; 35154 } 35155 } 35156 } 35157 35158 if (nearestElement) { 35159 var tp = nearestElement.tooltipPosition(); 35160 x = tp.x; 35161 y = tp.y; 35162 } 35163 35164 return { 35165 x: x, 35166 y: y 35167 }; 35168 } 35169 }; 35170}; 35171 35172},{"25":25,"26":26,"45":45}],36:[function(require,module,exports){ 35173'use strict'; 35174 35175var defaults = require(25); 35176var Element = require(26); 35177var helpers = require(45); 35178 35179defaults._set('global', { 35180 elements: { 35181 arc: { 35182 backgroundColor: defaults.global.defaultColor, 35183 borderColor: '#fff', 35184 borderWidth: 2 35185 } 35186 } 35187}); 35188 35189module.exports = Element.extend({ 35190 inLabelRange: function(mouseX) { 35191 var vm = this._view; 35192 35193 if (vm) { 35194 return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); 35195 } 35196 return false; 35197 }, 35198 35199 inRange: function(chartX, chartY) { 35200 var vm = this._view; 35201 35202 if (vm) { 35203 var pointRelativePosition = helpers.getAngleFromPoint(vm, {x: chartX, y: chartY}); 35204 var angle = pointRelativePosition.angle; 35205 var distance = pointRelativePosition.distance; 35206 35207 // Sanitise angle range 35208 var startAngle = vm.startAngle; 35209 var endAngle = vm.endAngle; 35210 while (endAngle < startAngle) { 35211 endAngle += 2.0 * Math.PI; 35212 } 35213 while (angle > endAngle) { 35214 angle -= 2.0 * Math.PI; 35215 } 35216 while (angle < startAngle) { 35217 angle += 2.0 * Math.PI; 35218 } 35219 35220 // Check if within the range of the open/close angle 35221 var betweenAngles = (angle >= startAngle && angle <= endAngle); 35222 var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius); 35223 35224 return (betweenAngles && withinRadius); 35225 } 35226 return false; 35227 }, 35228 35229 getCenterPoint: function() { 35230 var vm = this._view; 35231 var halfAngle = (vm.startAngle + vm.endAngle) / 2; 35232 var halfRadius = (vm.innerRadius + vm.outerRadius) / 2; 35233 return { 35234 x: vm.x + Math.cos(halfAngle) * halfRadius, 35235 y: vm.y + Math.sin(halfAngle) * halfRadius 35236 }; 35237 }, 35238 35239 getArea: function() { 35240 var vm = this._view; 35241 return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2)); 35242 }, 35243 35244 tooltipPosition: function() { 35245 var vm = this._view; 35246 var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2); 35247 var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius; 35248 35249 return { 35250 x: vm.x + (Math.cos(centreAngle) * rangeFromCentre), 35251 y: vm.y + (Math.sin(centreAngle) * rangeFromCentre) 35252 }; 35253 }, 35254 35255 draw: function() { 35256 var ctx = this._chart.ctx; 35257 var vm = this._view; 35258 var sA = vm.startAngle; 35259 var eA = vm.endAngle; 35260 35261 ctx.beginPath(); 35262 35263 ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA); 35264 ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true); 35265 35266 ctx.closePath(); 35267 ctx.strokeStyle = vm.borderColor; 35268 ctx.lineWidth = vm.borderWidth; 35269 35270 ctx.fillStyle = vm.backgroundColor; 35271 35272 ctx.fill(); 35273 ctx.lineJoin = 'bevel'; 35274 35275 if (vm.borderWidth) { 35276 ctx.stroke(); 35277 } 35278 } 35279}); 35280 35281},{"25":25,"26":26,"45":45}],37:[function(require,module,exports){ 35282'use strict'; 35283 35284var defaults = require(25); 35285var Element = require(26); 35286var helpers = require(45); 35287 35288var globalDefaults = defaults.global; 35289 35290defaults._set('global', { 35291 elements: { 35292 line: { 35293 tension: 0.4, 35294 backgroundColor: globalDefaults.defaultColor, 35295 borderWidth: 3, 35296 borderColor: globalDefaults.defaultColor, 35297 borderCapStyle: 'butt', 35298 borderDash: [], 35299 borderDashOffset: 0.0, 35300 borderJoinStyle: 'miter', 35301 capBezierPoints: true, 35302 fill: true, // do we fill in the area between the line and its base axis 35303 } 35304 } 35305}); 35306 35307module.exports = Element.extend({ 35308 draw: function() { 35309 var me = this; 35310 var vm = me._view; 35311 var ctx = me._chart.ctx; 35312 var spanGaps = vm.spanGaps; 35313 var points = me._children.slice(); // clone array 35314 var globalOptionLineElements = globalDefaults.elements.line; 35315 var lastDrawnIndex = -1; 35316 var index, current, previous, currentVM; 35317 35318 // If we are looping, adding the first point again 35319 if (me._loop && points.length) { 35320 points.push(points[0]); 35321 } 35322 35323 ctx.save(); 35324 35325 // Stroke Line Options 35326 ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; 35327 35328 // IE 9 and 10 do not support line dash 35329 if (ctx.setLineDash) { 35330 ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash); 35331 } 35332 35333 ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset; 35334 ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; 35335 ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth; 35336 ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; 35337 35338 // Stroke Line
35339 ctx.beginPath(); 35340 lastDrawnIndex = -1; 35341 35342 for (index = 0; index < points.length; ++index) { 35343 current = points[index]; 35344 previous = helpers.previousItem(points, index); 35345 currentVM = current._view; 35346 35347 // First point moves to it's starting position no matter what 35348 if (index === 0) { 35349 if (!currentVM.skip) { 35350 ctx.moveTo(currentVM.x, currentVM.y); 35351 lastDrawnIndex = index; 35352 } 35353 } else { 35354 previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex]; 35355 35356 if (!currentVM.skip) { 35357 if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) { 35358 // There was a gap and this is the first point after the gap 35359 ctx.moveTo(currentVM.x, currentVM.y); 35360 } else { 35361 // Line to next point 35362 helpers.canvas.lineTo(ctx, previous._view, current._view); 35363 } 35364 lastDrawnIndex = index; 35365 } 35366 } 35367 } 35368 35369 ctx.stroke(); 35370 ctx.restore(); 35371 } 35372}); 35373 35374},{"25":25,"26":26,"45":45}],38:[function(require,module,exports){ 35375'use strict'; 35376 35377var defaults = require(25); 35378var Element = require(26); 35379var helpers = require(45); 35380 35381var defaultColor = defaults.global.defaultColor; 35382 35383defaults._set('global', { 35384 elements: { 35385 point: { 35386 radius: 3, 35387 pointStyle: 'circle', 35388 backgroundColor: defaultColor, 35389 borderColor: defaultColor, 35390 borderWidth: 1, 35391 // Hover 35392 hitRadius: 1, 35393 hoverRadius: 4, 35394 hoverBorderWidth: 1 35395 } 35396 } 35397}); 35398 35399function xRange(mouseX) { 35400 var vm = this._view; 35401 return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false; 35402} 35403 35404function yRange(mouseY) { 35405 var vm = this._view; 35406 return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false; 35407} 35408 35409module.exports = Element.extend({ 35410 inRange: function(mouseX, mouseY) { 35411 var vm = this._view; 35412 return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false; 35413 }, 35414 35415 inLabelRange: xRange, 35416 inXRange: xRange, 35417 inYRange: yRange, 35418 35419 getCenterPoint: function() { 35420 var vm = this._view; 35421 return { 35422 x: vm.x, 35423 y: vm.y 35424 }; 35425 }, 35426 35427 getArea: function() { 35428 return Math.PI * Math.pow(this._view.radius, 2); 35429 }, 35430 35431 tooltipPosition: function() { 35432 var vm = this._view; 35433 return { 35434 x: vm.x, 35435 y: vm.y, 35436 padding: vm.radius + vm.borderWidth 35437 }; 35438 }, 35439 35440 draw: function(chartArea) { 35441 var vm = this._view; 35442 var model = this._model; 35443 var ctx = this._chart.ctx; 35444 var pointStyle = vm.pointStyle; 35445 var radius = vm.radius; 35446 var x = vm.x; 35447 var y = vm.y; 35448 var color = helpers.color; 35449 var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.) 35450 var ratio = 0; 35451 35452 if (vm.skip) { 35453 return; 35454 } 35455 35456 ctx.strokeStyle = vm.borderColor || defaultColor; 35457 ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth); 35458 ctx.fillStyle = vm.backgroundColor || defaultColor; 35459 35460 // Cliping for Points. 35461 // going out from inner charArea? 35462 if ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right * errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom * errMargin < model.y))) { 35463 // Point fade out 35464 if (model.x < chartArea.left) { 35465 ratio = (x - model.x) / (chartArea.left - model.x); 35466 } else if (chartArea.right * errMargin < model.x) { 35467 ratio = (model.x - x) / (model.x - chartArea.right); 35468 } else if (model.y < chartArea.top) { 35469 ratio = (y - model.y) / (chartArea.top - model.y); 35470 } else if (chartArea.bottom * errMargin < model.y) { 35471 ratio = (model.y - y) / (model.y - chartArea.bottom); 35472 } 35473 ratio = Math.round(ratio * 100) / 100; 35474 ctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString(); 35475 ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString(); 35476 } 35477 35478 helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y); 35479 } 35480}); 35481 35482},{"25":25,"26":26,"45":45}],39:[function(require,module,exports){ 35483'use strict'; 35484 35485var defaults = require(25); 35486var Element = require(26); 35487 35488defaults._set('global', { 35489 elements: { 35490 rectangle: { 35491 backgroundColor: defaults.global.defaultColor, 35492 borderColor: defaults.global.defaultColor, 35493 borderSkipped: 'bottom', 35494 borderWidth: 0 35495 } 35496 } 35497}); 35498 35499function isVertical(bar) { 35500 return bar._view.width !== undefined; 35501} 35502 35503/** 35504 * Helper function to get the bounds of the bar regardless of the orientation 35505 * @param bar {Chart.Element.Rectangle} the bar 35506 * @return {Bounds} bounds of the bar 35507 * @private 35508 */ 35509function getBarBounds(bar) { 35510 var vm = bar._view; 35511 var x1, x2, y1, y2; 35512 35513 if (isVertical(bar)) { 35514 // vertical 35515 var halfWidth = vm.width / 2; 35516 x1 = vm.x - halfWidth; 35517 x2 = vm.x + halfWidth; 35518 y1 = Math.min(vm.y, vm.base); 35519 y2 = Math.max(vm.y, vm.base); 35520 } else { 35521 // horizontal bar 35522 var halfHeight = vm.height / 2; 35523 x1 = Math.min(vm.x, vm.base); 35524 x2 = Math.max(vm.x, vm.base); 35525 y1 = vm.y - halfHeight; 35526 y2 = vm.y + halfHeight; 35527 } 35528 35529 return { 35530 left: x1, 35531 top: y1, 35532 right: x2, 35533 bottom: y2 35534 }; 35535} 35536 35537module.exports = Element.extend({ 35538 draw: function() { 35539 var ctx = this._chart.ctx; 35540 var vm = this._view; 35541 var left, right, top, bottom, signX, signY, borderSkipped; 35542 var borderWidth = vm.borderWidth; 35543 35544 if (!vm.horizontal) { 35545 // bar 35546 left = vm.x - vm.width / 2; 35547 right = vm.x + vm.width / 2; 35548 top = vm.y; 35549 bottom = vm.base; 35550 signX = 1; 35551 signY = bottom > top ? 1 : -1; 35552 borderSkipped = vm.borderSkipped || 'bottom'; 35553 } else { 35554 // horizontal bar 35555 left = vm.base; 35556 right = vm.x; 35557 top = vm.y - vm.height / 2; 35558 bottom = vm.y + vm.height / 2; 35559 signX = right > left ? 1 : -1; 35560 signY = 1; 35561 borderSkipped = vm.borderSkipped || 'left'; 35562 } 35563 35564 // Canvas doesn't allow us to stroke inside the width so we can 35565 // adjust the sizes to fit if we're setting a stroke on the line 35566 if (borderWidth) { 35567 // borderWidth shold be less than bar width and bar height. 35568 var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom)); 35569 borderWidth = borderWidth > barSize ? barSize : borderWidth; 35570 var halfStroke = borderWidth / 2; 35571 // Adjust borderWidth when bar top position is near vm.base(zero). 35572 var borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0); 35573 var borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0); 35574 var borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0); 35575 var borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0); 35576 // not become a vertical line? 35577 if (borderLeft !== borderRight) { 35578 top = borderTop; 35579 bottom = borderBottom; 35580 } 35581 // not become a horizontal line? 35582 if (borderTop !== borderBottom) { 35583 left = borderLeft; 35584 right = borderRight; 35585 } 35586 } 35587 35588 ctx.beginPath(); 35589 ctx.fillStyle = vm.backgroundColor; 35590 ctx.strokeStyle = vm.borderColor; 35591 ctx.lineWidth = borderWidth; 35592 35593 // Corner points, from bottom-left to bottom-right clockwise 35594 // | 1 2 | 35595 // | 0 3 | 35596 var corners = [ 35597 [left, bottom], 35598 [left, top], 35599 [right, top], 35600 [right, bottom] 35601 ]; 35602 35603 // Find first (starting) corner with fallback to 'bottom' 35604 var borders = ['bottom', 'left', 'top', 'right']; 35605 var startCorner = borders.indexOf(borderSkipped, 0); 35606 if (startCorner === -1) { 35607 startCorner = 0; 35608 } 35609 35610 function cornerAt(index) { 35611 return corners[(startCorner + index) % 4]; 35612 } 35613 35614 // Draw rectangle from 'startCorner' 35615 var corner = cornerAt(0); 35616 ctx.moveTo(corner[0], corner[1]); 35617 35618 for (var i = 1; i < 4; i++) { 35619 corner = cornerAt(i); 35620 ctx.lineTo(corner[0], corner[1]); 35621 } 35622 35623 ctx.fill(); 35624 if (borderWidth) { 35625 ctx.stroke(); 35626 } 35627 }, 35628 35629 height: function() { 35630 var vm = this._view; 35631 return vm.base - vm.y; 35632 }, 35633 35634 inRange: function(mouseX, mouseY) { 35635 var inRange = false;
35636 35637 if (this._view) { 35638 var bounds = getBarBounds(this); 35639 inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom; 35640 } 35641 35642 return inRange; 35643 }, 35644 35645 inLabelRange: function(mouseX, mouseY) { 35646 var me = this; 35647 if (!me._view) { 35648 return false; 35649 } 35650 35651 var inRange = false; 35652 var bounds = getBarBounds(me); 35653 35654 if (isVertical(me)) { 35655 inRange = mouseX >= bounds.left && mouseX <= bounds.right; 35656 } else { 35657 inRange = mouseY >= bounds.top && mouseY <= bounds.bottom; 35658 } 35659 35660 return inRange; 35661 }, 35662 35663 inXRange: function(mouseX) { 35664 var bounds = getBarBounds(this); 35665 return mouseX >= bounds.left && mouseX <= bounds.right; 35666 }, 35667 35668 inYRange: function(mouseY) { 35669 var bounds = getBarBounds(this); 35670 return mouseY >= bounds.top && mouseY <= bounds.bottom; 35671 }, 35672 35673 getCenterPoint: function() { 35674 var vm = this._view; 35675 var x, y; 35676 if (isVertical(this)) { 35677 x = vm.x; 35678 y = (vm.y + vm.base) / 2; 35679 } else { 35680 x = (vm.x + vm.base) / 2; 35681 y = vm.y; 35682 } 35683 35684 return {x: x, y: y}; 35685 }, 35686 35687 getArea: function() { 35688 var vm = this._view; 35689 return vm.width * Math.abs(vm.y - vm.base); 35690 }, 35691 35692 tooltipPosition: function() { 35693 var vm = this._view; 35694 return { 35695 x: vm.x, 35696 y: vm.y 35697 }; 35698 } 35699}); 35700 35701},{"25":25,"26":26}],40:[function(require,module,exports){ 35702'use strict'; 35703 35704module.exports = {}; 35705module.exports.Arc = require(36); 35706module.exports.Line = require(37); 35707module.exports.Point = require(38); 35708module.exports.Rectangle = require(39); 35709 35710},{"36":36,"37":37,"38":38,"39":39}],41:[function(require,module,exports){ 35711'use strict'; 35712 35713var helpers = require(42); 35714 35715/** 35716 * @namespace Chart.helpers.canvas 35717 */ 35718var exports = module.exports = { 35719 /** 35720 * Clears the entire canvas associated to the given `chart`. 35721 * @param {Chart} chart - The chart for which to clear the canvas. 35722 */ 35723 clear: function(chart) { 35724 chart.ctx.clearRect(0, 0, chart.width, chart.height); 35725 }, 35726 35727 /** 35728 * Creates a "path" for a rectangle with rounded corners at position (x, y) with a 35729 * given size (width, height) and the same `radius` for all corners. 35730 * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context. 35731 * @param {Number} x - The x axis of the coordinate for the rectangle starting point. 35732 * @param {Number} y - The y axis of the coordinate for the rectangle starting point. 35733 * @param {Number} width - The rectangle's width. 35734 * @param {Number} height - The rectangle's height. 35735 * @param {Number} radius - The rounded amount (in pixels) for the four corners. 35736 * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object? 35737 */ 35738 roundedRect: function(ctx, x, y, width, height, radius) { 35739 if (radius) { 35740 var rx = Math.min(radius, width / 2); 35741 var ry = Math.min(radius, height / 2); 35742 35743 ctx.moveTo(x + rx, y); 35744 ctx.lineTo(x + width - rx, y); 35745 ctx.quadraticCurveTo(x + width, y, x + width, y + ry); 35746 ctx.lineTo(x + width, y + height - ry); 35747 ctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height); 35748 ctx.lineTo(x + rx, y + height); 35749 ctx.quadraticCurveTo(x, y + height, x, y + height - ry); 35750 ctx.lineTo(x, y + ry); 35751 ctx.quadraticCurveTo(x, y, x + rx, y); 35752 } else { 35753 ctx.rect(x, y, width, height); 35754 } 35755 }, 35756 35757 drawPoint: function(ctx, style, radius, x, y) { 35758 var type, edgeLength, xOffset, yOffset, height, size; 35759 35760 if (style && typeof style === 'object') { 35761 type = style.toString(); 35762 if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') { 35763 ctx.drawImage(style, x - style.width / 2, y - style.height / 2, style.width, style.height); 35764 return; 35765 } 35766 } 35767 35768 if (isNaN(radius) || radius <= 0) { 35769 return; 35770 } 35771 35772 switch (style) { 35773 // Default includes circle 35774 default: 35775 ctx.beginPath(); 35776 ctx.arc(x, y, radius, 0, Math.PI * 2); 35777 ctx.closePath(); 35778 ctx.fill(); 35779 break; 35780 case 'triangle': 35781 ctx.beginPath(); 35782 edgeLength = 3 * radius / Math.sqrt(3); 35783 height = edgeLength * Math.sqrt(3) / 2; 35784 ctx.moveTo(x - edgeLength / 2, y + height / 3); 35785 ctx.lineTo(x + edgeLength / 2, y + height / 3); 35786 ctx.lineTo(x, y - 2 * height / 3); 35787 ctx.closePath(); 35788 ctx.fill(); 35789 break; 35790 case 'rect': 35791 size = 1 / Math.SQRT2 * radius; 35792 ctx.beginPath(); 35793 ctx.fillRect(x - size, y - size, 2 * size, 2 * size); 35794 ctx.strokeRect(x - size, y - size, 2 * size, 2 * size); 35795 break; 35796 case 'rectRounded': 35797 var offset = radius / Math.SQRT2; 35798 var leftX = x - offset; 35799 var topY = y - offset; 35800 var sideSize = Math.SQRT2 * radius; 35801 ctx.beginPath(); 35802 this.roundedRect(ctx, leftX, topY, sideSize, sideSize, radius / 2); 35803 ctx.closePath(); 35804 ctx.fill(); 35805 break; 35806 case 'rectRot': 35807 size = 1 / Math.SQRT2 * radius; 35808 ctx.beginPath(); 35809 ctx.moveTo(x - size, y); 35810 ctx.lineTo(x, y + size); 35811 ctx.lineTo(x + size, y); 35812 ctx.lineTo(x, y - size); 35813 ctx.closePath(); 35814 ctx.fill(); 35815 break; 35816 case 'cross': 35817 ctx.beginPath(); 35818 ctx.moveTo(x, y + radius);
35819 ctx.lineTo(x, y - radius); 35820 ctx.moveTo(x - radius, y); 35821 ctx.lineTo(x + radius, y); 35822 ctx.closePath(); 35823 break; 35824 case 'crossRot': 35825 ctx.beginPath(); 35826 xOffset = Math.cos(Math.PI / 4) * radius; 35827 yOffset = Math.sin(Math.PI / 4) * radius; 35828 ctx.moveTo(x - xOffset, y - yOffset); 35829 ctx.lineTo(x + xOffset, y + yOffset); 35830 ctx.moveTo(x - xOffset, y + yOffset); 35831 ctx.lineTo(x + xOffset, y - yOffset); 35832 ctx.closePath(); 35833 break; 35834 case 'star': 35835 ctx.beginPath(); 35836 ctx.moveTo(x, y + radius); 35837 ctx.lineTo(x, y - radius); 35838 ctx.moveTo(x - radius, y); 35839 ctx.lineTo(x + radius, y); 35840 xOffset = Math.cos(Math.PI / 4) * radius; 35841 yOffset = Math.sin(Math.PI / 4) * radius; 35842 ctx.moveTo(x - xOffset, y - yOffset); 35843 ctx.lineTo(x + xOffset, y + yOffset); 35844 ctx.moveTo(x - xOffset, y + yOffset); 35845 ctx.lineTo(x + xOffset, y - yOffset); 35846 ctx.closePath(); 35847 break; 35848 case 'line': 35849 ctx.beginPath(); 35850 ctx.moveTo(x - radius, y); 35851 ctx.lineTo(x + radius, y); 35852 ctx.closePath(); 35853 break; 35854 case 'dash': 35855 ctx.beginPath(); 35856 ctx.moveTo(x, y); 35857 ctx.lineTo(x + radius, y); 35858 ctx.closePath(); 35859 break; 35860 } 35861 35862 ctx.stroke(); 35863 }, 35864 35865 clipArea: function(ctx, area) { 35866 ctx.save(); 35867 ctx.beginPath(); 35868 ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); 35869 ctx.clip(); 35870 }, 35871 35872 unclipArea: function(ctx) { 35873 ctx.restore(); 35874 }, 35875 35876 lineTo: function(ctx, previous, target, flip) { 35877 if (target.steppedLine) { 35878 if ((target.steppedLine === 'after' && !flip) || (target.steppedLine !== 'after' && flip)) { 35879 ctx.lineTo(previous.x, target.y); 35880 } else { 35881 ctx.lineTo(target.x, previous.y); 35882 } 35883 ctx.lineTo(target.x, target.y); 35884 return; 35885 } 35886 35887 if (!target.tension) { 35888 ctx.lineTo(target.x, target.y); 35889 return; 35890 } 35891 35892 ctx.bezierCurveTo( 35893 flip ? previous.controlPointPreviousX : previous.controlPointNextX, 35894 flip ? previous.controlPointPreviousY : previous.controlPointNextY, 35895 flip ? target.controlPointNextX : target.controlPointPreviousX, 35896 flip ? target.controlPointNextY : target.controlPointPreviousY, 35897 target.x, 35898 target.y); 35899 } 35900}; 35901 35902// DEPRECATIONS 35903 35904/** 35905 * Provided for backward compatibility, use Chart.helpers.canvas.clear instead. 35906 * @namespace Chart.helpers.clear 35907 * @deprecated since version 2.7.0 35908 * @todo remove at version 3 35909 * @private 35910 */ 35911helpers.clear = exports.clear; 35912 35913/** 35914 * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead. 35915 * @namespace Chart.helpers.drawRoundedRectangle 35916 * @deprecated since version 2.7.0 35917 * @todo remove at version 3 35918 * @private 35919 */ 35920helpers.drawRoundedRectangle = function(ctx) { 35921 ctx.beginPath(); 35922 exports.roundedRect.apply(exports, arguments); 35923 ctx.closePath(); 35924}; 35925 35926},{"42":42}],42:[function(require,module,exports){ 35927'use strict'; 35928 35929/** 35930 * @namespace Chart.helpers 35931 */ 35932var helpers = { 35933 /** 35934 * An empty function that can be used, for example, for optional callback. 35935 */ 35936 noop: function() {}, 35937 35938 /** 35939 * Returns a unique id, sequentially generated from a global variable. 35940 * @returns {Number} 35941 * @function 35942 */ 35943 uid: (function() { 35944 var id = 0; 35945 return function() { 35946 return id++; 35947 }; 35948 }()), 35949 35950 /** 35951 * Returns true if `value` is neither null nor undefined, else returns false. 35952 * @param {*} value - The value to test. 35953 * @returns {Boolean} 35954 * @since 2.7.0 35955 */ 35956 isNullOrUndef: function(value) { 35957 return value === null || typeof value === 'undefined'; 35958 }, 35959 35960 /** 35961 * Returns true if `value` is an array, else returns false. 35962 * @param {*} value - The value to test. 35963 * @returns {Boolean} 35964 * @function 35965 */ 35966 isArray: Array.isArray ? Array.isArray : function(value) { 35967 return Object.prototype.toString.call(value) === '[object Array]'; 35968 }, 35969 35970 /** 35971 * Returns true if `value` is an object (excluding null), else returns false. 35972 * @param {*} value - The value to test. 35973 * @returns {Boolean} 35974 * @since 2.7.0 35975 */ 35976 isObject: function(value) { 35977 return value !== null && Object.prototype.toString.call(value) === '[object Object]'; 35978 }, 35979 35980 /** 35981 * Returns `value` if defined, else returns `defaultValue`. 35982 * @param {*} value - The value to return if defined. 35983 * @param {*} defaultValue - The value to return if `value` is undefined. 35984 * @returns {*} 35985 */ 35986 valueOrDefault: function(value, defaultValue) { 35987 return typeof value === 'undefined' ? defaultValue : value; 35988 }, 35989 35990 /** 35991 * Returns value at the given `index` in array if defined, else returns `defaultValue`. 35992 * @param {Array} value - The array to lookup for value at `index`. 35993 * @param {Number} index - The index in `value` to lookup for value. 35994 * @param {*} defaultValue - The value to return if `value[index]` is undefined. 35995 * @returns {*} 35996 */ 35997 valueAtIndexOrDefault: function(value, index, defaultValue) { 35998 return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue); 35999 }, 36000 36001 /** 36002 * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the 36003 * value returned by `fn`. If `fn` is not a function, this method returns undefined. 36004 * @param {Function} fn - The function to call. 36005 * @param {Array|undefined|null} args - The arguments with which `fn` should be called. 36006 * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`. 36007 * @returns {*} 36008 */ 36009 callback: function(fn, args, thisArg) { 36010 if (fn && typeof fn.call === 'function') { 36011 return fn.apply(thisArg, args); 36012 } 36013 }, 36014 36015 /** 36016 * Note(SB) for performance sake, this method should only be used when loopable type 36017 * is unknown or in none intensive code (not called often and small loopable). Else 36018 * it's preferable to use a regular for() loop and save extra function calls. 36019 * @param {Object|Array} loopable - The object or array to be iterated. 36020 * @param {Function} fn - The function to call for each item. 36021 * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`. 36022 * @param {Boolean} [reverse] - If true, iterates backward on the loopable. 36023 */ 36024 each: function(loopable, fn, thisArg, reverse) { 36025 var i, len, keys; 36026 if (helpers.isArray(loopable)) { 36027 len = loopable.length; 36028 if (reverse) { 36029 for (i = len - 1; i >= 0; i--) { 36030 fn.call(thisArg, loopable[i], i); 36031 } 36032 } else { 36033 for (i = 0; i < len; i++) { 36034 fn.call(thisArg, loopable[i], i); 36035 } 36036 } 36037 } else if (helpers.isObject(loopable)) { 36038 keys = Object.keys(loopable); 36039 len = keys.length; 36040 for (i = 0; i < len; i++) { 36041 fn.call(thisArg, loopable[keys[i]], keys[i]); 36042 } 36043 } 36044 }, 36045 36046 /** 36047 * Returns true if the `a0` and `a1` arrays have the same content, else returns false. 36048 * @see http://stackoverflow.com/a/14853974 36049 * @param {Array} a0 - The array to compare 36050 * @param {Array} a1 - The array to compare 36051 * @returns {Boolean} 36052 */ 36053 arrayEquals: function(a0, a1) { 36054 var i, ilen, v0, v1; 36055 36056 if (!a0 || !a1 || a0.length !== a1.length) { 36057 return false;
vendor: 10,367 bytes, lines 36058-36511
36058 } 36059 36060 for (i = 0, ilen = a0.length; i < ilen; ++i) { 36061 v0 = a0[i]; 36062 v1 = a1[i]; 36063 36064 if (v0 instanceof Array && v1 instanceof Array) { 36065 if (!helpers.arrayEquals(v0, v1)) { 36066 return false; 36067 } 36068 } else if (v0 !== v1) { 36069 // NOTE: two different object instances will never be equal: {x:20} != {x:20} 36070 return false; 36071 } 36072 } 36073 36074 return true; 36075 }, 36076 36077 /** 36078 * Returns a deep copy of `source` without keeping references on objects and arrays. 36079 * @param {*} source - The value to clone. 36080 * @returns {*} 36081 */ 36082 clone: function(source) { 36083 if (helpers.isArray(source)) { 36084 return source.map(helpers.clone); 36085 } 36086 36087 if (helpers.isObject(source)) { 36088 var target = {}; 36089 var keys = Object.keys(source); 36090 var klen = keys.length; 36091 var k = 0; 36092 36093 for (; k < klen; ++k) { 36094 target[keys[k]] = helpers.clone(source[keys[k]]); 36095 } 36096 36097 return target; 36098 } 36099 36100 return source; 36101 }, 36102 36103 /** 36104 * The default merger when Chart.helpers.merge is called without merger option. 36105 * Note(SB): this method is also used by configMerge and scaleMerge as fallback. 36106 * @private 36107 */ 36108 _merger: function(key, target, source, options) { 36109 var tval = target[key]; 36110 var sval = source[key]; 36111 36112 if (helpers.isObject(tval) && helpers.isObject(sval)) { 36113 helpers.merge(tval, sval, options); 36114 } else { 36115 target[key] = helpers.clone(sval); 36116 } 36117 }, 36118 36119 /** 36120 * Merges source[key] in target[key] only if target[key] is undefined. 36121 * @private 36122 */ 36123 _mergerIf: function(key, target, source) { 36124 var tval = target[key]; 36125 var sval = source[key]; 36126 36127 if (helpers.isObject(tval) && helpers.isObject(sval)) { 36128 helpers.mergeIf(tval, sval); 36129 } else if (!target.hasOwnProperty(key)) { 36130 target[key] = helpers.clone(sval); 36131 } 36132 }, 36133 36134 /** 36135 * Recursively deep copies `source` properties into `target` with the given `options`. 36136 * IMPORTANT: `target` is not cloned and will be updated with `source` properties. 36137 * @param {Object} target - The target object in which all sources are merged into. 36138 * @param {Object|Array(Object)} source - Object(s) to merge into `target`. 36139 * @param {Object} [options] - Merging options: 36140 * @param {Function} [options.merger] - The merge method (key, target, source, options) 36141 * @returns {Object} The `target` object. 36142 */ 36143 merge: function(target, source, options) { 36144 var sources = helpers.isArray(source) ? source : [source]; 36145 var ilen = sources.length; 36146 var merge, i, keys, klen, k; 36147 36148 if (!helpers.isObject(target)) { 36149 return target; 36150 } 36151 36152 options = options || {}; 36153 merge = options.merger || helpers._merger; 36154 36155 for (i = 0; i < ilen; ++i) { 36156 source = sources[i]; 36157 if (!helpers.isObject(source)) { 36158 continue; 36159 } 36160 36161 keys = Object.keys(source); 36162 for (k = 0, klen = keys.length; k < klen; ++k) { 36163 merge(keys[k], target, source, options); 36164 } 36165 } 36166 36167 return target; 36168 }, 36169 36170 /** 36171 * Recursively deep copies `source` properties into `target` *only* if not defined in target. 36172 * IMPORTANT: `target` is not cloned and will be updated with `source` properties. 36173 * @param {Object} target - The target object in which all sources are merged into. 36174 * @param {Object|Array(Object)} source - Object(s) to merge into `target`. 36175 * @returns {Object} The `target` object. 36176 */ 36177 mergeIf: function(target, source) { 36178 return helpers.merge(target, source, {merger: helpers._mergerIf}); 36179 }, 36180 36181 /** 36182 * Applies the contents of two or more objects together into the first object. 36183 * @param {Object} target - The target object in which all objects are merged into. 36184 * @param {Object} arg1 - Object containing additional properties to merge in target. 36185 * @param {Object} argN - Additional objects containing properties to merge in target. 36186 * @returns {Object} The `target` object. 36187 */ 36188 extend: function(target) { 36189 var setFn = function(value, key) { 36190 target[key] = value; 36191 }; 36192 for (var i = 1, ilen = arguments.length; i < ilen; ++i) { 36193 helpers.each(arguments[i], setFn); 36194 } 36195 return target; 36196 }, 36197 36198 /** 36199 * Basic javascript inheritance based on the model created in Backbone.js 36200 */ 36201 inherits: function(extensions) { 36202 var me = this; 36203 var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() { 36204 return me.apply(this, arguments); 36205 }; 36206 36207 var Surrogate = function() { 36208 this.constructor = ChartElement; 36209 }; 36210 36211 Surrogate.prototype = me.prototype; 36212 ChartElement.prototype = new Surrogate(); 36213 ChartElement.extend = helpers.inherits; 36214 36215 if (extensions) { 36216 helpers.extend(ChartElement.prototype, extensions); 36217 } 36218 36219 ChartElement.__super__ = me.prototype; 36220 return ChartElement; 36221 } 36222}; 36223 36224module.exports = helpers; 36225 36226// DEPRECATIONS 36227 36228/** 36229 * Provided for backward compatibility, use Chart.helpers.callback instead. 36230 * @function Chart.helpers.callCallback 36231 * @deprecated since version 2.6.0 36232 * @todo remove at version 3 36233 * @private 36234 */ 36235helpers.callCallback = helpers.callback; 36236 36237/** 36238 * Provided for backward compatibility, use Array.prototype.indexOf instead. 36239 * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+ 36240 * @function Chart.helpers.indexOf 36241 * @deprecated since version 2.7.0 36242 * @todo remove at version 3 36243 * @private 36244 */ 36245helpers.indexOf = function(array, item, fromIndex) { 36246 return Array.prototype.indexOf.call(array, item, fromIndex); 36247}; 36248 36249/** 36250 * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead. 36251 * @function Chart.helpers.getValueOrDefault 36252 * @deprecated since version 2.7.0 36253 * @todo remove at version 3 36254 * @private 36255 */ 36256helpers.getValueOrDefault = helpers.valueOrDefault; 36257 36258/** 36259 * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead. 36260 * @function Chart.helpers.getValueAtIndexOrDefault 36261 * @deprecated since version 2.7.0 36262 * @todo remove at version 3 36263 * @private 36264 */ 36265helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault; 36266 36267},{}],43:[function(require,module,exports){ 36268'use strict'; 36269 36270var helpers = require(42); 36271 36272/** 36273 * Easing functions adapted from Robert Penner's easing equations. 36274 * @namespace Chart.helpers.easingEffects 36275 * @see http://www.robertpenner.com/easing/ 36276 */ 36277var effects = { 36278 linear: function(t) { 36279 return t; 36280 }, 36281 36282 easeInQuad: function(t) { 36283 return t * t; 36284 }, 36285 36286 easeOutQuad: function(t) { 36287 return -t * (t - 2); 36288 }, 36289 36290 easeInOutQuad: function(t) { 36291 if ((t /= 0.5) < 1) { 36292 return 0.5 * t * t; 36293 } 36294 return -0.5 * ((--t) * (t - 2) - 1); 36295 }, 36296 36297 easeInCubic: function(t) { 36298 return t * t * t; 36299 }, 36300 36301 easeOutCubic: function(t) { 36302 return (t = t - 1) * t * t + 1; 36303 }, 36304 36305 easeInOutCubic: function(t) { 36306 if ((t /= 0.5) < 1) { 36307 return 0.5 * t * t * t; 36308 } 36309 return 0.5 * ((t -= 2) * t * t + 2); 36310 }, 36311 36312 easeInQuart: function(t) { 36313 return t * t * t * t; 36314 }, 36315 36316 easeOutQuart: function(t) { 36317 return -((t = t - 1) * t * t * t - 1); 36318 }, 36319 36320 easeInOutQuart: function(t) { 36321 if ((t /= 0.5) < 1) { 36322 return 0.5 * t * t * t * t; 36323 } 36324 return -0.5 * ((t -= 2) * t * t * t - 2); 36325 }, 36326 36327 easeInQuint: function(t) { 36328 return t * t * t * t * t; 36329 }, 36330 36331 easeOutQuint: function(t) { 36332 return (t = t - 1) * t * t * t * t + 1; 36333 }, 36334 36335 easeInOutQuint: function(t) { 36336 if ((t /= 0.5) < 1) { 36337 return 0.5 * t * t * t * t * t; 36338 } 36339 return 0.5 * ((t -= 2) * t * t * t * t + 2); 36340 }, 36341 36342 easeInSine: function(t) { 36343 return -Math.cos(t * (Math.PI / 2)) + 1; 36344 }, 36345 36346 easeOutSine: function(t) { 36347 return Math.sin(t * (Math.PI / 2)); 36348 }, 36349 36350 easeInOutSine: function(t) { 36351 return -0.5 * (Math.cos(Math.PI * t) - 1); 36352 }, 36353 36354 easeInExpo: function(t) { 36355 return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); 36356 }, 36357 36358 easeOutExpo: function(t) { 36359 return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; 36360 }, 36361 36362 easeInOutExpo: function(t) { 36363 if (t === 0) { 36364 return 0; 36365 } 36366 if (t === 1) { 36367 return 1; 36368 } 36369 if ((t /= 0.5) < 1) { 36370 return 0.5 * Math.pow(2, 10 * (t - 1)); 36371 } 36372 return 0.5 * (-Math.pow(2, -10 * --t) + 2); 36373 }, 36374 36375 easeInCirc: function(t) { 36376 if (t >= 1) { 36377 return t; 36378 } 36379 return -(Math.sqrt(1 - t * t) - 1); 36380 }, 36381 36382 easeOutCirc: function(t) { 36383 return Math.sqrt(1 - (t = t - 1) * t); 36384 }, 36385 36386 easeInOutCirc: function(t) { 36387 if ((t /= 0.5) < 1) { 36388 return -0.5 * (Math.sqrt(1 - t * t) - 1); 36389 } 36390 return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); 36391 }, 36392 36393 easeInElastic: function(t) { 36394 var s = 1.70158; 36395 var p = 0; 36396 var a = 1; 36397 if (t === 0) { 36398 return 0; 36399 } 36400 if (t === 1) { 36401 return 1; 36402 } 36403 if (!p) { 36404 p = 0.3; 36405 } 36406 if (a < 1) { 36407 a = 1; 36408 s = p / 4; 36409 } else { 36410 s = p / (2 * Math.PI) * Math.asin(1 / a); 36411 } 36412 return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); 36413 }, 36414 36415 easeOutElastic: function(t) { 36416 var s = 1.70158; 36417 var p = 0; 36418 var a = 1; 36419 if (t === 0) { 36420 return 0; 36421 } 36422 if (t === 1) { 36423 return 1; 36424 } 36425 if (!p) { 36426 p = 0.3; 36427 } 36428 if (a < 1) { 36429 a = 1; 36430 s = p / 4; 36431 } else { 36432 s = p / (2 * Math.PI) * Math.asin(1 / a); 36433 } 36434 return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1; 36435 }, 36436 36437 easeInOutElastic: function(t) { 36438 var s = 1.70158; 36439 var p = 0; 36440 var a = 1; 36441 if (t === 0) { 36442 return 0; 36443 } 36444 if ((t /= 0.5) === 2) { 36445 return 1; 36446 } 36447 if (!p) { 36448 p = 0.45; 36449 } 36450 if (a < 1) { 36451 a = 1; 36452 s = p / 4; 36453 } else { 36454 s = p / (2 * Math.PI) * Math.asin(1 / a); 36455 } 36456 if (t < 1) { 36457 return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); 36458 } 36459 return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1; 36460 }, 36461 easeInBack: function(t) { 36462 var s = 1.70158; 36463 return t * t * ((s + 1) * t - s); 36464 }, 36465 36466 easeOutBack: function(t) { 36467 var s = 1.70158; 36468 return (t = t - 1) * t * ((s + 1) * t + s) + 1; 36469 }, 36470 36471 easeInOutBack: function(t) { 36472 var s = 1.70158; 36473 if ((t /= 0.5) < 1) { 36474 return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); 36475 } 36476 return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); 36477 }, 36478 36479 easeInBounce: function(t) { 36480 return 1 - effects.easeOutBounce(1 - t); 36481 }, 36482 36483 easeOutBounce: function(t) { 36484 if (t < (1 / 2.75)) { 36485 return 7.5625 * t * t; 36486 } 36487 if (t < (2 / 2.75)) { 36488 return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75; 36489 } 36490 if (t < (2.5 / 2.75)) { 36491 return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375; 36492 } 36493 return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375; 36494 }, 36495 36496 easeInOutBounce: function(t) { 36497 if (t < 0.5) { 36498 return effects.easeInBounce(t * 2) * 0.5; 36499 } 36500 return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; 36501 } 36502}; 36503 36504module.exports = { 36505 effects: effects 36506}; 36507 36508// DEPRECATIONS 36509 36510/** 36511 * Provided for backward compatibility, use Chart.helpers.easing.effects instead.
36512 * @function Chart.helpers.easingEffects 36513 * @deprecated since version 2.7.0 36514 * @todo remove at version 3 36515 * @private 36516 */ 36517helpers.easingEffects = effects; 36518 36519},{"42":42}],44:[function(require,module,exports){ 36520'use strict'; 36521 36522var helpers = require(42); 36523 36524/** 36525 * @alias Chart.helpers.options 36526 * @namespace 36527 */ 36528module.exports = { 36529 /** 36530 * Converts the given line height `value` in pixels for a specific font `size`. 36531 * @param {Number|String} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em'). 36532 * @param {Number} size - The font size (in pixels) used to resolve relative `value`. 36533 * @returns {Number} The effective line height in pixels (size * 1.2 if value is invalid). 36534 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height 36535 * @since 2.7.0 36536 */ 36537 toLineHeight: function(value, size) { 36538 var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/); 36539 if (!matches || matches[1] === 'normal') { 36540 return size * 1.2; 36541 } 36542 36543 value = +matches[2]; 36544 36545 switch (matches[3]) { 36546 case 'px': 36547 return value; 36548 case '%': 36549 value /= 100; 36550 break; 36551 default: 36552 break; 36553 } 36554 36555 return size * value; 36556 }, 36557 36558 /** 36559 * Converts the given value into a padding object with pre-computed width/height. 36560 * @param {Number|Object} value - If a number, set the value to all TRBL component, 36561 * else, if and object, use defined properties and sets undefined ones to 0. 36562 * @returns {Object} The padding values (top, right, bottom, left, width, height) 36563 * @since 2.7.0 36564 */ 36565 toPadding: function(value) { 36566 var t, r, b, l; 36567 36568 if (helpers.isObject(value)) { 36569 t = +value.top || 0; 36570 r = +value.right || 0; 36571 b = +value.bottom || 0; 36572 l = +value.left || 0; 36573 } else { 36574 t = r = b = l = +value || 0; 36575 } 36576 36577 return { 36578 top: t, 36579 right: r, 36580 bottom: b, 36581 left: l, 36582 height: t + b, 36583 width: l + r 36584 }; 36585 }, 36586 36587 /** 36588 * Evaluates the given `inputs` sequentially and returns the first defined value. 36589 * @param {Array[]} inputs - An array of values, falling back to the last value. 36590 * @param {Object} [context] - If defined and the current value is a function, the value 36591 * is called with `context` as first argument and the result becomes the new input. 36592 * @param {Number} [index] - If defined and the current value is an array, the value 36593 * at `index` become the new input. 36594 * @since 2.7.0 36595 */ 36596 resolve: function(inputs, context, index) { 36597 var i, ilen, value; 36598 36599 for (i = 0, ilen = inputs.length; i < ilen; ++i) { 36600 value = inputs[i]; 36601 if (value === undefined) { 36602 continue; 36603 } 36604 if (context !== undefined && typeof value === 'function') { 36605 value = value(context); 36606 } 36607 if (index !== undefined && helpers.isArray(value)) { 36608 value = value[index]; 36609 } 36610 if (value !== undefined) { 36611 return value; 36612 } 36613 } 36614 } 36615}; 36616 36617},{"42":42}],45:[function(require,module,exports){ 36618'use strict'; 36619 36620module.exports = require(42); 36621module.exports.easing = require(43); 36622module.exports.canvas = require(41); 36623module.exports.options = require(44); 36624 36625},{"41":41,"42":42,"43":43,"44":44}],46:[function(require,module,exports){ 36626/** 36627 * Platform fallback implementation (minimal). 36628 * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939 36629 */ 36630 36631module.exports = { 36632 acquireContext: function(item) { 36633 if (item && item.canvas) { 36634 // Support for any object associated to a canvas (including a context2d) 36635 item = item.canvas; 36636 } 36637 36638 return item && item.getContext('2d') || null; 36639 } 36640}; 36641 36642},{}],47:[function(require,module,exports){ 36643/** 36644 * Chart.Platform implementation for targeting a web browser 36645 */ 36646 36647'use strict'; 36648 36649var helpers = require(45); 36650 36651var EXPANDO_KEY = '$chartjs'; 36652var CSS_PREFIX = 'chartjs-'; 36653var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor'; 36654var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation'; 36655var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart']; 36656 36657/** 36658 * DOM event types -> Chart.js event types. 36659 * Note: only events with different types are mapped. 36660 * @see https://developer.mozilla.org/en-US/docs/Web/Events 36661 */ 36662var EVENT_TYPES = { 36663 touchstart: 'mousedown', 36664 touchmove: 'mousemove', 36665 touchend: 'mouseup', 36666 pointerenter: 'mouseenter', 36667 pointerdown: 'mousedown', 36668 pointermove: 'mousemove', 36669 pointerup: 'mouseup', 36670 pointerleave: 'mouseout', 36671 pointerout: 'mouseout' 36672}; 36673 36674/** 36675 * The "used" size is the final value of a dimension property after all calculations have 36676 * been performed. This method uses the computed style of `element` but returns undefined 36677 * if the computed style is not expressed in pixels. That can happen in some cases where 36678 * `element` has a size relative to its parent and this last one is not yet displayed, 36679 * for example because of `display: none` on a parent node. 36680 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value 36681 * @returns {Number} Size in pixels or undefined if unknown. 36682 */ 36683function readUsedSize(element, property) { 36684 var value = helpers.getStyle(element, property); 36685 var matches = value && value.match(/^(\d+)(\.\d+)?px$/); 36686 return matches ? Number(matches[1]) : undefined; 36687} 36688 36689/** 36690 * Initializes the canvas style and render size without modifying the canvas display size, 36691 * since responsiveness is handled by the controller.resize() method. The config is used 36692 * to determine the aspect ratio to apply in case no explicit height has been specified. 36693 */ 36694function initCanvas(canvas, config) { 36695 var style = canvas.style; 36696 36697 // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it 36698 // returns null or '' if no explicit value has been set to the canvas attribute. 36699 var renderHeight = canvas.getAttribute('height'); 36700 var renderWidth = canvas.getAttribute('width'); 36701 36702 // Chart.js modifies some canvas values that we want to restore on de
36702stroy 36703 canvas[EXPANDO_KEY] = { 36704 initial: { 36705 height: renderHeight, 36706 width: renderWidth, 36707 style: { 36708 display: style.display, 36709 height: style.height, 36710 width: style.width 36711 } 36712 } 36713 }; 36714 36715 // Force canvas to display as block to avoid extra space caused by inline 36716 // elements, which would interfere with the responsive resize process. 36717 // https://github.com/chartjs/Chart.js/issues/2538 36718 style.display = style.display || 'block'; 36719 36720 if (renderWidth === null || renderWidth === '') { 36721 var displayWidth = readUsedSize(canvas, 'width'); 36722 if (displayWidth !== undefined) { 36723 canvas.width = displayWidth; 36724 } 36725 } 36726 36727 if (renderHeight === null || renderHeight === '') { 36728 if (canvas.style.height === '') { 36729 // If no explicit render height and style height, let's apply the aspect ratio, 36730 // which one can be specified by the user but also by charts as default option 36731 // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2. 36732 canvas.height = canvas.width / (config.options.aspectRatio || 2); 36733 } else { 36734 var displayHeight = readUsedSize(canvas, 'height'); 36735 if (displayWidth !== undefined) { 36736 canvas.height = displayHeight; 36737 } 36738 } 36739 } 36740 36741 return canvas; 36742} 36743 36744/** 36745 * Detects support for options object argument in addEventListener. 36746 * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support 36747 * @private 36748 */ 36749var supportsEventListenerOptions = (function() { 36750 var supports = false; 36751 try { 36752 var options = Object.defineProperty({}, 'passive', { 36753 get: function() { 36754 supports = true; 36755 } 36756 }); 36757 window.addEventListener('e', null, options); 36758 } catch (e) { 36759 // continue regardless of error 36760 } 36761 return supports; 36762}()); 36763 36764// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events. 36765// https://github.com/chartjs/Chart.js/issues/4287 36766var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false; 36767 36768function addEventListener(node, type, listener) { 36769 node.addEventListener(type, listener, eventListenerOptions); 36770} 36771 36772function removeEventListener(node, type, listener) { 36773 node.removeEventListener(type, listener, eventListenerOptions); 36774} 36775 36776function createEvent(type, chart, x, y, nativeEvent) { 36777 return { 36778 type: type, 36779 chart: chart, 36780 native: nativeEvent || null, 36781 x: x !== undefined ? x : null, 36782 y: y !== undefined ? y : null, 36783 }; 36784} 36785 36786function fromNativeEvent(event, chart) { 36787 var type = EVENT_TYPES[event.type] || event.type; 36788 var pos = helpers.getRelativePosition(event, chart); 36789 return createEvent(type, chart, pos.x, pos.y, event); 36790} 36791 36792function throttled(fn, thisArg) { 36793 var ticking = false; 36794 var args = []; 36795 36796 return function() { 36797 args = Array.prototype.slice.call(arguments); 36798 thisArg = thisArg || this; 36799 36800 if (!ticking) { 36801 ticking = true; 36802 helpers.requestAnimFrame.call(window, function() { 36803 ticking = false; 36804 fn.apply(thisArg, args); 36805 }); 36806 } 36807 }; 36808} 36809 36810// Implementation based on https://github.com/marcj/css-element-queries 36811function createResizer(handler) { 36812 var resizer = document.createElement('div'); 36813 var cls = CSS_PREFIX + 'size-monitor'; 36814 var maxSize = 1000000; 36815 var style = 36816 'position:absolute;' + 36817 'left:0;' + 36818 'top:0;' + 36819 'right:0;' + 36820 'bottom:0;' + 36821 'overflow:hidden;' + 36822 'pointer-events:none;' + 36823 'visibility:hidden;' + 36824 'z-index:-1;'; 36825 36826 resizer.style.cssText = style; 36827 resizer.className = cls; 36828 resizer.innerHTML = 36829 '<div class="' + cls + '-expand" style="' + style + '">' + 36830 '<div style="' + 36831 'position:absolute;' + 36832 'width:' + maxSize + 'px;' + 36833 'height:' + maxSize + 'px;' + 36834 'left:0;' + 36835 'top:0">' + 36836 '</div>' + 36837 '</div>' + 36838 '<div class="' + cls + '-shrink" style="' + style + '">' + 36839 '<div style="' + 36840 'position:absolute;' + 36841 'width:200%;' + 36842 'height:200%;' + 36843 'left:0; ' + 36844 'top:0">' + 36845 '</div>' + 36846 '</div>'; 36847 36848 var expand = resizer.childNodes[0]; 36849 var shrink = resizer.childNodes[1]; 36850 36851 resizer._reset = function() { 36852 expand.scrollLeft = maxSize; 36853 expand.scrollTop = maxSize; 36854 shrink.scrollLeft = maxSize; 36855 shrink.scrollTop = maxSize; 36856 }; 36857 var onScroll = function() { 36858 resizer._reset(); 36859 handler(); 36860 }; 36861 36862 addEventListener(expand, 'scroll', onScroll.bind(expand, 'expand')); 36863 addEventListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink')); 36864 36865 return resizer; 36866} 36867 36868// https://davidwalsh.name/detect-node-insertion 36869function watchForRender(node, handler) { 36870 var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); 36871 var proxy = expando.renderProxy = function(e) { 36872 if (e.animationName === CSS_RENDER_ANIMATION) { 36873 handler(); 36874 } 36875 }; 36876
36877 helpers.each(ANIMATION_START_EVENTS, function(type) { 36878 addEventListener(node, type, proxy); 36879 }); 36880 36881 // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class 36882 // is removed then added back immediately (same animation frame?). Accessing the 36883 // `offsetParent` property will force a reflow and re-evaluate the CSS animation. 36884 // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics 36885 // https://github.com/chartjs/Chart.js/issues/4737 36886 expando.reflow = !!node.offsetParent; 36887 36888 node.classList.add(CSS_RENDER_MONITOR); 36889} 36890 36891function unwatchForRender(node) { 36892 var expando = node[EXPANDO_KEY] || {}; 36893 var proxy = expando.renderProxy; 36894 36895 if (proxy) { 36896 helpers.each(ANIMATION_START_EVENTS, function(type) { 36897 removeEventListener(node, type, proxy); 36898 }); 36899 36900 delete expando.renderProxy; 36901 } 36902 36903 node.classList.remove(CSS_RENDER_MONITOR); 36904} 36905 36906function addResizeListener(node, listener, chart) { 36907 var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); 36908 36909 // Let's keep track of this added resizer and thus avoid DOM query when removing it. 36910 var resizer = expando.resizer = createResizer(throttled(function() { 36911 if (expando.resizer) { 36912 return listener(createEvent('resize', chart)); 36913 } 36914 })); 36915 36916 // The resizer needs to be attached to the node parent, so we first need to be 36917 // sure that `node` is attached to the DOM before injecting the resizer element. 36918 watchForRender(node, function() { 36919 if (expando.resizer) { 36920 var container = node.parentNode; 36921 if (container && container !== resizer.parentNode) { 36922 container.insertBefore(resizer, container.firstChild); 36923 } 36924 36925 // The container size might have changed, let's reset the resizer state. 36926 resizer._reset(); 36927 } 36928 }); 36929} 36930 36931function removeResizeListener(node) { 36932 var expando = node[EXPANDO_KEY] || {}; 36933 var resizer = expando.resizer; 36934 36935 delete expando.resizer; 36936 unwatchForRender(node); 36937 36938 if (resizer && resizer.parentNode) { 36939 resizer.parentNode.removeChild(resizer); 36940 } 36941} 36942 36943function injectCSS(platform, css) { 36944 // http://stackoverflow.com/q/3922139 36945 var style = platform._style || document.createElement('style'); 36946 if (!platform._style) { 36947 platform._style = style; 36948 css = '/* Chart.js */\n' + css; 36949 style.setAttribute('type', 'text/css'); 36950 document.getElementsByTagName('head')[0].appendChild(style); 36951 } 36952 36953 style.appendChild(document.createTextNode(css)); 36954} 36955 36956module.exports = { 36957 /** 36958 * This property holds whether this platform is enabled for the current environment. 36959 * Currently used by platform.js to select the proper implementation. 36960 * @private 36961 */ 36962 _enabled: typeof window !== 'undefined' && typeof document !== 'undefined', 36963 36964 initialize: function() { 36965 var keyframes = 'from{opacity:0.99}to{opacity:1}'; 36966 36967 injectCSS(this, 36968 // DOM rendering detection 36969 // https://davidwalsh.name/detect-node-insertion 36970 '@-webkit-keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' + 36971 '@keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' + 36972 '.' + CSS_RENDER_MONITOR + '{' + 36973 '-webkit-animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' + 36974 'animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' + 36975 '}' 36976 ); 36977 }, 36978 36979 acquireContext: function(item, config) { 36980 if (typeof item === 'string') { 36981 item = document.getElementById(item); 36982 } else if (item.length) { 36983 // Support for array based queries (such as jQuery) 36984 item = item[0]; 36985 } 36986 36987 if (item && item.canvas) { 36988 // Support for any object associated to a canvas (including a context2d) 36989 item = item.canvas; 36990 } 36991 36992 // To prevent canvas fingerprinting, some add-ons undefine the getContext 36993 // method, for example: https://github.com/kkapsner/CanvasBlocker 36994 // https://github.com/chartjs/Chart.js/issues/2807 36995 var context = item && item.getContext && item.getContext('2d'); 36996 36997 // `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is 36998 // inside an iframe or when running in a protected environment. We could guess the 36999 // types from their toString() value but let's keep things flexible and assume it's 37000 // a sufficient condition if the item has a context2D which has item as `canvas`. 37001 // https://github.com/chartjs/Chart.js/issues/3887 37002 // https://github.com/chartjs/Chart.js/issues/4102 37003 // https://github.com/chartjs/Chart.js/issues/4152 37004 if (context && context.canvas === item) { 37005 initCanvas(item, config); 37006 return context; 37007 } 37008 37009 return null; 37010 }, 37011 37012 releaseContext: function(context) { 37013 var canvas = context.canvas; 37014 if (!canvas[EXPANDO_KEY]) { 37015 return; 37016 } 37017 37018 var initial = canvas[EXPANDO_KEY].initial; 37019 ['height', 'width'].forEach(function(prop) { 37020 var value = initial[prop]; 37021 if (helpers.isNullOrUndef(value)) { 37022 canvas.removeAttribute(prop); 37023 } else { 37024 canvas.setAttribute(prop, value); 37025 } 37026 }); 37027 37028 helpers.each(initial.style || {}, function(value, key) { 37029 canvas.style[key] = value; 37030 }); 37031 37032 // The canvas render size might have been changed (and thus the state stack discarded),
37033 // we can't use save() and restore() to restore the initial state. So make sure that at 37034 // least the canvas context is reset to the default state by setting the canvas width. 37035 // https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html 37036 canvas.width = canvas.width; 37037 37038 delete canvas[EXPANDO_KEY]; 37039 }, 37040 37041 addEventListener: function(chart, type, listener) { 37042 var canvas = chart.canvas; 37043 if (type === 'resize') { 37044 // Note: the resize event is not supported on all browsers. 37045 addResizeListener(canvas, listener, chart); 37046 return; 37047 } 37048 37049 var expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {}); 37050 var proxies = expando.proxies || (expando.proxies = {}); 37051 var proxy = proxies[chart.id + '_' + type] = function(event) { 37052 listener(fromNativeEvent(event, chart)); 37053 }; 37054 37055 addEventListener(canvas, type, proxy); 37056 }, 37057 37058 removeEventListener: function(chart, type, listener) { 37059 var canvas = chart.canvas; 37060 if (type === 'resize') { 37061 // Note: the resize event is not supported on all browsers. 37062 removeResizeListener(canvas, listener); 37063 return; 37064 } 37065 37066 var expando = listener[EXPANDO_KEY] || {}; 37067 var proxies = expando.proxies || {}; 37068 var proxy = proxies[chart.id + '_' + type]; 37069 if (!proxy) { 37070 return; 37071 } 37072 37073 removeEventListener(canvas, type, proxy); 37074 } 37075}; 37076 37077// DEPRECATIONS 37078 37079/** 37080 * Provided for backward compatibility, use EventTarget.addEventListener instead. 37081 * EventTarget.addEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+ 37082 * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener 37083 * @function Chart.helpers.addEvent 37084 * @deprecated since version 2.7.0 37085 * @todo remove at version 3 37086 * @private 37087 */ 37088helpers.addEvent = addEventListener; 37089 37090/** 37091 * Provided for backward compatibility, use EventTarget.removeEventListener instead. 37092 * EventTarget.removeEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+ 37093 * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener 37094 * @function Chart.helpers.removeEvent 37095 * @deprecated since version 2.7.0 37096 * @todo remove at version 3 37097 * @private 37098 */ 37099helpers.removeEvent = removeEventListener; 37100 37101},{"45":45}],48:[function(require,module,exports){ 37102'use strict'; 37103 37104var helpers = require(45); 37105var basic = require(46); 37106var dom = require(47); 37107 37108// @TODO Make possible to select another platform at build time. 37109var implementation = dom._enabled ? dom : basic; 37110 37111/** 37112 * @namespace Chart.platform 37113 * @see https://chartjs.gitbooks.io/proposals/content/Platform.html 37114 * @since 2.4.0 37115 */ 37116module.exports = helpers.extend({ 37117 /** 37118 * @since 2.7.0 37119 */ 37120 initialize: function() {}, 37121 37122 /** 37123 * Called at chart construction time, returns a context2d instance implementing 37124 * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}. 37125 * @param {*} item - The native item from which to acquire context (platform specific) 37126 * @param {Object} options - The chart options 37127 * @returns {CanvasRenderingContext2D} context2d instance 37128 */ 37129 acquireContext: function() {}, 37130 37131 /** 37132 * Called at chart destruction time, releases any resources associated to the context 37133 * previously returned by the acquireContext() method. 37134 * @param {CanvasRenderingContext2D} context - The context2d instance 37135 * @returns {Boolean} true if the method succeeded, else false 37136 */ 37137 releaseContext: function() {}, 37138 37139 /** 37140 * Registers the specified listener on the given chart. 37141 * @param {Chart} chart - Chart from which to listen for event 37142 * @param {String} type - The ({@link IEvent}) type to listen for 37143 * @param {Function} listener - Receives a notification (an object that implements 37144 * the {@link IEvent} interface) when an event of the specified type occurs. 37145 */ 37146 addEventListener: function() {}, 37147 37148 /** 37149 * Removes the specified listener previously registered with addEventListener. 37150 * @param {Chart} chart -Chart from which to remove the listener 37151 * @param {String} type - The ({@link IEvent}) type to remove 37152 * @param {Function} listener - The listener function to remove from the event target. 37153 */ 37154 removeEventListener: function() {} 37155 37156}, implementation); 37157 37158/** 37159 * @interface IPlatform 37160 * Allows abstracting platform dependencies away from the chart 37161 * @borrows Chart.platform.acquireContext as acquireContext 37162 * @borrows Chart.platform.releaseContext as releaseContext 37163 * @borrows Chart.platform.addEventListener as addEventListener 37164 * @borrows Chart.platform.removeEventListener as removeEventListener 37165 */ 37166 37167/** 37168 * @interface IEvent 37169 * @prop {String} type - The event type name, possible values are: 37170 * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',
37171 * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize' 37172 * @prop {*} native - The original native event (null for emulated events, e.g. 'resize') 37173 * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events) 37174 * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events) 37175 */ 37176 37177},{"45":45,"46":46,"47":47}],49:[function(require,module,exports){ 37178'use strict'; 37179 37180module.exports = {}; 37181module.exports.filler = require(50); 37182module.exports.legend = require(51); 37183module.exports.title = require(52); 37184 37185},{"50":50,"51":51,"52":52}],50:[function(require,module,exports){ 37186/** 37187 * Plugin based on discussion from the following Chart.js issues: 37188 * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569 37189 * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897 37190 */ 37191 37192'use strict'; 37193 37194var defaults = require(25); 37195var elements = require(40); 37196var helpers = require(45); 37197 37198defaults._set('global', { 37199 plugins: { 37200 filler: { 37201 propagate: true 37202 } 37203 } 37204}); 37205 37206var mappers = { 37207 dataset: function(source) { 37208 var index = source.fill; 37209 var chart = source.chart; 37210 var meta = chart.getDatasetMeta(index); 37211 var visible = meta && chart.isDatasetVisible(index); 37212 var points = (visible && meta.dataset._children) || []; 37213 var length = points.length || 0; 37214 37215 return !length ? null : function(point, i) { 37216 return (i < length && points[i]._view) || null; 37217 }; 37218 }, 37219 37220 boundary: function(source) { 37221 var boundary = source.boundary; 37222 var x = boundary ? boundary.x : null; 37223 var y = boundary ? boundary.y : null; 37224 37225 return function(point) { 37226 return { 37227 x: x === null ? point.x : x, 37228 y: y === null ? point.y : y, 37229 }; 37230 }; 37231 } 37232}; 37233 37234// @todo if (fill[0] === '#') 37235function decodeFill(el, index, count) { 37236 var model = el._model || {}; 37237 var fill = model.fill; 37238 var target; 37239 37240 if (fill === undefined) { 37241 fill = !!model.backgroundColor; 37242 } 37243 37244 if (fill === false || fill === null) { 37245 return false; 37246 } 37247 37248 if (fill === true) { 37249 return 'origin'; 37250 } 37251 37252 target = parseFloat(fill, 10); 37253 if (isFinite(target) && Math.floor(target) === target) { 37254 if (fill[0] === '-' || fill[0] === '+') { 37255 target = index + target; 37256 } 37257 37258 if (target === index || target < 0 || target >= count) { 37259 return false; 37260 } 37261 37262 return target; 37263 } 37264 37265 switch (fill) { 37266 // compatibility 37267 case 'bottom': 37268 return 'start'; 37269 case 'top': 37270 return 'end'; 37271 case 'zero': 37272 return 'origin'; 37273 // supported boundaries 37274 case 'origin': 37275 case 'start': 37276 case 'end': 37277 return fill; 37278 // invalid fill values 37279 default: 37280 return false; 37281 } 37282} 37283 37284function computeBoundary(source) { 37285 var model = source.el._model || {}; 37286 var scale = source.el._scale || {}; 37287 var fill = source.fill; 37288 var target = null; 37289 var horizontal; 37290 37291 if (isFinite(fill)) { 37292 return null; 37293 } 37294 37295 // Backward compatibility: until v3, we still need to support boundary values set on 37296 // the model (scaleTop, scaleBottom and scaleZero) because some external plugins and 37297 // controllers might still use it (e.g. the Smith chart). 37298 37299 if (fill === 'start') { 37300 target = model.scaleBottom === undefined ? scale.bottom : model.scaleBottom; 37301 } else if (fill === 'end') { 37302 target = model.scaleTop === undefined ? scale.top : model.scaleTop; 37303 } else if (model.scaleZero !== undefined) { 37304 target = model.scaleZero; 37305 } else if (scale.getBasePosition) { 37306 target = scale.getBasePosition(); 37307 } else if (scale.getBasePixel) { 37308 target = scale.getBasePixel(); 37309 } 37310 37311 if (target !== undefined && target !== null) { 37312 if (target.x !== undefined && target.y !== undefined) { 37313 return target; 37314 } 37315 37316 if (typeof target === 'number' && isFinite(target)) { 37317 horizontal = scale.isHorizontal(); 37318 return { 37319 x: horizontal ? target : null, 37320 y: horizontal ? null : target 37321 }; 37322 } 37323 } 37324 37325 return null; 37326} 37327 37328function resolveTarget(sources, index, propagate) { 37329 var source = sources[index]; 37330 var fill = source.fill; 37331 var visited = [index]; 37332 var target; 37333 37334 if (!propagate) { 37335 return fill; 37336 } 37337 37338 while (fill !== false && visited.indexOf(fill) === -1) { 37339 if (!isFinite(fill)) { 37340 return fill; 37341 } 37342 37343 target = sources[fill]; 37344 if (!target) { 37345 return false;
37346 } 37347 37348 if (target.visible) { 37349 return fill; 37350 } 37351 37352 visited.push(fill); 37353 fill = target.fill; 37354 } 37355 37356 return false; 37357} 37358 37359function createMapper(source) { 37360 var fill = source.fill; 37361 var type = 'dataset'; 37362 37363 if (fill === false) { 37364 return null; 37365 } 37366 37367 if (!isFinite(fill)) { 37368 type = 'boundary'; 37369 } 37370 37371 return mappers[type](source); 37372} 37373 37374function isDrawable(point) { 37375 return point && !point.skip; 37376} 37377 37378function drawArea(ctx, curve0, curve1, len0, len1) { 37379 var i; 37380 37381 if (!len0 || !len1) { 37382 return; 37383 } 37384 37385 // building first area curve (normal) 37386 ctx.moveTo(curve0[0].x, curve0[0].y); 37387 for (i = 1; i < len0; ++i) { 37388 helpers.canvas.lineTo(ctx, curve0[i - 1], curve0[i]); 37389 } 37390 37391 // joining the two area curves 37392 ctx.lineTo(curve1[len1 - 1].x, curve1[len1 - 1].y); 37393 37394 // building opposite area curve (reverse) 37395 for (i = len1 - 1; i > 0; --i) { 37396 helpers.canvas.lineTo(ctx, curve1[i], curve1[i - 1], true); 37397 } 37398} 37399 37400function doFill(ctx, points, mapper, view, color, loop) { 37401 var count = points.length; 37402 var span = view.spanGaps; 37403 var curve0 = []; 37404 var curve1 = []; 37405 var len0 = 0; 37406 var len1 = 0; 37407 var i, ilen, index, p0, p1, d0, d1; 37408 37409 ctx.beginPath(); 37410 37411 for (i = 0, ilen = (count + !!loop); i < ilen; ++i) { 37412 index = i % count; 37413 p0 = points[index]._view; 37414 p1 = mapper(p0, index, view); 37415 d0 = isDrawable(p0); 37416 d1 = isDrawable(p1); 37417 37418 if (d0 && d1) { 37419 len0 = curve0.push(p0); 37420 len1 = curve1.push(p1); 37421 } else if (len0 && len1) { 37422 if (!span) { 37423 drawArea(ctx, curve0, curve1, len0, len1); 37424 len0 = len1 = 0; 37425 curve0 = []; 37426 curve1 = []; 37427 } else { 37428 if (d0) { 37429 curve0.push(p0); 37430 } 37431 if (d1) { 37432 curve1.push(p1); 37433 } 37434 } 37435 } 37436 } 37437 37438 drawArea(ctx, curve0, curve1, len0, len1); 37439 37440 ctx.closePath(); 37441 ctx.fillStyle = color; 37442 ctx.fill(); 37443} 37444 37445module.exports = { 37446 id: 'filler', 37447 37448 afterDatasetsUpdate: function(chart, options) { 37449 var count = (chart.data.datasets || []).length; 37450 var propagate = options.propagate; 37451 var sources = []; 37452 var meta, i, el, source; 37453 37454 for (i = 0; i < count; ++i) { 37455 meta = chart.getDatasetMeta(i); 37456 el = meta.dataset; 37457 source = null; 37458 37459 if (el && el._model && el instanceof elements.Line) { 37460 source = { 37461 visible: chart.isDatasetVisible(i), 37462 fill: decodeFill(el, i, count), 37463 chart: chart, 37464 el: el 37465 }; 37466 } 37467 37468 meta.$filler = source; 37469 sources.push(source); 37470 } 37471 37472 for (i = 0; i < count; ++i) { 37473 source = sources[i]; 37474 if (!source) { 37475 continue; 37476 } 37477 37478 source.fill = resolveTarget(sources, i, propagate); 37479 source.boundary = computeBoundary(source); 37480 source.mapper = createMapper(source); 37481 } 37482 }, 37483 37484 beforeDatasetDraw: function(chart, args) { 37485 var meta = args.meta.$filler; 37486 if (!meta) { 37487 return; 37488 } 37489 37490 var ctx = chart.ctx; 37491 var el = meta.el; 37492 var view = el._view; 37493 var points = el._children || []; 37494 var mapper = meta.mapper; 37495 var color = view.backgroundColor || defaults.global.defaultColor; 37496 37497 if (mapper && color && points.length) { 37498 helpers.canvas.clipArea(ctx, chart.chartArea); 37499 doFill(ctx, points, mapper, view, color, el._loop); 37500 helpers.canvas.unclipArea(ctx); 37501 } 37502 } 37503}; 37504 37505},{"25":25,"40":40,"45":45}],51:[function(require,module,exports){ 37506'use strict'; 37507 37508var defaults = require(25); 37509var Element = require(26); 37510var helpers = require(45); 37511var layouts = require(30); 37512 37513var noop = helpers.noop; 37514 37515defaults._set('global', { 37516 legend: { 37517 display: true, 37518 position: 'top', 37519 fullWidth: true, 37520 reverse: false, 37521 weight: 1000, 37522 37523 // a callback that will handle 37524 onClick: function(e, legendItem) { 37525 var index = legendItem.datasetIndex; 37526 var ci = this.chart; 37527 var meta = ci.getDatasetMeta(index); 37528 37529 // See controller.isDatasetVisible comment 37530 meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null; 37531 37532 // We hid a dataset ... rerender the chart 37533 ci.update(); 37534 }, 37535 37536 onHover: null, 37537 37538 labels: { 37539 boxWidth: 40, 37540 padding: 10, 37541 // Generates labels shown in the legend 37542 // Valid properties to return: 37543 // text : text to display 37544 // fillStyle : fill of coloured box 37545 // strokeStyle: stroke of coloured box 37546 // hidden : if this legend item refers to a hidden item 37547 // lineCap : cap style for line 37548 // lineDash 37549 // lineDashOffset : 37550 // lineJoin : 37551 // lineWidth :
37552 generateLabels: function(chart) { 37553 var data = chart.data; 37554 return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) { 37555 return { 37556 text: dataset.label, 37557 fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]), 37558 hidden: !chart.isDatasetVisible(i), 37559 lineCap: dataset.borderCapStyle, 37560 lineDash: dataset.borderDash, 37561 lineDashOffset: dataset.borderDashOffset, 37562 lineJoin: dataset.borderJoinStyle, 37563 lineWidth: dataset.borderWidth, 37564 strokeStyle: dataset.borderColor, 37565 pointStyle: dataset.pointStyle, 37566 37567 // Below is extra data used for toggling the datasets 37568 datasetIndex: i 37569 }; 37570 }, this) : []; 37571 } 37572 } 37573 }, 37574 37575 legendCallback: function(chart) { 37576 var text = []; 37577 text.push('<ul class="' + chart.id + '-legend">'); 37578 for (var i = 0; i < chart.data.datasets.length; i++) { 37579 text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '"></span>'); 37580 if (chart.data.datasets[i].label) { 37581 text.push(chart.data.datasets[i].label); 37582 } 37583 text.push('</li>'); 37584 } 37585 text.push('</ul>'); 37586 return text.join(''); 37587 } 37588}); 37589 37590/** 37591 * Helper function to get the box width based on the usePointStyle option 37592 * @param labelopts {Object} the label options on the legend 37593 * @param fontSize {Number} the label font size 37594 * @return {Number} width of the color box area 37595 */ 37596function getBoxWidth(labelOpts, fontSize) { 37597 return labelOpts.usePointStyle ? 37598 fontSize * Math.SQRT2 : 37599 labelOpts.boxWidth; 37600} 37601 37602/** 37603 * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required! 37604 */ 37605var Legend = Element.extend({ 37606 37607 initialize: function(config) { 37608 helpers.extend(this, config); 37609 37610 // Contains hit boxes for each dataset (in dataset order) 37611 this.legendHitBoxes = []; 37612 37613 // Are we in doughnut mode which has a different data type 37614 this.doughnutMode = false; 37615 }, 37616 37617 // These methods are ordered by lifecycle. Utilities then follow. 37618 // Any function defined here is inherited by all legend types. 37619 // Any function can be extended by the legend type 37620 37621 beforeUpdate: noop, 37622 update: function(maxWidth, maxHeight, margins) { 37623 var me = this; 37624 37625 // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) 37626 me.beforeUpdate(); 37627 37628 // Absorb the master measurements 37629 me.maxWidth = maxWidth; 37630 me.maxHeight = maxHeight; 37631 me.margins = margins; 37632 37633 // Dimensions 37634 me.beforeSetDimensions(); 37635 me.setDimensions(); 37636 me.afterSetDimensions(); 37637 // Labels 37638 me.beforeBuildLabels(); 37639 me.buildLabels(); 37640 me.afterBuildLabels(); 37641 37642 // Fit 37643 me.beforeFit(); 37644 me.fit(); 37645 me.afterFit(); 37646 // 37647 me.afterUpdate(); 37648 37649 return me.minSize; 37650 }, 37651 afterUpdate: noop, 37652 37653 // 37654 37655 beforeSetDimensions: noop, 37656 setDimensions: function() { 37657 var me = this; 37658 // Set the unconstrained dimension before label rotation 37659 if (me.isHorizontal()) { 37660 // Reset position before calculating rotation 37661 me.width = me.maxWidth; 37662 me.left = 0; 37663 me.right = me.width; 37664 } else { 37665 me.height = me.maxHeight; 37666 37667 // Reset position before calculating rotation 37668 me.top = 0; 37669 me.bottom = me.height; 37670 } 37671 37672 // Reset padding 37673 me.paddingLeft = 0; 37674 me.paddingTop = 0; 37675 me.paddingRight = 0; 37676 me.paddingBottom = 0; 37677 37678 // Reset minSize 37679 me.minSize = { 37680 width: 0, 37681 height: 0 37682 }; 37683 }, 37684 afterSetDimensions: noop, 37685 37686 // 37687 37688 beforeBuildLabels: noop, 37689 buildLabels: function() { 37690 var me = this; 37691 var labelOpts = me.options.labels || {}; 37692 var legendItems = helpers.callback(labelOpts.generateLabels, [me.chart], me) || []; 37693 37694 if (labelOpts.filter) { 37695 legendItems = legendItems.filter(function(item) { 37696 return labelOpts.filter(item, me.chart.data); 37697 }); 37698 } 37699 37700 if (me.options.reverse) { 37701 legendItems.reverse(); 37702 } 37703 37704 me.legendItems = legendItems; 37705 }, 37706 afterBuildLabels: noop, 37707 37708 // 37709 37710 beforeFit: noop, 37711 fit: function() { 37712 var me = this; 37713 var opts = me.options; 37714 var labelOpts = opts.labels; 37715 var display = opts.display; 37716 37717 var ctx = me.ctx; 37718 37719 var globalDefault = defaults.global; 37720 var valueOrDefault = helpers.valueOrDefault; 37721 var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize); 37722 var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle); 37723 var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily); 37724 var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily); 37725 37726 // Reset hit boxes 37727 var hitboxes = me.legendHitBoxes = []; 37728 37729 var minSize = me.minSize; 37730 var isHorizontal = me.isHorizontal(); 37731 37732 if (isHorizontal) { 37733 minSize.width = me.maxWidth; // fill all the width 37734 minSize.height = display ? 10 : 0; 37735 } else { 37736 minSize.width = display ? 10 : 0; 37737 minSize.height = me.maxHeight; // fill all the height 37738 } 37739 37740 // Increase sizes here 37741 if (display) { 37742 ctx.font = labelFont; 37743 37744 if (isHorizontal) { 37745 // Labels 37746
37747 // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one 37748 var lineWidths = me.lineWidths = [0]; 37749 var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0; 37750 37751 ctx.textAlign = 'left'; 37752 ctx.textBaseline = 'top'; 37753 37754 helpers.each(me.legendItems, function(legendItem, i) { 37755 var boxWidth = getBoxWidth(labelOpts, fontSize); 37756 var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width; 37757 37758 if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) { 37759 totalHeight += fontSize + (labelOpts.padding); 37760 lineWidths[lineWidths.length] = me.left; 37761 } 37762 37763 // Store the hitbox width and height here. Final position will be updated in `draw` 37764 hitboxes[i] = { 37765 left: 0, 37766 top: 0, 37767 width: width, 37768 height: fontSize 37769 }; 37770 37771 lineWidths[lineWidths.length - 1] += width + labelOpts.padding; 37772 }); 37773 37774 minSize.height += totalHeight; 37775 37776 } else { 37777 var vPadding = labelOpts.padding; 37778 var columnWidths = me.columnWidths = []; 37779 var totalWidth = labelOpts.padding; 37780 var currentColWidth = 0; 37781 var currentColHeight = 0; 37782 var itemHeight = fontSize + vPadding; 37783 37784 helpers.each(me.legendItems, function(legendItem, i) { 37785 var boxWidth = getBoxWidth(labelOpts, fontSize); 37786 var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width; 37787 37788 // If too tall, go to new column 37789 if (currentColHeight + itemHeight > minSize.height) { 37790 totalWidth += currentColWidth + labelOpts.padding; 37791 columnWidths.push(currentColWidth); // previous column width 37792 37793 currentColWidth = 0; 37794 currentColHeight = 0; 37795 } 37796 37797 // Get max width 37798 currentColWidth = Math.max(currentColWidth, itemWidth); 37799 currentColHeight += itemHeight; 37800 37801 // Store the hitbox width and height here. Final position will be updated in `draw` 37802 hitboxes[i] = { 37803 left: 0, 37804 top: 0, 37805 width: itemWidth, 37806 height: fontSize 37807 }; 37808 }); 37809 37810 totalWidth += currentColWidth; 37811 columnWidths.push(currentColWidth); 37812 minSize.width += totalWidth; 37813 } 37814 } 37815 37816 me.width = minSize.width; 37817 me.height = minSize.height; 37818 }, 37819 afterFit: noop, 37820 37821 // Shared Methods 37822 isHorizontal: function() { 37823 return this.options.position === 'top' || this.options.position === 'bottom'; 37824 }, 37825 37826 // Actually draw the legend on the canvas 37827 draw: function() { 37828 var me = this; 37829 var opts = me.options; 37830 var labelOpts = opts.labels; 37831 var globalDefault = defaults.global; 37832 var lineDefault = globalDefault.elements.line; 37833 var legendWidth = me.width; 37834 var lineWidths = me.lineWidths; 37835 37836 if (opts.display) { 37837 var ctx = me.ctx; 37838 var valueOrDefault = helpers.valueOrDefault; 37839 var fontColor = valueOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor); 37840 var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize); 37841 var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle); 37842 var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily); 37843 var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily); 37844 var cursor; 37845 37846 // Canvas setup 37847 ctx.textAlign = 'left'; 37848 ctx.textBaseline = 'middle'; 37849 ctx.lineWidth = 0.5; 37850 ctx.strokeStyle = fontColor; // for strikethrough effect 37851 ctx.fillStyle = fontColor; // render in correct colour 37852 ctx.font = labelFont; 37853 37854 var boxWidth = getBoxWidth(labelOpts, fontSize); 37855 var hitboxes = me.legendHitBoxes; 37856 37857 // current position 37858 var drawLegendBox = function(x, y, legendItem) { 37859 if (isNaN(boxWidth) || boxWidth <= 0) { 37860 return; 37861 } 37862 37863 // Set the ctx for the box 37864 ctx.save(); 37865 37866 ctx.fillStyle = valueOrDefault(legendItem.fillStyle, globalDefault.defaultColor); 37867 ctx.lineCap = valueOrDefault(legendItem.lineCap, lineDefault.borderCapStyle); 37868 ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset); 37869 ctx.lineJoin = valueOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle); 37870 ctx.lineWidth = valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth); 37871 ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, globalDefault.defaultColor); 37872 var isLineWidthZero = (valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0); 37873 37874 if (ctx.setLineDash) { 37875 // IE 9 and 10 do not support line dash 37876 ctx.setLineDash(valueOrDefault(legendItem.lineDash, lineDefault.borderDash)); 37877 } 37878 37879 if (opts.labels && opts.labels.usePointStyle) { 37880 // Recalculate x and y for drawPoint() because its expecting 37881 // x and y to be center of figure (instead of top left) 37882 var radius = fontSize * Math.SQRT2 / 2; 37883 var offSet = radius / Math.SQRT2; 37884 var centerX = x + offSet; 37885 var centerY = y + offSet; 37886 37887 // Draw pointStyle as legend symbol 37888 helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY); 37889 } else { 37890 // Draw box as legend symbol
37891 if (!isLineWidthZero) { 37892 ctx.strokeRect(x, y, boxWidth, fontSize); 37893 } 37894 ctx.fillRect(x, y, boxWidth, fontSize); 37895 } 37896 37897 ctx.restore(); 37898 }; 37899 var fillText = function(x, y, legendItem, textWidth) { 37900 var halfFontSize = fontSize / 2; 37901 var xLeft = boxWidth + halfFontSize + x; 37902 var yMiddle = y + halfFontSize; 37903 37904 ctx.fillText(legendItem.text, xLeft, yMiddle); 37905 37906 if (legendItem.hidden) { 37907 // Strikethrough the text if hidden 37908 ctx.beginPath(); 37909 ctx.lineWidth = 2; 37910 ctx.moveTo(xLeft, yMiddle); 37911 ctx.lineTo(xLeft + textWidth, yMiddle); 37912 ctx.stroke(); 37913 } 37914 }; 37915 37916 // Horizontal 37917 var isHorizontal = me.isHorizontal(); 37918 if (isHorizontal) { 37919 cursor = { 37920 x: me.left + ((legendWidth - lineWidths[0]) / 2), 37921 y: me.top + labelOpts.padding, 37922 line: 0 37923 }; 37924 } else { 37925 cursor = { 37926 x: me.left + labelOpts.padding, 37927 y: me.top + labelOpts.padding, 37928 line: 0 37929 }; 37930 } 37931 37932 var itemHeight = fontSize + labelOpts.padding; 37933 helpers.each(me.legendItems, function(legendItem, i) { 37934 var textWidth = ctx.measureText(legendItem.text).width; 37935 var width = boxWidth + (fontSize / 2) + textWidth; 37936 var x = cursor.x; 37937 var y = cursor.y; 37938 37939 if (isHorizontal) { 37940 if (x + width >= legendWidth) { 37941 y = cursor.y += itemHeight; 37942 cursor.line++; 37943 x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2); 37944 } 37945 } else if (y + itemHeight > me.bottom) { 37946 x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding; 37947 y = cursor.y = me.top + labelOpts.padding; 37948 cursor.line++; 37949 } 37950 37951 drawLegendBox(x, y, legendItem); 37952 37953 hitboxes[i].left = x; 37954 hitboxes[i].top = y; 37955 37956 // Fill the actual label 37957 fillText(x, y, legendItem, textWidth); 37958 37959 if (isHorizontal) { 37960 cursor.x += width + (labelOpts.padding); 37961 } else { 37962 cursor.y += itemHeight; 37963 } 37964 37965 }); 37966 } 37967 }, 37968 37969 /** 37970 * Handle an event 37971 * @private 37972 * @param {IEvent} event - The event to handle 37973 * @return {Boolean} true if a change occured 37974 */ 37975 handleEvent: function(e) { 37976 var me = this; 37977 var opts = me.options; 37978 var type = e.type === 'mouseup' ? 'click' : e.type; 37979 var changed = false; 37980 37981 if (type === 'mousemove') { 37982 if (!opts.onHover) { 37983 return; 37984 } 37985 } else if (type === 'click') { 37986 if (!opts.onClick) { 37987 return; 37988 } 37989 } else { 37990 return; 37991 } 37992 37993 // Chart event already has relative position in it 37994 var x = e.x; 37995 var y = e.y; 37996 37997 if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) { 37998 // See if we are touching one of the dataset boxes 37999 var lh = me.legendHitBoxes; 38000 for (var i = 0; i < lh.length; ++i) { 38001 var hitBox = lh[i]; 38002 38003 if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) { 38004 // Touching an element 38005 if (type === 'click') { 38006 // use e.native for backwards compatibility 38007 opts.onClick.call(me, e.native, me.legendItems[i]); 38008 changed = true; 38009 break; 38010 } else if (type === 'mousemove') { 38011 // use e.native for backwards compatibility 38012 opts.onHover.call(me, e.native, me.legendItems[i]); 38013 changed = true; 38014 break; 38015 } 38016 } 38017 } 38018 } 38019 38020 return changed; 38021 } 38022}); 38023 38024function createNewLegendAndAttach(chart, legendOpts) { 38025 var legend = new Legend({ 38026 ctx: chart.ctx, 38027 options: legendOpts, 38028 chart: chart 38029 }); 38030 38031 layouts.configure(chart, legend, legendOpts); 38032 layouts.addBox(chart, legend); 38033 chart.legend = legend; 38034} 38035 38036module.exports = { 38037 id: 'legend', 38038 38039 /** 38040 * Backward compatibility: since 2.1.5, the legend is registered as a plugin, making 38041 * Chart.Legend obsolete. To avoid a breaking change, we export the Legend as part of 38042 * the plugin, which one will be re-exposed in the chart.js file. 38043 * https://github.com/chartjs/Chart.js/pull/2640 38044 * @private 38045 */ 38046 _element: Legend, 38047 38048 beforeInit: function(chart) { 38049 var legendOpts = chart.options.legend; 38050 38051 if (legendOpts) { 38052 createNewLegendAndAttach(chart, legendOpts); 38053 } 38054 }, 38055 38056 beforeUpdate: function(chart) { 38057 var legendOpts = chart.options.legend; 38058 var legend = chart.legend; 38059 38060 if (legendOpts) { 38061 helpers.mergeIf(legendOpts, defaults.global.legend); 38062 38063 if (legend) { 38064 layouts.configure(chart, legend, legendOpts); 38065 legend.options = legendOpts; 38066 } else { 38067 createNewLegendAndAttach(chart, legendOpts); 38068 } 38069 } else if (legend) { 38070 layouts.removeBox(chart, legend); 38071 delete chart.legend; 38072 } 38073 }, 38074
38075 afterEvent: function(chart, e) { 38076 var legend = chart.legend; 38077 if (legend) { 38078 legend.handleEvent(e); 38079 } 38080 } 38081}; 38082 38083},{"25":25,"26":26,"30":30,"45":45}],52:[function(require,module,exports){ 38084'use strict'; 38085 38086var defaults = require(25); 38087var Element = require(26); 38088var helpers = require(45); 38089var layouts = require(30); 38090 38091var noop = helpers.noop; 38092 38093defaults._set('global', { 38094 title: { 38095 display: false, 38096 fontStyle: 'bold', 38097 fullWidth: true, 38098 lineHeight: 1.2, 38099 padding: 10, 38100 position: 'top', 38101 text: '', 38102 weight: 2000 // by default greater than legend (1000) to be above 38103 } 38104}); 38105 38106/** 38107 * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required! 38108 */ 38109var Title = Element.extend({ 38110 initialize: function(config) { 38111 var me = this; 38112 helpers.extend(me, config); 38113 38114 // Contains hit boxes for each dataset (in dataset order) 38115 me.legendHitBoxes = []; 38116 }, 38117 38118 // These methods are ordered by lifecycle. Utilities then follow. 38119 38120 beforeUpdate: noop, 38121 update: function(maxWidth, maxHeight, margins) { 38122 var me = this; 38123 38124 // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) 38125 me.beforeUpdate(); 38126 38127 // Absorb the master measurements 38128 me.maxWidth = maxWidth; 38129 me.maxHeight = maxHeight; 38130 me.margins = margins; 38131 38132 // Dimensions 38133 me.beforeSetDimensions(); 38134 me.setDimensions(); 38135 me.afterSetDimensions(); 38136 // Labels 38137 me.beforeBuildLabels(); 38138 me.buildLabels(); 38139 me.afterBuildLabels(); 38140 38141 // Fit 38142 me.beforeFit(); 38143 me.fit(); 38144 me.afterFit(); 38145 // 38146 me.afterUpdate(); 38147 38148 return me.minSize; 38149 38150 }, 38151 afterUpdate: noop, 38152 38153 // 38154 38155 beforeSetDimensions: noop, 38156 setDimensions: function() { 38157 var me = this; 38158 // Set the unconstrained dimension before label rotation 38159 if (me.isHorizontal()) { 38160 // Reset position before calculating rotation 38161 me.width = me.maxWidth; 38162 me.left = 0; 38163 me.right = me.width; 38164 } else { 38165 me.height = me.maxHeight; 38166 38167 // Reset position before calculating rotation 38168 me.top = 0; 38169 me.bottom = me.height; 38170 } 38171 38172 // Reset padding 38173 me.paddingLeft = 0; 38174 me.paddingTop = 0; 38175 me.paddingRight = 0; 38176 me.paddingBottom = 0; 38177 38178 // Reset minSize 38179 me.minSize = { 38180 width: 0, 38181 height: 0 38182 }; 38183 }, 38184 afterSetDimensions: noop, 38185 38186 // 38187 38188 beforeBuildLabels: noop, 38189 buildLabels: noop, 38190 afterBuildLabels: noop, 38191 38192 // 38193 38194 beforeFit: noop, 38195 fit: function() { 38196 var me = this; 38197 var valueOrDefault = helpers.valueOrDefault; 38198 var opts = me.options; 38199 var display = opts.display; 38200 var fontSize = valueOrDefault(opts.fontSize, defaults.global.defaultFontSize); 38201 var minSize = me.minSize; 38202 var lineCount = helpers.isArray(opts.text) ? opts.text.length : 1; 38203 var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize); 38204 var textSize = display ? (lineCount * lineHeight) + (opts.padding * 2) : 0; 38205 38206 if (me.isHorizontal()) { 38207 minSize.width = me.maxWidth; // fill all the width 38208 minSize.height = textSize; 38209 } else { 38210 minSize.width = textSize; 38211 minSize.height = me.maxHeight; // fill all the height 38212 } 38213 38214 me.width = minSize.width; 38215 me.height = minSize.height; 38216 38217 }, 38218 afterFit: noop, 38219 38220 // Shared Methods 38221 isHorizontal: function() { 38222 var pos = this.options.position; 38223 return pos === 'top' || pos === 'bottom'; 38224 }, 38225 38226 // Actually draw the title block on the canvas 38227 draw: function() { 38228 var me = this; 38229 var ctx = me.ctx; 38230 var valueOrDefault = helpers.valueOrDefault; 38231 var opts = me.options; 38232 var globalDefaults = defaults.global; 38233 38234 if (opts.display) { 38235 var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize); 38236 var fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle); 38237 var fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily); 38238 var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily); 38239 var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize); 38240 var offset = lineHeight / 2 + opts.padding; 38241 var rotation = 0; 38242 var top = me.top; 38243 var left = me.left; 38244 var bottom = me.bottom; 38245 var right = me.right; 38246 var maxWidth, titleX, titleY; 38247 38248 ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour 38249 ctx.font = titleFont; 38250 38251 // Horizontal 38252 if (me.isHorizontal()) { 38253 titleX = left + ((right - left) / 2); // midpoint of the width 38254 titleY = top + offset; 38255 maxWidth = right - left; 38256 } else { 38257 titleX = opts.position === 'left' ? left + offset : right - offset; 38258 titleY = top + ((bottom - top) / 2); 38259 maxWidth = bottom - top; 38260 rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5); 38261 } 38262 38263 ctx.save(); 38264 ctx.translate(titleX, titleY); 38265 ctx.rotate(rotation); 38266 ctx.textAlign = 'center'; 38267 ctx.textBaseline = 'middle'; 38268 38269 var text = opts.text; 38270 if (helpers.isArray(text)) { 38271 var y = 0; 38272 for (var i = 0; i < text.length; ++i) { 38273 ctx.fillText(text[i], 0, y, maxWidth); 38274 y += lineHeight; 38275 } 38276 } else { 38277 ctx.fillText(text, 0, 0, maxWidth); 38278 } 38279
38280 ctx.restore(); 38281 } 38282 } 38283}); 38284 38285function createNewTitleBlockAndAttach(chart, titleOpts) { 38286 var title = new Title({ 38287 ctx: chart.ctx, 38288 options: titleOpts, 38289 chart: chart 38290 }); 38291 38292 layouts.configure(chart, title, titleOpts); 38293 layouts.addBox(chart, title); 38294 chart.titleBlock = title; 38295} 38296 38297module.exports = { 38298 id: 'title', 38299 38300 /** 38301 * Backward compatibility: since 2.1.5, the title is registered as a plugin, making 38302 * Chart.Title obsolete. To avoid a breaking change, we export the Title as part of 38303 * the plugin, which one will be re-exposed in the chart.js file. 38304 * https://github.com/chartjs/Chart.js/pull/2640 38305 * @private 38306 */ 38307 _element: Title, 38308 38309 beforeInit: function(chart) { 38310 var titleOpts = chart.options.title; 38311 38312 if (titleOpts) { 38313 createNewTitleBlockAndAttach(chart, titleOpts); 38314 } 38315 }, 38316 38317 beforeUpdate: function(chart) { 38318 var titleOpts = chart.options.title; 38319 var titleBlock = chart.titleBlock; 38320 38321 if (titleOpts) { 38322 helpers.mergeIf(titleOpts, defaults.global.title); 38323 38324 if (titleBlock) { 38325 layouts.configure(chart, titleBlock, titleOpts); 38326 titleBlock.options = titleOpts; 38327 } else { 38328 createNewTitleBlockAndAttach(chart, titleOpts); 38329 } 38330 } else if (titleBlock) { 38331 layouts.removeBox(chart, titleBlock); 38332 delete chart.titleBlock; 38333 } 38334 } 38335}; 38336 38337},{"25":25,"26":26,"30":30,"45":45}],53:[function(require,module,exports){ 38338'use strict'; 38339 38340module.exports = function(Chart) { 38341 38342 // Default config for a category scale 38343 var defaultConfig = { 38344 position: 'bottom' 38345 }; 38346 38347 var DatasetScale = Chart.Scale.extend({ 38348 /** 38349 * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those 38350 * else fall back to data.labels 38351 * @private 38352 */ 38353 getLabels: function() { 38354 var data = this.chart.data; 38355 return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels; 38356 }, 38357 38358 determineDataLimits: function() { 38359 var me = this; 38360 var labels = me.getLabels(); 38361 me.minIndex = 0; 38362 me.maxIndex = labels.length - 1; 38363 var findIndex; 38364 38365 if (me.options.ticks.min !== undefined) { 38366 // user specified min value 38367 findIndex = labels.indexOf(me.options.ticks.min); 38368 me.minIndex = findIndex !== -1 ? findIndex : me.minIndex; 38369 } 38370 38371 if (me.options.ticks.max !== undefined) { 38372 // user specified max value 38373 findIndex = labels.indexOf(me.options.ticks.max); 38374 me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex; 38375 } 38376 38377 me.min = labels[me.minIndex]; 38378 me.max = labels[me.maxIndex]; 38379 }, 38380 38381 buildTicks: function() { 38382 var me = this; 38383 var labels = me.getLabels(); 38384 // If we are viewing some subset of labels, slice the original array 38385 me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1); 38386 }, 38387 38388 getLabelForIndex: function(index, datasetIndex) { 38389 var me = this; 38390 var data = me.chart.data; 38391 var isHorizontal = me.isHorizontal(); 38392 38393 if (data.yLabels && !isHorizontal) { 38394 return me.getRightValue(data.datasets[datasetIndex].data[index]); 38395 } 38396 return me.ticks[index - me.minIndex]; 38397 }, 38398 38399 // Used to get data value locations. Value can either be an index or a numerical value 38400 getPixelForValue: function(value, index) { 38401 var me = this; 38402 var offset = me.options.offset; 38403 // 1 is added because we need the length but we have the indexes 38404 var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1)), 1); 38405 38406 // If value is a data object, then index is the index in the data array, 38407 // not the index of the scale. We need to change that. 38408 var valueCategory; 38409 if (value !== undefined && value !== null) { 38410 valueCategory = me.isHorizontal() ? value.x : value.y; 38411 } 38412 if (valueCategory !== undefined || (value !== undefined && isNaN(index))) { 38413 var labels = me.getLabels(); 38414 value = valueCategory || value; 38415 var idx = labels.indexOf(value); 38416 index = idx !== -1 ? idx : index; 38417 } 38418 38419 if (me.isHorizontal()) { 38420 var valueWidth = me.width / offsetAmt; 38421 var widthOffset = (valueWidth * (index - me.minIndex)); 38422 38423 if (offset) { 38424 widthOffset += (valueWidth / 2); 38425 } 38426 38427 return me.left + Math.round(widthOffset); 38428 } 38429 var valueHeight = me.height / offsetAmt; 38430 var heightOffset = (valueHeight * (index - me.minIndex)); 38431 38432 if (offset) { 38433 heightOffset += (valueHeight / 2); 38434 } 38435 38436 return me.top + Math.round(heightOffset); 38437 }, 38438 getPixelForTick: function(index) { 38439 return this.getPixelForValue(this.ticks[index], index + this.minIndex, null); 38440 }, 38441 getValueForPixel: function(pixel) { 38442 var me = this; 38443 var offset = me.options.offset; 38444 var value; 38445 var offsetAmt = Math.max((me._ticks.length - (offset ? 0 : 1)), 1); 38446 var horz = me.isHorizontal(); 38447 var valueDimension = (horz ? me.width : me.height) / offsetAmt; 38448 38449 pixel -= horz ? me.left : me.top; 38450 38451 if (offset) { 38452 pixel -= (valueDimension / 2); 38453 } 38454 38455 if (pixel <= 0) { 38456 value = 0; 38457 } else { 38458 value = Math.round(pixel / valueDimension); 38459 } 38460 38461 return value + me.minIndex; 38462 }, 38463 getBasePixel: function() { 38464 return this.bottom; 38465 } 38466 }); 38467 38468 Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig); 38469 38470}; 38471 38472},{}],54:[function(require,module,exports){ 38473'use strict'; 38474 38475var defaults = require(25); 38476var helpers = require(45); 38477var Ticks = require(34); 38478 38479module.exports = function(Chart) { 38480 38481 var defaultConfig = { 38482 position: 'left', 38483 ticks: { 38484 callback: Ticks.formatters.linear 38485 } 38486 }; 38487 38488 var LinearScale = Chart.LinearScaleBase.extend({ 38489 38490 determineDataLimits: function() { 38491 var me = this; 38492 var opts = me.options; 38493 var chart = me.chart; 38494 var data = chart.data; 38495 var datasets = data.datasets; 38496 var isHorizontal = me.isHorizontal(); 38497 var DEFAULT_MIN = 0; 38498 var DEFAULT_MAX = 1; 38499 38500 function IDMatches(meta) { 38501 return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id; 38502 } 38503 38504 // First Calculate the range 38505 me.min = null; 38506 me.max = null; 38507 38508 var hasStacks = opts.stacked; 38509 if (hasStacks === undefined) { 38510 helpers.each(datasets, function(dataset, datasetIndex) { 38511 if (hasStacks) { 38512 return; 38513 } 38514 38515 var meta = chart.getDatasetMeta(datasetIndex); 38516 if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) && 38517 meta.stack !== undefined) { 38518 hasStacks = true; 38519 } 38520 }); 38521 } 38522 38523 if (opts.stacked || hasStacks) { 38524 var valuesPerStack = {}; 38525 38526 helpers.each(datasets, function(dataset, datasetIndex) { 38527 var meta = chart.getDatasetMeta(datasetIndex); 38528 var key = [ 38529 meta.type, 38530 // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined 38531 ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''), 38532 meta.stack 38533 ].join('.'); 38534 38535 if (valuesPerStack[key] === undefined) { 38536 valuesPerStack[key] = { 38537 positiveValues: [], 38538 negativeValues: [] 38539 }; 38540 } 38541 38542 // Store these per type 38543 var positiveValues = valuesPerStack[key].positiveValues; 38544 var negativeValues = valuesPerStack[key].negativeValues; 38545 38546 if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { 38547 helpers.each(dataset.data, function(rawValue, index) { 38548 var value = +me.getRightValue(rawValue); 38549 if (isNaN(value) || meta.data[index].hidden) { 38550 return; 38551 } 38552 38553 positiveValues[index] = positiveValues[index] || 0; 38554 negativeValues[index] = negativeValues[index] || 0; 38555 38556 if (opts.relativePoints) { 38557 positiveValues[index] = 100; 38558 } else if (value < 0) { 38559 negativeValues[index] += value; 38560 } else { 38561 positiveValues[index] += value; 38562 } 38563 }); 38564 } 38565 }); 38566 38567 helpers.each(valuesPerStack, function(valuesForType) { 38568 var values = valuesForType.positiveValues.concat(valuesForType.negativeValues); 38569 var minVal = helpers.min(values); 38570 var maxVal = helpers.max(values); 38571 me.min = me.min === null ? minVal : Math.min(me.min, minVal); 38572 me.max = me.max === null ? maxVal : Math.max(me.max, maxVal); 38573 }); 38574 38575 } else { 38576 helpers.each(datasets, function(dataset, datasetIndex) { 38577 var meta = chart.getDatasetMeta(datasetIndex); 38578 if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { 38579 helpers.each(dataset.data, function(rawValue, index) { 38580 var value = +me.getRightValue(rawValue); 38581 if (isNaN(value) || meta.data[index].hidden) { 38582 return; 38583 } 38584 38585 if (me.min === null) { 38586 me.min = value; 38587 } else if (value < me.min) { 38588 me.min = value; 38589 } 38590 38591 if (me.max === null) { 38592 me.max = value; 38593 } else if (value > me.max) { 38594 me.max = value; 38595 } 38596 }); 38597 } 38598 }); 38599 } 38600 38601 me.min = isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN; 38602 me.max = isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX; 38603 38604 // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero 38605 this.handleTickRangeOptions(); 38606 }, 38607 getTickLimit: function() { 38608 var maxTicks; 38609 var me = this; 38610 var tickOpts = me.options.ticks; 38611 38612 if (me.isHorizontal()) { 38613 maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50)); 38614 } else { 38615 // The factor of 2 used to scale the font size has been experimentally determined.
38616 var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, defaults.global.defaultFontSize); 38617 maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize))); 38618 } 38619 38620 return maxTicks; 38621 }, 38622 // Called after the ticks are built. We need 38623 handleDirectionalChanges: function() { 38624 if (!this.isHorizontal()) { 38625 // We are in a vertical orientation. The top value is the highest. So reverse the array 38626 this.ticks.reverse(); 38627 } 38628 }, 38629 getLabelForIndex: function(index, datasetIndex) { 38630 return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); 38631 }, 38632 // Utils 38633 getPixelForValue: function(value) { 38634 // This must be called after fit has been run so that 38635 // this.left, this.top, this.right, and this.bottom have been defined 38636 var me = this; 38637 var start = me.start; 38638 38639 var rightValue = +me.getRightValue(value); 38640 var pixel; 38641 var range = me.end - start; 38642 38643 if (me.isHorizontal()) { 38644 pixel = me.left + (me.width / range * (rightValue - start)); 38645 } else { 38646 pixel = me.bottom - (me.height / range * (rightValue - start)); 38647 } 38648 return pixel; 38649 }, 38650 getValueForPixel: function(pixel) { 38651 var me = this; 38652 var isHorizontal = me.isHorizontal(); 38653 var innerDimension = isHorizontal ? me.width : me.height; 38654 var offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension; 38655 return me.start + ((me.end - me.start) * offset); 38656 }, 38657 getPixelForTick: function(index) { 38658 return this.getPixelForValue(this.ticksAsNumbers[index]); 38659 } 38660 }); 38661 Chart.scaleService.registerScaleType('linear', LinearScale, defaultConfig); 38662 38663}; 38664 38665},{"25":25,"34":34,"45":45}],55:[function(require,module,exports){ 38666'use strict'; 38667 38668var helpers = require(45); 38669 38670/** 38671 * Generate a set of linear ticks 38672 * @param generationOptions the options used to generate the ticks 38673 * @param dataRange the range of the data 38674 * @returns {Array<Number>} array of tick values 38675 */ 38676function generateTicks(generationOptions, dataRange) { 38677 var ticks = []; 38678 // To get a "nice" value for the tick spacing, we will use the appropriately named 38679 // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks 38680 // for details. 38681 38682 var spacing; 38683 if (generationOptions.stepSize && generationOptions.stepSize > 0) { 38684 spacing = generationOptions.stepSize; 38685 } else { 38686 var niceRange = helpers.niceNum(dataRange.max - dataRange.min, false); 38687 spacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true); 38688 } 38689 var niceMin = Math.floor(dataRange.min / spacing) * spacing; 38690 var niceMax = Math.ceil(dataRange.max / spacing) * spacing; 38691 38692 // If min, max and stepSize is set and they make an evenly spaced scale use it. 38693 if (generationOptions.min && generationOptions.max && generationOptions.stepSize) { 38694 // If very close to our whole number, use it. 38695 if (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) { 38696 niceMin = generationOptions.min; 38697 niceMax = generationOptions.max; 38698 } 38699 } 38700 38701 var numSpaces = (niceMax - niceMin) / spacing; 38702 // If very close to our rounded value, use it. 38703 if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) { 38704 numSpaces = Math.round(numSpaces); 38705 } else { 38706 numSpaces = Math.ceil(numSpaces); 38707 } 38708 38709 var precision = 1; 38710 if (spacing < 1) { 38711 precision = Math.pow(10, spacing.toString().length - 2); 38712 niceMin = Math.round(niceMin * precision) / precision; 38713 niceMax = Math.round(niceMax * precision) / precision; 38714 } 38715 ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin); 38716 for (var j = 1; j < numSpaces; ++j) { 38717 ticks.push(Math.round((niceMin + j * spacing) * precision) / precision); 38718 } 38719 ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax); 38720 38721 return ticks; 38722} 38723 38724 38725module.exports = function(Chart) { 38726 38727 var noop = helpers.noop; 38728 38729 Chart.LinearScaleBase = Chart.Scale.extend({ 38730 getRightValue: function(value) { 38731 if (typeof value === 'string') { 38732 return +value; 38733 } 38734 return Chart.Scale.prototype.getRightValue.call(this, value); 38735 }, 38736 38737 handleTickRangeOptions: function() { 38738 var me = this; 38739 var opts = me.options; 38740 var tickOpts = opts.ticks; 38741 38742 // If we are forcing it to begin at 0, but 0 will already be rendered on the chart, 38743 // do nothing since that would make the chart weird. If the user really wants a weird chart 38744 // axis, they can manually override it 38745 if (tickOpts.beginAtZero) { 38746 var minSign = helpers.sign(me.min); 38747 var maxSign = helpers.sign(me.max); 38748 38749 if (minSign < 0 && maxSign < 0) { 38750 // move the top up to 0 38751 me.max = 0; 38752 } else if (minSign > 0 && maxSign > 0) { 38753 // move the bottom down to 0 38754 me.min = 0; 38755 } 38756 } 38757 38758 var setMin = tickOpts.min !== undefined || tickOpts.suggestedMin !== undefined; 38759 var setMax = tickOpts.max !== undefined || tickOpts.suggestedMax !== undefined; 38760 38761 if (tickOpts.min !== undefined) { 38762 me.min = tickOpts.min; 38763 } else if (tickOpts.suggestedMin !== undefined) { 38764 if (me.min === null) { 38765 me.min = tickOpts.suggestedMin; 38766 } else { 38767 me.min = Math.min(me.min, tickOpts.suggestedMin); 38768 } 38769 } 38770 38771 if (tickOpts.max !== undefined) { 38772 me.max = tickOpts.max; 38773 } else if (tickOpts.suggestedMax !== undefined) { 38774 if (me.max === null) { 38775 me.max = tickOpts.suggestedMax; 38776 } else { 38777 me.max = Math.max(me.max, tickOpts.suggestedMax); 38778 } 38779 } 38780 38781 if (setMin !== setMax) { 38782 // We set the min or the max but not both. 38783 // So ensure that our range is good 38784 // Inverted or 0 length range can happen when
38785 // ticks.min is set, and no datasets are visible 38786 if (me.min >= me.max) { 38787 if (setMin) { 38788 me.max = me.min + 1; 38789 } else { 38790 me.min = me.max - 1; 38791 } 38792 } 38793 } 38794 38795 if (me.min === me.max) { 38796 me.max++; 38797 38798 if (!tickOpts.beginAtZero) { 38799 me.min--; 38800 } 38801 } 38802 }, 38803 getTickLimit: noop, 38804 handleDirectionalChanges: noop, 38805 38806 buildTicks: function() { 38807 var me = this; 38808 var opts = me.options; 38809 var tickOpts = opts.ticks; 38810 38811 // Figure out what the max number of ticks we can support it is based on the size of 38812 // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 38813 // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on 38814 // the graph. Make sure we always have at least 2 ticks 38815 var maxTicks = me.getTickLimit(); 38816 maxTicks = Math.max(2, maxTicks); 38817 38818 var numericGeneratorOptions = { 38819 maxTicks: maxTicks, 38820 min: tickOpts.min, 38821 max: tickOpts.max, 38822 stepSize: helpers.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize) 38823 }; 38824 var ticks = me.ticks = generateTicks(numericGeneratorOptions, me); 38825 38826 me.handleDirectionalChanges(); 38827 38828 // At this point, we need to update our max and min given the tick values since we have expanded the 38829 // range of the scale 38830 me.max = helpers.max(ticks); 38831 me.min = helpers.min(ticks); 38832 38833 if (tickOpts.reverse) { 38834 ticks.reverse(); 38835 38836 me.start = me.max; 38837 me.end = me.min; 38838 } else { 38839 me.start = me.min; 38840 me.end = me.max; 38841 } 38842 }, 38843 convertTicksToLabels: function() { 38844 var me = this; 38845 me.ticksAsNumbers = me.ticks.slice(); 38846 me.zeroLineIndex = me.ticks.indexOf(0); 38847 38848 Chart.Scale.prototype.convertTicksToLabels.call(me); 38849 } 38850 }); 38851}; 38852 38853},{"45":45}],56:[function(require,module,exports){ 38854'use strict'; 38855 38856var helpers = require(45); 38857var Ticks = require(34); 38858 38859/** 38860 * Generate a set of logarithmic ticks 38861 * @param generationOptions the options used to generate the ticks 38862 * @param dataRange the range of the data 38863 * @returns {Array<Number>} array of tick values 38864 */ 38865function generateTicks(generationOptions, dataRange) { 38866 var ticks = []; 38867 var valueOrDefault = helpers.valueOrDefault; 38868 38869 // Figure out what the max number of ticks we can support it is based on the size of 38870 // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 38871 // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on 38872 // the graph 38873 var tickVal = valueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min)))); 38874 38875 var endExp = Math.floor(helpers.log10(dataRange.max)); 38876 var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp)); 38877 var exp, significand; 38878 38879 if (tickVal === 0) { 38880 exp = Math.floor(helpers.log10(dataRange.minNotZero)); 38881 significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp)); 38882 38883 ticks.push(tickVal); 38884 tickVal = significand * Math.pow(10, exp); 38885 } else { 38886 exp = Math.floor(helpers.log10(tickVal)); 38887 significand = Math.floor(tickVal / Math.pow(10, exp)); 38888 } 38889 var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1; 38890 38891 do { 38892 ticks.push(tickVal); 38893 38894 ++significand; 38895 if (significand === 10) { 38896 significand = 1; 38897 ++exp; 38898 precision = exp >= 0 ? 1 : precision; 38899 } 38900 38901 tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision; 38902 } while (exp < endExp || (exp === endExp && significand < endSignificand)); 38903 38904 var lastTick = valueOrDefault(generationOptions.max, tickVal); 38905 ticks.push(lastTick); 38906 38907 return ticks; 38908} 38909 38910 38911module.exports = function(Chart) { 38912 38913 var defaultConfig = { 38914 position: 'left', 38915 38916 // label settings 38917 ticks: { 38918 callback: Ticks.formatters.logarithmic 38919 } 38920 }; 38921 38922 var LogarithmicScale = Chart.Scale.extend({ 38923 determineDataLimits: function() { 38924 var me = this; 38925 var opts = me.options; 38926 var chart = me.chart; 38927 var data = chart.data; 38928 var datasets = data.datasets; 38929 var isHorizontal = me.isHorizontal(); 38930 function IDMatches(meta) { 38931 return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id; 38932 } 38933 38934 // Calculate Range 38935 me.min = null; 38936 me.max = null; 38937 me.minNotZero = null; 38938 38939 var hasStacks = opts.stacked; 38940 if (hasStacks === undefined) { 38941 helpers.each(datasets, function(dataset, datasetIndex) { 38942 if (hasStacks) { 38943 return; 38944 } 38945 38946 var meta = chart.getDatasetMeta(datasetIndex); 38947 if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) && 38948 meta.stack !== undefined) { 38949 hasStacks = true; 38950 } 38951 }); 38952 } 38953 38954 if (opts.stacked || hasStacks) { 38955 var valuesPerStack = {}; 38956 38957 helpers.each(datasets, function(dataset, datasetIndex) { 38958 var meta = chart.getDatasetMeta(datasetIndex); 38959 var key = [ 38960 meta.type, 38961 // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined 38962 ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''), 38963 meta.stack 38964 ].join('.'); 38965 38966 if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { 38967 if (valuesPerStack[key] === undefined) { 38968 valuesPerStack[key] = []; 38969 } 38970 38971 helpers.each(dataset.data, function(rawValue, index) { 38972 var values = valuesPerStack[key]; 38973 var value = +me.getRightValue(rawValue); 38974 // invalid, hidden and negative values are ignored 38975 if (isNaN(value) || meta.data[index].hidden || value < 0) { 38976 return; 38977 } 38978 values[index] = values[index] || 0; 38979 values[index] += value; 38980 }); 38981 } 38982 }); 38983 38984 helpers.each(valuesPerStack, function(valuesForType) { 38985 if (valuesForType.length > 0) { 38986 var minVal = helpers.min(valuesForType); 38987 var maxVal = helpers.max(valuesForType); 38988 me.min = me.min === null ? minVal : Math.min(me.min, minVal); 38989 me.max = me.max === null ? maxVal : Math.max(me.max, maxVal); 38990 } 38991 }); 38992 38993 } else { 38994 helpers.each(datasets, function(dataset, datasetIndex) { 38995 var meta = chart.getDatasetMeta(datasetIndex); 38996 if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { 38997 helpers.each(dataset.data, function(rawValue, index) { 38998 var value = +me.getRightValue(rawValue); 38999 // invalid, hidden and negative values are ignored 39000 if (isNaN(value) || meta.data[index].hidden || value < 0) { 39001 return; 39002 } 39003 39004 if (me.min === null) { 39005 me.min = value; 39006 } else if (value < me.min) { 39007 me.min = value; 39008 } 39009 39010 if (me.max === null) { 39011 me.max = value; 39012 } else if (value > me.max) { 39013 me.max = value; 39014 } 39015 39016 if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) { 39017 me.minNotZero = value; 39018 } 39019 }); 39020 } 39021 }); 39022 } 39023 39024 // Common base implementation to handle ticks.min, ticks.max 39025 this.handleTickRangeOptions(); 39026 }, 39027 handleTickRangeOptions: function() { 39028 var me = this; 39029 var opts = me.options; 39030 var tickOpts = opts.ticks; 39031 var valueOrDefault = helpers.valueOrDefault; 39032 var DEFAULT_MIN = 1; 39033 var DEFAULT_MAX = 10; 39034 39035 me.min = valueOrDefault(tickOpts.min, me.min); 39036 me.max = valueOrDefault(tickOpts.max, me.max); 39037 39038 if (me.min === me.max) { 39039 if (me.min !== 0 && me.min !== null) {
39040 me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1); 39041 me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1); 39042 } else { 39043 me.min = DEFAULT_MIN; 39044 me.max = DEFAULT_MAX; 39045 } 39046 } 39047 if (me.min === null) { 39048 me.min = Math.pow(10, Math.floor(helpers.log10(me.max)) - 1); 39049 } 39050 if (me.max === null) { 39051 me.max = me.min !== 0 39052 ? Math.pow(10, Math.floor(helpers.log10(me.min)) + 1) 39053 : DEFAULT_MAX; 39054 } 39055 if (me.minNotZero === null) { 39056 if (me.min > 0) { 39057 me.minNotZero = me.min; 39058 } else if (me.max < 1) { 39059 me.minNotZero = Math.pow(10, Math.floor(helpers.log10(me.max))); 39060 } else { 39061 me.minNotZero = DEFAULT_MIN; 39062 } 39063 } 39064 }, 39065 buildTicks: function() { 39066 var me = this; 39067 var opts = me.options; 39068 var tickOpts = opts.ticks; 39069 var reverse = !me.isHorizontal(); 39070 39071 var generationOptions = { 39072 min: tickOpts.min, 39073 max: tickOpts.max 39074 }; 39075 var ticks = me.ticks = generateTicks(generationOptions, me); 39076 39077 // At this point, we need to update our max and min given the tick values since we have expanded the 39078 // range of the scale 39079 me.max = helpers.max(ticks); 39080 me.min = helpers.min(ticks); 39081 39082 if (tickOpts.reverse) { 39083 reverse = !reverse; 39084 me.start = me.max; 39085 me.end = me.min; 39086 } else { 39087 me.start = me.min; 39088 me.end = me.max; 39089 } 39090 if (reverse) { 39091 ticks.reverse(); 39092 } 39093 }, 39094 convertTicksToLabels: function() { 39095 this.tickValues = this.ticks.slice(); 39096 39097 Chart.Scale.prototype.convertTicksToLabels.call(this); 39098 }, 39099 // Get the correct tooltip label 39100 getLabelForIndex: function(index, datasetIndex) { 39101 return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); 39102 }, 39103 getPixelForTick: function(index) { 39104 return this.getPixelForValue(this.tickValues[index]); 39105 }, 39106 /** 39107 * Returns the value of the first tick. 39108 * @param {Number} value - The minimum not zero value. 39109 * @return {Number} The first tick value. 39110 * @private 39111 */ 39112 _getFirstTickValue: function(value) { 39113 var exp = Math.floor(helpers.log10(value)); 39114 var significand = Math.floor(value / Math.pow(10, exp)); 39115 39116 return significand * Math.pow(10, exp); 39117 }, 39118 getPixelForValue: function(value) { 39119 var me = this; 39120 var reverse = me.options.ticks.reverse; 39121 var log10 = helpers.log10; 39122 var firstTickValue = me._getFirstTickValue(me.minNotZero); 39123 var offset = 0; 39124 var innerDimension, pixel, start, end, sign; 39125 39126 value = +me.getRightValue(value); 39127 if (reverse) { 39128 start = me.end; 39129 end = me.start; 39130 sign = -1; 39131 } else { 39132 start = me.start; 39133 end = me.end; 39134 sign = 1; 39135 } 39136 if (me.isHorizontal()) { 39137 innerDimension = me.width; 39138 pixel = reverse ? me.right : me.left; 39139 } else { 39140 innerDimension = me.height; 39141 sign *= -1; // invert, since the upper-left corner of the canvas is at pixel (0, 0) 39142 pixel = reverse ? me.top : me.bottom; 39143 } 39144 if (value !== start) { 39145 if (start === 0) { // include zero tick 39146 offset = helpers.getValueOrDefault( 39147 me.options.ticks.fontSize, 39148 Chart.defaults.global.defaultFontSize 39149 ); 39150 innerDimension -= offset; 39151 start = firstTickValue; 39152 } 39153 if (value !== 0) { 39154 offset += innerDimension / (log10(end) - log10(start)) * (log10(value) - log10(start)); 39155 } 39156 pixel += sign * offset; 39157 } 39158 return pixel; 39159 }, 39160 getValueForPixel: function(pixel) { 39161 var me = this; 39162 var reverse = me.options.ticks.reverse; 39163 var log10 = helpers.log10; 39164 var firstTickValue = me._getFirstTickValue(me.minNotZero); 39165 var innerDimension, start, end, value; 39166 39167 if (reverse) { 39168 start = me.end; 39169 end = me.start; 39170 } else { 39171 start = me.start; 39172 end = me.end; 39173 } 39174 if (me.isHorizontal()) { 39175 innerDimension = me.width; 39176 value = reverse ? me.right - pixel : pixel - me.left; 39177 } else { 39178 innerDimension = me.height; 39179 value = reverse ? pixel - me.top : me.bottom - pixel; 39180 } 39181 if (value !== start) { 39182 if (start === 0) { // include zero tick 39183 var offset = helpers.getValueOrDefault( 39184 me.options.ticks.fontSize, 39185 Chart.defaults.global.defaultFontSize 39186 ); 39187 value -= offset; 39188 innerDimension -= offset; 39189 start = firstTickValue; 39190 } 39191 value *= log10(end) - log10(start); 39192 value /= innerDimension; 39193 value = Math.pow(10, log10(start) + value); 39194 } 39195 return value; 39196 } 39197 }); 39198 Chart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig); 39199 39200}; 39201 39202},{"34":34,"45":45}],57:[function(require,module,exports){ 39203'use strict'; 39204 39205var defaults = require(25); 39206var helpers = require(45); 39207var Ticks = require(34); 39208 39209module.exports = function(Chart) { 39210 39211 var globalDefaults = defaults.global; 39212 39213 var defaultConfig = { 39214 display: true, 39215 39216 // Boolean - Whether to animate scaling the chart from the centre 39217 animate: true, 39218 position: 'chartArea', 39219 39220 angleLines: { 39221 display: true, 39222 color: 'rgba(0, 0, 0, 0.1)', 39223 lineWidth: 1 39224 }, 39225 39226 gridLines: { 39227 circular: false 39228 }, 39229 39230 // label settings 39231 ticks: { 39232 // Boolean - Show a backdrop to the scale label 39233 showLabelBackdrop: true, 39234 39235 // String - The colour of the label backdrop 39236 backdropColor: 'rgba(255,255,255,0.75)', 39237 39238 // Number - The backdrop padding above & below the label in pixels 39239 backdropPaddingY: 2, 39240 39241 // Number - The backdrop padding to the side of the label in pixels 39242 backdropPaddingX: 2, 39243 39244 callback: Ticks.formatters.linear 39245 }, 39246 39247 pointLabels: { 39248 // Boolean - if true, show point labels 39249 display: true, 39250 39251 // Number - Point label font size in pixels 39252 fontSize: 10, 39253 39254 // Function - Used to convert point labels 39255 callback: function(label) { 39256 return label; 39257 } 39258 } 39259 }; 39260 39261 function getValueCount(scale) { 39262 var opts = scale.options; 39263 return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0; 39264 } 39265 39266 function getPointLabelFontOptions(scale) { 39267 var pointLabelOptions = scale.options.pointLabels; 39268 var fontSize = helpers.valueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize); 39269 var fontStyle = helpers.valueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle); 39270 var fontFamily = helpers.valueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily); 39271 var font = helpers.fontString(fontSize, fontStyle, fontFamily); 39272 39273 return { 39274 size: fontSize, 39275 style: fontStyle, 39276 family: fontFamily, 39277 font: font 39278 }; 39279 } 39280 39281 function measureLabelSize(ctx, fontSize, label) { 39282 if (helpers.isArray(label)) { 39283 return { 39284 w: helpers.longestText(ctx, ctx.font, label), 39285 h: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize) 39286 }; 39287 } 39288 39289 return { 39290 w: ctx.measureText(label).width, 39291 h: fontSize 39292 }; 39293 } 39294 39295 function determineLimits(angle, pos, size, min, max) { 39296 if (angle === min || angle === max) { 39297 return { 39298 start: pos - (size / 2), 39299 end: pos + (size / 2) 39300 }; 39301 } else if (angle < min || angle > max) { 39302 return { 39303 start: pos - size - 5, 39304 end: pos 39305 }; 39306 } 39307 39308 return { 39309 start: pos, 39310 end: pos + size + 5 39311 }; 39312 } 39313 39314 /** 39315 * Helper function to fit a radial linear scale with point labels 39316 */ 39317 function fitWithPointLabels(scale) { 39318 /* 39319 * Right, this is really confusing and there is a lot of maths going on here 39320 * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9 39321 * 39322 * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif 39323 * 39324 * Solution: 39325 * 39326 * We assume the radius of the polygon is half the size of the canvas at first 39327 * at each index we check if the text overlaps. 39328 * 39329 * Where it does, we store that angle and that index. 39330 * 39331 * After finding the largest index and angle we calculate how much we need to remove 39332 * from the shape radius to move the point inwards by that x. 39333 * 39334 * We average the left and right distances to get the maximum shape radius that can fit in the box 39335 * along with labels. 39336 * 39337 * Once we have that, we can find the centre point for the chart, by taking the x text protrusion 39338 * on each side, removing that from the size, halving it and adding the left x protrusion width. 39339 * 39340 * This will mean we have a shape fitted to the canvas, as large as it can be with the labels 39341 * and position it in the most space efficient manner 39342 * 39343 * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif 39344 */ 39345 39346 var plFont = getPointLabelFontOptions(scale); 39347 39348 // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. 39349 // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points 39350 var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2); 39351 var furthestLimits = { 39352 r: scale.width, 39353 l: 0, 39354 t: scale.height, 39355 b: 0 39356 }; 39357 var furthestAngles = {}; 39358 var i, textSize, pointPosition; 39359 39360 scale.ctx.font = plFont.font; 39361 scale._pointLabelSizes = []; 39362 39363 var valueCount = getValueCount(scale); 39364 for (i = 0; i < valueCount; i++) { 39365 pointPosition = scale.getPointPosition(i, largestPossibleRadius); 39366 textSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || ''); 39367 scale._pointLabelSizes[i] = textSize; 39368 39369 // Add quarter circle to make degree 0 mean top of circle 39370 var angleRadians = scale.getIndexAngle(i); 39371 var angle = helpers.toDegrees(angleRadians) % 360; 39372 var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180); 39373 var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270); 39374 39375 if (hLimits.start < furthestLimits.l) { 39376 furthestLimits.l = hLimits.start; 39377 furthestAngles.l = angleRadians; 39378 } 39379 39380 if (hLimits.end > furthestLimits.r) { 39381 furthestLimits.r = hLimits.end; 39382 furthestAngles.r = angleRadians; 39383 } 39384 39385 if (vLimits.start < furthestLimits.t) { 39386 furthestLimits.t = vLimits.start; 39387 furthestAngles.t = angleRadians; 39388 } 39389 39390 if (vLimits.end > furthestLimits.b) { 39391 furthestLimits.b = vLimits.end; 39392 furthestAngles.b = angleRadians; 39393 } 39394 } 39395 39396 scale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles); 39397 } 39398 39399 /** 39400 * Helper function to fit a radial linear scale with no point labels 39401 */ 39402 function fit(scale) { 39403 var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2); 39404 scale.drawingArea = Math.round(largestPossibleRadius); 39405 scale.setCenterPoint(0, 0, 0, 0); 39406 } 39407 39408 function getTextAlignForAngle(angle) { 39409 if (angle === 0 || angle === 180) { 39410 return 'center'; 39411 } else if (angle < 180) { 39412 return 'left'; 39413 } 39414 39415 return 'right'; 39416 } 39417 39418 function fillText(ctx, text, position, fontSize) { 39419 if (helpers.isArray(text)) { 39420 var y = position.y; 39421 var spacing = 1.5 * fontSize; 39422 39423 for (var i = 0; i < text.length; ++i) { 39424 ctx.fillText(text[i], position.x, y); 39425 y += spacing; 39426 } 39427 } else { 39428 ctx.fillText(text, position.x, position.y); 39429 } 39430 } 39431 39432 function adjustPointPositionForLabelHeight(angle, textSize, position) { 39433 if (angle === 90 || angle === 270) { 39434 position.y -= (textSize.h / 2); 39435 } else if (angle > 270 || angle < 90) { 39436 position.y -= textSize.h; 39437 } 39438 } 39439 39440 function drawPointLabels(scale) { 39441 var ctx = scale.ctx; 39442 var opts = scale.options; 39443 var angleLineOpts = opts.angleLines; 39444 var pointLabelOpts = opts.pointLabels; 39445 39446 ctx.lineWidth = angleLineOpts.lineWidth; 39447 ctx.strokeStyle = angleLineOpts.color; 39448 39449 var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max); 39450 39451 // Point Label Font 39452 var plFont = getPointLabelFontOptions(scale); 39453 39454 ctx.textBaseline = 'top'; 39455 39456 for (var i = getValueCount(scale) - 1; i >= 0; i--) { 39457 if (angleLineOpts.display) { 39458 var outerPosition = scale.getPointPosition(i, outerDistance); 39459 ctx.beginPath(); 39460 ctx.moveTo(scale.xCenter, scale.yCenter); 39461 ctx.lineTo(outerPosition.x, outerPosition.y); 39462 ctx.stroke(); 39463 ctx.closePath(); 39464 } 39465 39466 if (pointLabelOpts.display) { 39467 // Extra 3px out for some label spacing 39468 var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5); 39469 39470 // Keep this in loop since we may support array properties here 39471 var pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, globalDefaults.defaultFontColor); 39472 ctx.font = plFont.font; 39473 ctx.fillStyle = pointLabelFontColor; 39474 39475 var angleRadians = scale.getIndexAngle(i); 39476 var angle = helpers.toDegrees(angleRadians); 39477 ctx.textAlign = getTextAlignForAngle(angle); 39478 adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition); 39479 fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size); 39480 } 39481 } 39482 } 39483 39484 function drawRadiusLine(scale, gridLineOpts, radius, index) { 39485 var ctx = scale.ctx; 39486 ctx.strokeStyle = helpers.valueAtIndexOrDefault(gridLineOpts.color, index - 1); 39487 ctx.lineWidth = helpers.valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1); 39488 39489 if (scale.options.gridLines.circular) { 39490 // Draw circular arcs between the points 39491 ctx.beginPath(); 39492 ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2); 39493 ctx.closePath(); 39494 ctx.stroke(); 39495 } else { 39496 // Draw straight lines connecting each index 39497 var valueCount = getValueCount(scale); 39498
39499 if (valueCount === 0) { 39500 return; 39501 } 39502 39503 ctx.beginPath(); 39504 var pointPosition = scale.getPointPosition(0, radius); 39505 ctx.moveTo(pointPosition.x, pointPosition.y); 39506 39507 for (var i = 1; i < valueCount; i++) { 39508 pointPosition = scale.getPointPosition(i, radius); 39509 ctx.lineTo(pointPosition.x, pointPosition.y); 39510 } 39511 39512 ctx.closePath(); 39513 ctx.stroke(); 39514 } 39515 } 39516 39517 function numberOrZero(param) { 39518 return helpers.isNumber(param) ? param : 0; 39519 } 39520 39521 var LinearRadialScale = Chart.LinearScaleBase.extend({ 39522 setDimensions: function() { 39523 var me = this; 39524 var opts = me.options; 39525 var tickOpts = opts.ticks; 39526 // Set the unconstrained dimension before label rotation 39527 me.width = me.maxWidth; 39528 me.height = me.maxHeight; 39529 me.xCenter = Math.round(me.width / 2); 39530 me.yCenter = Math.round(me.height / 2); 39531 39532 var minSize = helpers.min([me.height, me.width]); 39533 var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); 39534 me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2); 39535 }, 39536 determineDataLimits: function() { 39537 var me = this; 39538 var chart = me.chart; 39539 var min = Number.POSITIVE_INFINITY; 39540 var max = Number.NEGATIVE_INFINITY; 39541 39542 helpers.each(chart.data.datasets, function(dataset, datasetIndex) { 39543 if (chart.isDatasetVisible(datasetIndex)) { 39544 var meta = chart.getDatasetMeta(datasetIndex); 39545 39546 helpers.each(dataset.data, function(rawValue, index) { 39547 var value = +me.getRightValue(rawValue); 39548 if (isNaN(value) || meta.data[index].hidden) { 39549 return; 39550 } 39551 39552 min = Math.min(value, min); 39553 max = Math.max(value, max); 39554 }); 39555 } 39556 }); 39557 39558 me.min = (min === Number.POSITIVE_INFINITY ? 0 : min); 39559 me.max = (max === Number.NEGATIVE_INFINITY ? 0 : max); 39560 39561 // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero 39562 me.handleTickRangeOptions(); 39563 }, 39564 getTickLimit: function() { 39565 var tickOpts = this.options.ticks; 39566 var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); 39567 return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize))); 39568 }, 39569 convertTicksToLabels: function() { 39570 var me = this; 39571 39572 Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me); 39573 39574 // Point labels 39575 me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me); 39576 }, 39577 getLabelForIndex: function(index, datasetIndex) { 39578 return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); 39579 }, 39580 fit: function() { 39581 if (this.options.pointLabels.display) { 39582 fitWithPointLabels(this); 39583 } else { 39584 fit(this); 39585 } 39586 }, 39587 /** 39588 * Set radius reductions and determine new radius and center point 39589 * @private 39590 */ 39591 setReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) { 39592 var me = this; 39593 var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l); 39594 var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r); 39595 var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t); 39596 var radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b); 39597 39598 radiusReductionLeft = numberOrZero(radiusReductionLeft); 39599 radiusReductionRight = numberOrZero(radiusReductionRight); 39600 radiusReductionTop = numberOrZero(radiusReductionTop); 39601 radiusReductionBottom = numberOrZero(radiusReductionBottom); 39602 39603 me.drawingArea = Math.min( 39604 Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2), 39605 Math.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2)); 39606 me.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom); 39607 }, 39608 setCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) { 39609 var me = this; 39610 var maxRight = me.width - rightMovement - me.drawingArea; 39611 var maxLeft = leftMovement + me.drawingArea; 39612 var maxTop = topMovement + me.drawingArea; 39613 var maxBottom = me.height - bottomMovement - me.drawingArea; 39614 39615 me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left); 39616 me.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top); 39617 }, 39618 39619 getIndexAngle: function(index) { 39620 var angleMultiplier = (Math.PI * 2) / getValueCount(this); 39621 var startAngle = this.chart.options && this.chart.options.startAngle ? 39622 this.chart.options.startAngle : 39623 0; 39624 39625 var startAngleRadians = startAngle * Math.PI * 2 / 360; 39626 39627 // Start from the top instead of right, so remove a quarter of the circle 39628 return index * angleMultiplier + startAngleRadians; 39629 }, 39630 getDistanceFromCenterForValue: function(value) { 39631 var me = this; 39632 39633 if (value === null) { 39634 return 0; // null always in center 39635 } 39636 39637 // Take into account half font size + the yPadding of the top value 39638 var scalingFactor = me.drawingArea / (me.max - me.min); 39639 if (me.options.ticks.reverse) { 39640 return (me.max - value) * scalingFactor; 39641 } 39642 return (value - me.min) * scalingFactor; 39643 }, 39644 getPointPosition: function(index, distanceFromCenter) { 39645 var me = this; 39646 var thisAngle = me.getIndexAngle(index) - (Math.PI / 2); 39647 return { 39648 x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter, 39649 y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter 39650 }; 39651 }, 39652 getPointPositionForValue: function(index, value) { 39653 return this.getPointPosition(index, this.getDistanceFromCenterForValue(value)); 39654 }, 39655 39656 getBasePosition: function() { 39657 var me = this; 39658 var min = me.min; 39659 var max = me.max; 39660 39661 return me.getPointPositionForValue(0, 39662 me.beginAtZero ? 0 : 39663 min < 0 && max < 0 ? max : 39664 min > 0 && max > 0 ? min : 39665 0); 39666 }, 39667 39668 draw: function() { 39669 var me = this; 39670 var opts = me.options; 39671 var gridLineOpts = opts.gridLines; 39672 var tickOpts = opts.ticks; 39673 var valueOrDefault = helpers.valueOrDefault; 39674 39675 if (opts.display) { 39676 var ctx = me.ctx; 39677 var startAngle = this.getIndexAngle(0); 39678 39679 // Tick Font
39680 var tickFontSize = valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); 39681 var tickFontStyle = valueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle); 39682 var tickFontFamily = valueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily); 39683 var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); 39684 39685 helpers.each(me.ticks, function(label, index) { 39686 // Don't draw a centre value (if it is minimum) 39687 if (index > 0 || tickOpts.reverse) { 39688 var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]); 39689 39690 // Draw circular lines around the scale 39691 if (gridLineOpts.display && index !== 0) { 39692 drawRadiusLine(me, gridLineOpts, yCenterOffset, index); 39693 } 39694 39695 if (tickOpts.display) { 39696 var tickFontColor = valueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor); 39697 ctx.font = tickLabelFont; 39698 39699 ctx.save(); 39700 ctx.translate(me.xCenter, me.yCenter); 39701 ctx.rotate(startAngle); 39702 39703 if (tickOpts.showLabelBackdrop) { 39704 var labelWidth = ctx.measureText(label).width; 39705 ctx.fillStyle = tickOpts.backdropColor; 39706 ctx.fillRect( 39707 -labelWidth / 2 - tickOpts.backdropPaddingX, 39708 -yCenterOffset - tickFontSize / 2 - tickOpts.backdropPaddingY, 39709 labelWidth + tickOpts.backdropPaddingX * 2, 39710 tickFontSize + tickOpts.backdropPaddingY * 2 39711 ); 39712 } 39713 39714 ctx.textAlign = 'center'; 39715 ctx.textBaseline = 'middle'; 39716 ctx.fillStyle = tickFontColor; 39717 ctx.fillText(label, 0, -yCenterOffset); 39718 ctx.restore(); 39719 } 39720 } 39721 }); 39722 39723 if (opts.angleLines.display || opts.pointLabels.display) { 39724 drawPointLabels(me); 39725 } 39726 } 39727 } 39728 }); 39729 Chart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig); 39730 39731}; 39732 39733},{"25":25,"34":34,"45":45}],58:[function(require,module,exports){ 39734/* global window: false */ 39735'use strict'; 39736 39737var moment = require(6); 39738moment = typeof moment === 'function' ? moment : window.moment; 39739 39740var defaults = require(25); 39741var helpers = require(45); 39742 39743// Integer constants are from the ES6 spec. 39744var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991; 39745var MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; 39746 39747var INTERVALS = { 39748 millisecond: { 39749 common: true, 39750 size: 1, 39751 steps: [1, 2, 5, 10, 20, 50, 100, 250, 500] 39752 }, 39753 second: { 39754 common: true, 39755 size: 1000, 39756 steps: [1, 2, 5, 10, 30] 39757 }, 39758 minute: { 39759 common: true, 39760 size: 60000, 39761 steps: [1, 2, 5, 10, 30] 39762 }, 39763 hour: { 39764 common: true, 39765 size: 3600000, 39766 steps: [1, 2, 3, 6, 12] 39767 }, 39768 day: { 39769 common: true, 39770 size: 86400000, 39771 steps: [1, 2, 5] 39772 }, 39773 week: { 39774 common: false, 39775 size: 604800000, 39776 steps: [1, 2, 3, 4] 39777 }, 39778 month: { 39779 common: true, 39780 size: 2.628e9, 39781 steps: [1, 2, 3] 39782 }, 39783 quarter: { 39784 common: false, 39785 size: 7.884e9, 39786 steps: [1, 2, 3, 4] 39787 }, 39788 year: { 39789 common: true, 39790 size: 3.154e10 39791 } 39792}; 39793 39794var UNITS = Object.keys(INTERVALS); 39795 39796function sorter(a, b) { 39797 return a - b; 39798} 39799 39800function arrayUnique(items) { 39801 var hash = {}; 39802 var out = []; 39803 var i, ilen, item; 39804 39805 for (i = 0, ilen = items.length; i < ilen; ++i) { 39806 item = items[i]; 39807 if (!hash[item]) { 39808 hash[item] = true; 39809 out.push(item); 39810 } 39811 } 39812 39813 return out; 39814} 39815 39816/** 39817 * Returns an array of {time, pos} objects used to interpolate a specific `time` or position 39818 * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is 39819 * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other 39820 * extremity (left + width or top + height). Note that it would be more optimized to directly 39821 * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need 39822 * to create the lookup table. The table ALWAYS contains at least two items: min and max. 39823 * 39824 * @param {Number[]} timestamps - timestamps sorted from lowest to highest. 39825 * @param {String} distribution - If 'linear', timestamps will be spread linearly along the min 39826 * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}. 39827 * If 'series', timestamps will be positioned at the same distance from each other. In this 39828 * case, only timestamps that break the time linearity are registered, meaning that in the 39829 * best case, all timestamps are linear, the table contains only min and max. 39830 */ 39831function buildLookupTable(timestamps, min, max, distribution) { 39832 if (distribution === 'linear' || !timestamps.length) { 39833 return [ 39834 {time: min, pos: 0}, 39835 {time: max, pos: 1} 39836 ]; 39837 } 39838 39839 var table = []; 39840 var items = [min]; 39841 var i, ilen, prev, curr, next; 39842 39843 for (i = 0, ilen = timestamps.length; i < ilen; ++i) { 39844 curr = timestamps[i]; 39845 if (curr > min && curr < max) { 39846 items.push(curr); 39847 } 39848 } 39849 39850 items.push(max); 39851 39852 for (i = 0, ilen = items.length; i < ilen; ++i) { 39853 next = items[i + 1]; 39854 prev = items[i - 1]; 39855 curr = items[i]; 39856 39857 // only add points that breaks the scale linearity 39858 if (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) { 39859 table.push({time: curr, pos: i / (ilen - 1)}); 39860 } 39861 } 39862 39863 return table; 39864} 39865 39866// @see adapted from http://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/ 39867function lookup(table, key, value) { 39868 var lo = 0; 39869 var hi = table.length - 1; 39870 var mid, i0, i1; 39871 39872 while (lo >= 0 && lo <= hi) { 39873 mid = (lo + hi) >> 1; 39874 i0 = table[mid - 1] || null; 39875 i1 = table[mid]; 39876 39877 if (!i0) { 39878 // given value is outside table (before first item) 39879 return {lo: null, hi: i1}; 39880 } else if (i1[key] < value) { 39881 lo = mid + 1; 39882 } else if (i0[key] > value) {
39883 hi = mid - 1; 39884 } else { 39885 return {lo: i0, hi: i1}; 39886 } 39887 } 39888 39889 // given value is outside table (after last item) 39890 return {lo: i1, hi: null}; 39891} 39892 39893/** 39894 * Linearly interpolates the given source `value` using the table items `skey` values and 39895 * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos') 39896 * returns the position for a timestamp equal to 42. If value is out of bounds, values at 39897 * index [0, 1] or [n - 1, n] are used for the interpolation. 39898 */ 39899function interpolate(table, skey, sval, tkey) { 39900 var range = lookup(table, skey, sval); 39901 39902 // Note: the lookup table ALWAYS contains at least 2 items (min and max) 39903 var prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo; 39904 var next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi; 39905 39906 var span = next[skey] - prev[skey]; 39907 var ratio = span ? (sval - prev[skey]) / span : 0; 39908 var offset = (next[tkey] - prev[tkey]) * ratio; 39909 39910 return prev[tkey] + offset; 39911} 39912 39913/** 39914 * Convert the given value to a moment object using the given time options. 39915 * @see http://momentjs.com/docs/#/parsing/ 39916 */ 39917function momentify(value, options) { 39918 var parser = options.parser; 39919 var format = options.parser || options.format; 39920 39921 if (typeof parser === 'function') { 39922 return parser(value); 39923 } 39924 39925 if (typeof value === 'string' && typeof format === 'string') { 39926 return moment(value, format); 39927 } 39928 39929 if (!(value instanceof moment)) { 39930 value = moment(value); 39931 } 39932 39933 if (value.isValid()) { 39934 return value; 39935 } 39936 39937 // Labels are in an incompatible moment format and no `parser` has been provided. 39938 // The user might still use the deprecated `format` option to convert his inputs. 39939 if (typeof format === 'function') { 39940 return format(value); 39941 } 39942 39943 return value; 39944} 39945 39946function parse(input, scale) { 39947 if (helpers.isNullOrUndef(input)) { 39948 return null; 39949 } 39950 39951 var options = scale.options.time; 39952 var value = momentify(scale.getRightValue(input), options); 39953 if (!value.isValid()) { 39954 return null; 39955 } 39956 39957 if (options.round) { 39958 value.startOf(options.round); 39959 } 39960 39961 return value.valueOf(); 39962} 39963 39964/** 39965 * Returns the number of unit to skip to be able to display up to `capacity` number of ticks 39966 * in `unit` for the given `min` / `max` range and respecting the interval steps constraints. 39967 */ 39968function determineStepSize(min, max, unit, capacity) { 39969 var range = max - min; 39970 var interval = INTERVALS[unit]; 39971 var milliseconds = interval.size; 39972 var steps = interval.steps; 39973 var i, ilen, factor; 39974 39975 if (!steps) { 39976 return Math.ceil(range / (capacity * milliseconds)); 39977 } 39978 39979 for (i = 0, ilen = steps.length; i < ilen; ++i) { 39980 factor = steps[i]; 39981 if (Math.ceil(range / (milliseconds * factor)) <= capacity) { 39982 break; 39983 } 39984 } 39985 39986 return factor; 39987} 39988 39989/** 39990 * Figures out what unit results in an appropriate number of auto-generated ticks 39991 */ 39992function determineUnitForAutoTicks(minUnit, min, max, capacity) { 39993 var ilen = UNITS.length; 39994 var i, interval, factor; 39995 39996 for (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) { 39997 interval = INTERVALS[UNITS[i]]; 39998 factor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER; 39999 40000 if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) { 40001 return UNITS[i]; 40002 } 40003 } 40004 40005 return UNITS[ilen - 1]; 40006} 40007 40008/** 40009 * Figures out what unit to format a set of ticks with 40010 */ 40011function determineUnitForFormatting(ticks, minUnit, min, max) { 40012 var duration = moment.duration(moment(max).diff(moment(min))); 40013 var ilen = UNITS.length; 40014 var i, unit; 40015 40016 for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) { 40017 unit = UNITS[i]; 40018 if (INTERVALS[unit].common && duration.as(unit) >= ticks.length) { 40019 return unit; 40020 } 40021 } 40022 40023 return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0]; 40024} 40025 40026function determineMajorUnit(unit) { 40027 for (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) { 40028 if (INTERVALS[UNITS[i]].common) { 40029 return UNITS[i]; 40030 } 40031 } 40032} 40033 40034/** 40035 * Generates a maximum of `capacity` timestamps between min and max, rounded to the 40036 * `minor` unit, aligned on the `major` unit and using the given scale time `options`. 40037 * Important: this method can return ticks outside the min and max range, it's the 40038 * responsibility of the calling code to clamp values if needed. 40039 */ 40040function generate(min, max, capacity, options) { 40041 var timeOpts = options.time; 40042 var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity); 40043 var major = determineMajorUnit(minor); 40044 var stepSize = helpers.valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize); 40045 var weekday = minor === 'week' ? timeOpts.isoWeekday : false;
40046 var majorTicksEnabled = options.ticks.major.enabled; 40047 var interval = INTERVALS[minor]; 40048 var first = moment(min); 40049 var last = moment(max); 40050 var ticks = []; 40051 var time; 40052 40053 if (!stepSize) { 40054 stepSize = determineStepSize(min, max, minor, capacity); 40055 } 40056 40057 // For 'week' unit, handle the first day of week option 40058 if (weekday) { 40059 first = first.isoWeekday(weekday); 40060 last = last.isoWeekday(weekday); 40061 } 40062 40063 // Align first/last ticks on unit 40064 first = first.startOf(weekday ? 'day' : minor); 40065 last = last.startOf(weekday ? 'day' : minor); 40066 40067 // Make sure that the last tick include max 40068 if (last < max) { 40069 last.add(1, minor); 40070 } 40071 40072 time = moment(first); 40073 40074 if (majorTicksEnabled && major && !weekday && !timeOpts.round) { 40075 // Align the first tick on the previous `minor` unit aligned on the `major` unit: 40076 // we first aligned time on the previous `major` unit then add the number of full 40077 // stepSize there is between first and the previous major time. 40078 time.startOf(major); 40079 time.add(~~((first - time) / (interval.size * stepSize)) * stepSize, minor); 40080 } 40081 40082 for (; time < last; time.add(stepSize, minor)) { 40083 ticks.push(+time); 40084 } 40085 40086 ticks.push(+time); 40087 40088 return ticks; 40089} 40090 40091/** 40092 * Returns the right and left offsets from edges in the form of {left, right}. 40093 * Offsets are added when the `offset` option is true. 40094 */ 40095function computeOffsets(table, ticks, min, max, options) { 40096 var left = 0; 40097 var right = 0; 40098 var upper, lower; 40099 40100 if (options.offset && ticks.length) { 40101 if (!options.time.min) { 40102 upper = ticks.length > 1 ? ticks[1] : max; 40103 lower = ticks[0]; 40104 left = ( 40105 interpolate(table, 'time', upper, 'pos') - 40106 interpolate(table, 'time', lower, 'pos') 40107 ) / 2; 40108 } 40109 if (!options.time.max) { 40110 upper = ticks[ticks.length - 1]; 40111 lower = ticks.length > 1 ? ticks[ticks.length - 2] : min; 40112 right = ( 40113 interpolate(table, 'time', upper, 'pos') - 40114 interpolate(table, 'time', lower, 'pos') 40115 ) / 2; 40116 } 40117 } 40118 40119 return {left: left, right: right}; 40120} 40121 40122function ticksFromTimestamps(values, majorUnit) { 40123 var ticks = []; 40124 var i, ilen, value, major; 40125 40126 for (i = 0, ilen = values.length; i < ilen; ++i) { 40127 value = values[i]; 40128 major = majorUnit ? value === +moment(value).startOf(majorUnit) : false; 40129 40130 ticks.push({ 40131 value: value, 40132 major: major 40133 }); 40134 } 40135 40136 return ticks; 40137} 40138 40139function determineLabelFormat(data, timeOpts) { 40140 var i, momentDate, hasTime; 40141 var ilen = data.length; 40142 40143 // find the label with the most parts (milliseconds, minutes, etc.) 40144 // format all labels with the same level of detail as the most specific label 40145 for (i = 0; i < ilen; i++) { 40146 momentDate = momentify(data[i], timeOpts); 40147 if (momentDate.millisecond() !== 0) { 40148 return 'MMM D, YYYY h:mm:ss.SSS a'; 40149 } 40150 if (momentDate.second() !== 0 || momentDate.minute() !== 0 || momentDate.hour() !== 0) { 40151 hasTime = true; 40152 } 40153 } 40154 if (hasTime) { 40155 return 'MMM D, YYYY h:mm:ss a'; 40156 } 40157 return 'MMM D, YYYY'; 40158} 40159 40160module.exports = function(Chart) { 40161 40162 var defaultConfig = { 40163 position: 'bottom', 40164 40165 /** 40166 * Data distribution along the scale: 40167 * - 'linear': data are spread according to their time (distances can vary), 40168 * - 'series': data are spread at the same distance from each other. 40169 * @see https://github.com/chartjs/Chart.js/pull/4507 40170 * @since 2.7.0 40171 */ 40172 distribution: 'linear', 40173 40174 /** 40175 * Scale boundary strategy (bypassed by min/max time options) 40176 * - `data`: make sure data are fully visible, ticks outside are removed 40177 * - `ticks`: make sure ticks are fully visible, data outside are truncated 40178 * @see https://github.com/chartjs/Chart.js/pull/4556 40179 * @since 2.7.0 40180 */ 40181 bounds: 'data', 40182 40183 time: { 40184 parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment 40185 format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/ 40186 unit: false, // false == automatic or override with week, month, year, etc. 40187 round: false, // none, or override with week, month, year, etc. 40188 displayFormat: false, // DEPRECATED 40189 isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/ 40190 minUnit: 'millisecond', 40191 40192 // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/ 40193 displayFormats: { 40194 millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM, 40195 second: 'h:mm:ss a', // 11:20:01 AM 40196 minute: 'h:mm a', // 11:20 AM 40197 hour: 'hA', // 5PM 40198 day: 'MMM D', // Sep 4 40199 week: 'll', // Week 46, or maybe "[W]WW - YYYY" ? 40200 month: 'MMM YYYY', // Sept 2015 40201 quarter: '[Q]Q - YYYY', // Q3 40202 year: 'YYYY' // 2015 40203 }, 40204 }, 40205 ticks: { 40206 autoSkip: false, 40207 40208 /** 40209 * Ticks generation input values: 40210 * - 'auto': generates "optimal" ticks based on scale size and time options. 40211 * - 'data': generates ticks from data (including labels from data {t|x|y} objects). 40212 * - 'labels': generates ticks from user given `data.labels` values ONLY. 40213 * @see https://github.com/chartjs/Chart.js/pull/4507 40214 * @since 2.7.0 40215 */ 40216 source: 'auto', 40217 40218 major: { 40219 enabled: false 40220 } 40221 } 40222 }; 40223 40224 var TimeScale = Chart.Scale.extend({ 40225 initialize: function() { 40226 if (!moment) { 40227 throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com'); 40228 } 40229 40230 this.mergeTicksOptions(); 40231 40232 Chart.Scale.prototype.initialize.call(this); 40233 }, 40234 40235 update: function() { 40236 var me = this; 40237 var options = me.options; 40238 40239 // DEPRECATIONS: output a message only one time per update 40240 if (options.time && options.time.format) { 40241 console.warn('options.time.format is deprecated and replaced by options.time.parser.'); 40242 } 40243 40244 return Chart.Scale.prototype.update.apply(me, arguments); 40245 }, 40246 40247 /** 40248 * Allows data to be referenced via 't' attribute 40249 */ 40250 getRightValue: function(rawValue) { 40251 if (rawValue && rawValue.t !== undefined) { 40252 rawValue = rawValue.t; 40253 } 40254 return Chart.Scale.prototype.getRightValue.call(this, rawValue); 40255 }, 40256 40257 determineDataLimits: function() { 40258 var me = this; 40259 var chart = me.chart; 40260 var timeOpts = me.options.time; 40261 var unit = timeOpts.unit || 'day'; 40262 var min = MAX_INTEGER; 40263 var max = MIN_INTEGER; 40264 var timestamps = []; 40265 var datasets = []; 40266 var labels = []; 40267 var i, j, ilen, jlen, data, timestamp; 40268 40269 // Convert labels to timestamps 40270 for (i = 0, ilen = chart.data.labels.length; i < ilen; ++i) { 40271 labels.push(parse(chart.data.labels[i], me)); 40272 } 40273 40274 // Convert data to timestamps 40275 for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { 40276 if (chart.isDatasetVisible(i)) { 40277 data = chart.data.datasets[i].data; 40278 40279 // Let's consider that all data have the same format. 40280 if (helpers.isObject(data[0])) { 40281 datasets[i] = []; 40282 40283 for (j = 0, jlen = data.length; j < jlen; ++j) { 40284 timestamp = parse(data[j], me); 40285 timestamps.push(timestamp); 40286 datasets[i][j] = timestamp; 40287 } 40288 } else { 40289 timestamps.push.apply(timestamps, labels); 40290 datasets[i] = labels.slice(0); 40291 } 40292 } else { 40293 datasets[i] = []; 40294 } 40295 } 40296 40297 if (labels.length) { 40298 // Sort labels **after** data have been converted 40299 labels = arrayUnique(labels).sort(sorter); 40300 min = Math.min(min, labels[0]); 40301 max = Math.max(max, labels[labels.length - 1]); 40302 } 40303 40304 if (timestamps.length) { 40305 timestamps = arrayUnique(timestamps).sort(sorter); 40306 min = Math.min(min, timestamps[0]); 40307 max = Math.max(max, timestamps[timestamps.length - 1]); 40308 } 40309 40310 min = parse(timeOpts.min, me) || min; 40311 max = parse(timeOpts.max, me) || max; 40312 40313 // In case there is no valid min/max, set limits based on unit time option 40314 min = min === MAX_INTEGER ? +moment().startOf(unit) : min; 40315 max = max === MIN_INTEGER ? +moment().endOf(unit) + 1 : max; 40316 40317 // Make sure that max is strictly higher than min (required by the lookup table) 40318 me.min = Math.min(min, max); 40319 me.max = Math.max(min + 1, max); 40320 40321 // PRIVATE 40322 me._horizontal = me.isHorizontal(); 40323 me._table = []; 40324 me._timestamps = { 40325 data: timestamps, 40326 datasets: datasets, 40327 labels: labels 40328 }; 40329 }, 40330 40331 buildTicks: function() { 40332 var me = this; 40333 var min = me.min; 40334 var max = me.max; 40335 var options = me.options; 40336 var timeOpts = options.time; 40337 var timestamps = []; 40338 var ticks = []; 40339 var i, ilen, timestamp; 40340 40341 switch (options.ticks.source) { 40342 case 'data': 40343 timestamps = me._timestamps.data; 40344 break; 40345 case 'labels': 40346 timestamps = me._timestamps.labels; 40347 break; 40348 case 'auto': 40349 default: 40350 timestamps = generate(min, max, me.getLabelCapacity(min), options); 40351 } 40352 40353 if (options.bounds === 'ticks' && timestamps.length) { 40354 min = timestamps[0]; 40355 max = timestamps[timestamps.length - 1]; 40356 } 40357 40358 // Enforce limits with user min/max options 40359 min = parse(timeOpts.min, me) || min; 40360 max = parse(timeOpts.max, me) || max; 40361 40362 // Remove ticks outside the min/max range 40363 for (i = 0, ilen = timestamps.length; i < ilen; ++i) { 40364 timestamp = timestamps[i]; 40365 if (timestamp >= min && timestamp <= max) { 40366 ticks.push(timestamp); 40367 } 40368 } 40369 40370 me.min = min; 40371 me.max = max; 40372 40373 // PRIVATE 40374 me._unit = timeOpts.unit || determineUnitForFormatting(ticks, timeOpts.minUnit, me.min, me.max); 40375 me._majorUnit = determineMajorUnit(me._unit); 40376 me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution); 40377 me._offsets = computeOffsets(me._table, ticks, min, max, options); 40378 me._labelFormat = determineLabelFormat(me._timestamps.data, timeOpts); 40379 40380 return ticksFromTimestamps(ticks, me._majorUnit); 40381 }, 40382 40383 getLabelForIndex: function(index, datasetIndex) { 40384 var me = this; 40385 var data = me.chart.data; 40386 var timeOpts = me.options.time; 40387 var label = data.labels && index < data.labels.length ? data.labels[index] : ''; 40388 var value = data.datasets[datasetIndex].data[index]; 40389 40390 if (helpers.isObject(value)) { 40391 label = me.getRightValue(value); 40392 } 40393 if (timeOpts.tooltipFormat) { 40394 return momentify(label, timeOpts).format(timeOpts.tooltipFormat); 40395 } 40396 if (typeof label === 'string') { 40397 return label; 40398 } 40399 40400 return momentify(label, timeOpts).format(me._labelFormat); 40401 }, 40402 40403 /** 40404 * Function to format an individual tick mark 40405 * @private 40406 */ 40407 tickFormatFunction: function(tick, index, ticks, formatOverride) { 40408 var me = this; 40409 var options = me.options; 40410 var time = tick.valueOf(); 40411 var formats = options.time.displayFormats; 40412 var minorFormat = formats[me._unit]; 40413 var majorUnit = me._majorUnit; 40414 var majorFormat = formats[majorUnit]; 40415 var majorTime = tick.clone().startOf(majorUnit).valueOf(); 40416 var majorTickOpts = options.ticks.major; 40417 var major = majorTickOpts.enabled && majorUnit && majorFormat && time === majorTime; 40418 var label = tick.format(formatOverride ? formatOverride : major ? majorFormat : minorFormat); 40419 var tickOpts = major ? majorTickOpts : options.ticks.minor; 40420 var formatter = helpers.valueOrDefault(tickOpts.callback, tickOpts.userCallback); 40421 40422 return formatter ? formatter(label, index, ticks) : label; 40423 }, 40424 40425 convertTicksToLabels: function(ticks) { 40426 var labels = []; 40427 var i, ilen; 40428 40429 for (i = 0, ilen = ticks.length; i < ilen; ++i) { 40430 labels.push(this.tickFormatFunction(moment(ticks[i].value), i, ticks)); 40431 } 40432 40433 return labels; 40434 }, 40435 40436 /** 40437 * @private 40438 */ 40439 getPixelForOffset: function(time) { 40440 var me = this; 40441 var size = me._horizontal ? me.width : me.height; 40442 var start = me._horizontal ? me.left : me.top; 40443 var pos = interpolate(me._table, 'time', time, 'pos'); 40444 40445 return start + size * (me._offsets.left + pos) / (me._offsets.left + 1 + me._offsets.right); 40446 }, 40447 40448 getPixelForValue: function(value, index, datasetIndex) { 40449 var me = this; 40450 var time = null; 40451 40452 if (index !== undefined && datasetIndex !== undefined) { 40453 time = me._timestamps.datasets[datasetIndex][index]; 40454 } 40455 40456 if (time === null) { 40457 time = parse(value, me); 40458 } 40459 40460 if (time !== null) { 40461 return me.getPixelForOffset(time); 40462 } 40463 }, 40464 40465 getPixelForTick: function(index) { 40466 var ticks = this.getTicks(); 40467 return index >= 0 && index < ticks.length ? 40468 this.getPixelForOffset(ticks[index].value) : 40469 null; 40470 }, 40471 40472 getValueForPixel: function(pixel) { 40473 var me = this; 40474 var size = me._horizontal ? me.width : me.height; 40475 var start = me._horizontal ? me.left : me.top; 40476 var pos = (size ? (pixel - start) / size : 0) * (me._offsets.left + 1 + me._offsets.left) - me._offsets.right; 40477 var time = interpolate(me._table, 'pos', pos, 'time'); 40478 40479 return moment(time); 40480 }, 40481 40482 /** 40483 * Crude approximation of what the label width might be 40484 * @private 40485 */ 40486 getLabelWidth: function(label) { 40487 var me = this; 40488 var ticksOpts = me.options.ticks; 40489 var tickLabelWidth = me.ctx.measureText(label).width; 40490 var angle = helpers.toRadians(ticksOpts.maxRotation); 40491 var cosRotation = Math.cos(angle); 40492 var sinRotation = Math.sin(angle);
40493 var tickFontSize = helpers.valueOrDefault(ticksOpts.fontSize, defaults.global.defaultFontSize); 40494 40495 return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation); 40496 }, 40497 40498 /** 40499 * @private 40500 */ 40501 getLabelCapacity: function(exampleTime) { 40502 var me = this; 40503 40504 var formatOverride = me.options.time.displayFormats.millisecond; // Pick the longest format for guestimation 40505 40506 var exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, [], formatOverride); 40507 var tickLabelWidth = me.getLabelWidth(exampleLabel); 40508 var innerWidth = me.isHorizontal() ? me.width : me.height; 40509 40510 var capacity = Math.floor(innerWidth / tickLabelWidth); 40511 return capacity > 0 ? capacity : 1; 40512 } 40513 }); 40514 40515 Chart.scaleService.registerScaleType('time', TimeScale, defaultConfig); 40516}; 40517 40518},{"25":25,"45":45,"6":6}]},{},[7])(7) 40519}); 40520;
vendor: 17,892 bytes, lines 40520-41065
40520/*! 40521 * jQCloud 2.0.3 40522 * Copyright 2011 Luca Ongaro (http://www.lucaongaro.eu) 40523 * Copyright 2013 Daniel White (http://www.developerdan.com) 40524 * Copyright 2014-2017 Damien "Mistic" Sorel (http://www.strangeplanet.fr) 40525 * Licensed under MIT (http://opensource.org/licenses/MIT) 40526 */ 40527(function(root, factory) { 40528 if (typeof define === 'function' && define.amd) { 40529 define(['jquery'], factory); 40530 } 40531 else if (typeof module === 'object' && module.exports) { 40532 module.exports = factory(require('jquery')); 40533 } 40534 else { 40535 factory(root.jQuery); 40536 } 40537}(this, function($) { 40538'use strict'; 40539 40540/* 40541 * Plugin class 40542 */ 40543var jQCloud = function(element, word_array, options) { 40544 this.$element = $(element); 40545 40546 this.word_array = word_array || []; 40547 this.options = options; 40548 40549 this.sizeGenerator = null; 40550 this.colorGenerator = null; 40551 40552 // Data used internally 40553 this.data = { 40554 placed_words: [], 40555 timeouts: {}, 40556 namespace: null, 40557 step: null, 40558 angle: null, 40559 aspect_ratio: null, 40560 max_weight: null, 40561 min_weight: null, 40562 sizes: [], 40563 colors: [] 40564 }; 40565 40566 this.initialize(); 40567}; 40568 40569jQCloud.DEFAULTS = { 40570 width: 100, 40571 height: 100, 40572 center: { x: 0.5, y: 0.5 }, 40573 steps: 10, 40574 delay: null, 40575 shape: 'elliptic', 40576 classPattern: 'w{n}', 40577 encodeURI: true, 40578 removeOverflowing: true, 40579 afterCloudRender: null, 40580 autoResize: false, 40581 colors: null, 40582 fontSize: null, 40583 template: null 40584}; 40585 40586jQCloud.prototype = { 40587 initialize: function() { 40588 // Set/Get dimensions 40589 if (this.options.width) { 40590 this.$element.width(this.options.width); 40591 } 40592 else { 40593 this.options.width = this.$element.width(); 40594 } 40595 if (this.options.height) { 40596 this.$element.height(this.options.height); 40597 } 40598 else { 40599 this.options.height = this.$element.height(); 40600 } 40601 40602 // Default options value 40603 this.options = $.extend(true, {}, jQCloud.DEFAULTS, this.options); 40604 40605 // Ensure delay 40606 if (this.options.delay === null) { 40607 this.options.delay = this.word_array.length > 50 ? 10 : 0; 40608 } 40609 40610 // Backward compatibility 40611 if (this.options.center.x > 1) { 40612 this.options.center.x = this.options.center.x / this.options.width; 40613 this.options.center.y = this.options.center.y / this.options.height; 40614 } 40615 40616 // Create colorGenerator function from options 40617 // Direct function 40618 if (typeof this.options.colors == 'function') { 40619 this.colorGenerator = this.options.colors; 40620 } 40621 // Array of sizes 40622 else if ($.isArray(this.options.colors)) { 40623 var cl = this.options.colors.length; 40624 if (cl > 0) { 40625 // Fill the sizes array to X items 40626 if (cl < this.options.steps) { 40627 for (var i = cl; i < this.options.steps; i++) { 40628 this.options.colors[i] = this.options.colors[cl - 1]; 40629 } 40630 } 40631 40632 this.colorGenerator = function(weight) { 40633 return this.options.colors[this.options.steps - weight]; 40634 }; 40635 } 40636 } 40637 40638 // Create sizeGenerator function from options 40639 // Direct function 40640 if (typeof this.options.fontSize == 'function') { 40641 this.sizeGenerator = this.options.fontSize; 40642 } 40643 // Object with 'from' and 'to' 40644 else if ($.isPlainObject(this.options.fontSize)) { 40645 this.sizeGenerator = function(width, height, weight) { 40646 var max = width * this.options.fontSize.from, 40647 min = width * this.options.fontSize.to; 40648 return Math.round(min + (max - min) * 1.0 / (this.options.steps - 1) * (weight - 1)) + 'px'; 40649 }; 40650 } 40651 // Array of sizes 40652 else if ($.isArray(this.options.fontSize)) { 40653 var sl = this.options.fontSize.length; 40654 if (sl > 0) { 40655 // Fill the sizes array to X items 40656 if (sl < this.options.steps) { 40657 for (var j = sl; j < this.options.steps; j++) { 40658 this.options.fontSize[j] = this.options.fontSize[sl - 1]; 40659 } 40660 } 40661 40662 this.sizeGenerator = function(width, height, weight) { 40663 return this.options.fontSize[this.options.steps - weight]; 40664 }; 40665 } 40666 } 40667 40668 this.data.angle = Math.random() * 6.28; 40669 this.data.step = (this.options.shape === 'rectangular') ? 18.0 : 2.0; 40670 this.data.aspect_ratio = this.options.width / this.options.height; 40671 this.clearTimeouts(); 40672 40673 // Namespace word ids to avoid collisions between multiple clouds 40674 this.data.namespace = (this.$element.attr('id') || Math.floor((Math.random() * 1000000)).toString(36)) + '_word_'; 40675 40676 this.$element.addClass('jqcloud'); 40677 40678 // Container's CSS position cannot be 'static' 40679 if (this.$element.css('position') === 'static') { 40680 this.$element.css('position', 'relative'); 40681 } 40682 40683 // Delay execution so that the browser can render the page before the computatively intensive word cloud drawing 40684 this.createTimeout($.proxy(this.drawWordCloud, this), 10); 40685 40686 // Attach window resize event 40687 if (this.options.autoResize) { 40688 $(window).on('resize.' + this.data.namespace, throttle(this.resize, 50, this)); 40689 } 40690 }, 40691 40692 // Helper function to keep track of timeouts so they can be destroyed 40693 createTimeout: function(callback, time) { 40694 var timeout = setTimeout($.proxy(function() { 40695 delete this.data.timeouts[timeout]; 40696 callback(); 40697 }, this), time); 40698 this.data.timeouts[timeout] = true; 40699 }, 40700 40701 // Destroy all timeouts 40702 clearTimeouts: function() { 40703 $.each(this.data.timeouts, function(key) { 40704 clearTimeout(key); 40705 }); 40706 this.data.timeouts = {}; 40707 }, 40708 40709 // Pairwise overlap detection 40710 overlapping: function(a, b) { 40711 if (Math.abs(2.0 * a.left + a.width - 2.0 * b.left - b.width) < a.width + b.width) { 40712 if (Math.abs(2.0 * a.top + a.height - 2.0 * b.top - b.height) < a.height + b.height) { 40713 return true; 40714 } 40715 } 40716 return false; 40717 }, 40718 40719 // Helper function to test if an element overlaps others 40720 hitTest: function(elem) { 40721 // Check elements for overlap one by one, stop and return false as soon as an overlap is found 40722 for (var i = 0, l = this.data.placed_words.length; i < l; i++) { 40723 if (this.overlapping(elem, this.data.placed_words[i])) { 40724 return true; 40725 } 40726 } 40727 return false; 40728 }, 40729 40730 // Initialize the drawing of the whole cloud 40731 drawWordCloud: function() { 40732 var i, l; 40733 40734 this.$element.children('[id^="' + this.data.namespace + '"]').remove(); 40735 40736 if (this.word_array.length === 0) { 40737 return; 40738 } 40739 40740 // Make sure every weight is a number before sorting 40741 for (i = 0, l = this.word_array.length; i < l; i++) { 40742 this.word_array[i].weight = parseFloat(this.word_array[i].weight, 10); 40743 } 40744 40745 // Sort word_array from the word with the highest weight to the one with the lowest 40746 this.word_array.sort(function(a, b) { 40747 return b.weight - a.weight; 40748 }); 40749 40750 // Kepp trace of bounds 40751 this.data.max_weight = this.word_array[0].weight; 40752 this.data.min_weight = this.word_array[this.word_array.length - 1].weight; 40753 40754 // Generate colors 40755 this.data.colors = []; 40756 if (this.colorGenerator) { 40757 for (i = 0; i < this.options.steps; i++) { 40758 this.data.colors.push(this.colorGenerator(i + 1)); 40759 } 40760 } 40761 40762 // Generate font sizes 40763 this.data.sizes = []; 40764 if (this.sizeGenerator) { 40765 for (i = 0; i < this.options.steps; i++) { 40766 this.data.sizes.push(this.sizeGenerator(this.options.width, this.options.height, i + 1)); 40767 } 40768 } 40769 40770 // Iterate drawOneWord on every word, immediately or with delay 40771 if (this.options.delay > 0) { 40772 this.drawOneWordDelayed(); 40773 } 40774 else { 40775 for (i = 0, l = this.word_array.length; i < l; i++) { 40776 this.drawOneWord(i, this.word_array[i]); 40777 } 40778 40779 if (typeof this.options.afterCloudRender === 'function') { 40780 this.options.afterCloudRender.call(this.$element); 40781 } 40782 } 40783 }, 40784 40785 // Function to draw a word, by moving it in spiral until it finds a suitable empty place 40786 drawOneWord: function(index, word) { 40787 var word_id = this.data.namespace + index, 40788 word_selector = '#' + word_id, 40789 40790 // option.shape == 'elliptic' 40791 angle = this.data.angle, 40792 radius = 0.0, 40793 40794 // option.shape == 'rectangular' 40795 steps_in_direction = 0.0, 40796 quarter_turns = 0.0, 40797 40798 weight = Math.floor(this.options.steps / 2), 40799 word_span, 40800 word_size, 40801 word_style; 40802 40803 // Create word attr object 40804 word.attr = $.extend({}, word.html, { id: word_id }); 40805 40806 // Linearly map the original weight to a discrete scale from 1 to 10 40807 // Only if weights are different 40808 if (this.data.max_weight != this.data.min_weight) { 40809 weight = Math.round((word.weight - this.data.min_weight) * 1.0 * (this.options.steps - 1) / (this.data.max_weight - this.data.min_weight)) + 1; 40810 } 40811 word_span = $('<span>').attr(word.attr); 40812 40813 word_span.addClass('jqcloud-word'); 40814 40815 // Apply class 40816 if (this.options.classPattern) { 40817 word_span.addClass(this.options.classPattern.replace('{n}', weight)); 40818 } 40819 40820 // Apply color 40821 if (this.data.colors.length) { 40822 word_span.css('color', this.data.colors[weight - 1]); 40823 } 40824 40825 // Apply color from word property 40826 if (word.color) { 40827 word_span.css('color', word.color); 40828 } 40829 40830 // Apply size 40831 if (this.data.sizes.length) { 40832 word_span.css('font-size', this.data.sizes[weight - 1]); 40833 } 40834 40835 //Render using template function if provided. 40836 if (this.options.template) { 40837 word_span.html(this.options.template(word)); 40838 } else if (word.link) { 40839 // Append link if word.link attribute was set 40840 // If link is a string, then use it as the link href 40841 if (typeof word.link === 'string') { 40842 word.link = { href: word.link }; 40843 } 40844 40845 if (this.options.encodeURI) { 40846 word.link.href = encodeURI(word.link.href).replace(/'/g, '%27'); 40847 } 40848 40849 word_span.append($('<a>').attr(word.link).text(word.text)); 40850 } 40851 else { 40852 word_span.text(word.text); 40853 } 40854 40855 // Bind handlers to words 40856 if (word.handlers) { 40857 word_span.on(word.handlers); 40858 } 40859 40860 this.$element.append(word_span); 40861 40862 word_size = { 40863 width: word_span.outerWidth(), 40864 height: word_span.outerHeight() 40865 }; 40866 word_size.left = this.options.center.x * this.options.width - word_size.width / 2.0; 40867 word_size.top = this.options.center.y * this.options.height - word_size.height / 2.0; 40868 40869 // Save a reference to the style property, for better performance 40870 word_style = word_span[0].style; 40871 word_style.position = 'absolute'; 40872 word_style.left = word_size.left + 'px'; 40873 word_style.top = word_size.top + 'px'; 40874 40875 while (this.hitTest(word_size)) { 40876 // option shape is 'rectangular' so move the word in a rectangular spiral 40877 if (this.options.shape === 'rectangular') { 40878 steps_in_direction++; 40879 40880 if (steps_in_direction * this.data.step > (1 + Math.floor(quarter_turns / 2.0)) * this.data.step * ((quarter_turns % 4 % 2) === 0 ? 1 : this.data.aspect_ratio)) { 40881 steps_in_direction = 0.0; 40882 quarter_turns++; 40883 } 40884 40885 switch (quarter_turns % 4) { 40886 case 1: 40887 word_size.left += this.data.step * this.data.aspect_ratio + Math.random() * 2.0; 40888 break; 40889 case 2: 40890 word_size.top -= this.data.step + Math.random() * 2.0; 40891 break; 40892 case 3: 40893 word_size.left -= this.data.step * this.data.aspect_ratio + Math.random() * 2.0; 40894 break; 40895 case 0: 40896 word_size.top += this.data.step + Math.random() * 2.0; 40897 break; 40898 } 40899 } 40900 // Default settings: elliptic spiral shape 40901 else { 40902 radius += this.data.step; 40903 angle += (index % 2 === 0 ? 1 : -1) * this.data.step; 40904 40905 word_size.left = this.options.center.x * this.options.width - (word_size.width / 2.0) + (radius * Math.cos(angle)) * this.data.aspect_ratio; 40906 word_size.top = this.options.center.y * this.options.height + radius * Math.sin(angle) - (word_size.height / 2.0); 40907 } 40908 word_style.left = word_size.left + 'px'; 40909 word_style.top = word_size.top + 'px'; 40910 } 40911 40912 // Don't render word if part of it would be outside the container 40913 if (this.options.removeOverflowing && ( 40914 word_size.left < 0 || word_size.top < 0 || 40915 (word_size.left + word_size.width) > this.options.width || 40916 (word_size.top + word_size.height) > this.options.height 40917 ) 40918 ) { 40919 word_span.remove(); 40920 return; 40921 } 40922 40923 // Save position for further usage 40924 this.data.placed_words.push(word_size); 40925 40926 if (typeof word.afterWordRender === 'function') { 40927 word.afterWordRender.call(word_span); 40928 } 40929 }, 40930 40931 // Draw one word then recall the function after a delay 40932 drawOneWordDelayed: function(index) { 40933 index = index || 0; 40934 40935 // if not visible then do not attempt to draw 40936 if (!this.$element.is(':visible')) { 40937 this.createTimeout($.proxy(function() { 40938 this.drawOneWordDelayed(index); 40939 }, this), 10); 40940 40941 return; 40942 } 40943 40944 if (index < this.word_array.length) { 40945 this.drawOneWord(index, this.word_array[index]); 40946 40947 this.createTimeout($.proxy(function() { 40948 this.drawOneWordDelayed(index + 1); 40949 }, this), this.options.delay); 40950 } 40951 else { 40952 if (typeof this.options.afterCloudRender == 'function') { 40953 this.options.afterCloudRender.call(this.$element); 40954 } 40955 } 40956 }, 40957 40958 // Destroy any data and objects added by the plugin 40959 destroy: function() { 40960 if (this.options.autoResize) { 40961 $(window).off('resize.' + this.data.namespace); 40962 } 40963 40964 this.clearTimeouts(); 40965 this.$element.removeClass('jqcloud'); 40966 this.$element.removeData('jqcloud'); 40967 this.$element.children('[id^="' + this.data.namespace + '"]').remove(); 40968 }, 40969 40970 // Update the list of words 40971 update: function(word_array) { 40972 this.word_array = word_array; 40973 this.data.placed_words = []; 40974 40975 this.clearTimeouts(); 40976 this.drawWordCloud(); 40977 }, 40978 40979 resize: function() { 40980 var new_size = { 40981 width: this.$element.width(), 40982 height: this.$element.height() 40983 }; 40984 40985 if (new_size.width != this.options.width || new_size.height != this.options.height) { 40986 this.options.width = new_size.width; 40987 this.options.height = new_size.height; 40988 this.data.aspect_ratio = this.options.width / this.options.height; 40989 40990 this.update(this.word_array); 40991 } 40992 }, 40993}; 40994 40995/* 40996 * Apply throttling to a callback 40997 * @param callback {function} 40998 * @param delay {int} milliseconds 40999 * @param context {object|null} 41000 * @return {function} 41001 */ 41002function throttle(callback, delay, context) { 41003 var state = { 41004 pid: null, 41005 last: 0 41006 }; 41007 41008 return function() { 41009 var elapsed = new Date().getTime() - state.last, 41010 args = arguments, 41011 that = this; 41012 41013 function exec() { 41014 state.last = new Date().getTime(); 41015 return callback.apply(context || that, Array.prototype.slice.call(args)); 41016 } 41017 41018 if (elapsed > delay) { 41019 return exec(); 41020 } 41021 else { 41022 clearTimeout(state.pid); 41023 state.pid = setTimeout(exec, delay - elapsed); 41024 } 41025 }; 41026} 41027 41028/* 41029 * jQuery plugin 41030 */ 41031$.fn.jQCloud = function(word_array, option) { 41032 var args = arguments; 41033 41034 return this.each(function() { 41035 var $this = $(this), 41036 data = $this.data('jqcloud'); 41037 41038 if (!data && word_array === 'destroy') { 41039 // Don't even try to initialize when called with 'destroy' 41040 return; 41041 } 41042 if (!data) { 41043 var options = typeof option === 'object' ? option : {}; 41044 $this.data('jqcloud', (data = new jQCloud(this, word_array, options))); 41045 } 41046 else if (typeof word_array === 'string') { 41047 data[word_array].apply(data, Array.prototype.slice.call(args, 1)); 41048 } 41049 }); 41050}; 41051 41052$.fn.jQCloud.defaults = { 41053 set: function(options) { 41054 $.extend(true, jQCloud.DEFAULTS, options); 41055 }, 41056 get: function(key) { 41057 var options = jQCloud.DEFAULTS; 41058 if (key) { 41059 options = options[key]; 41060 } 41061 return $.extend(true, {}, options); 41062 } 41063}; 41064 41065}));
41065 41066;(function (global, factory) { 41067 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : 41068 typeof define === 'function' && define.amd ? define(['jquery'], factory) : 41069 (global.Util = factory(global.jQuery)); 41070}(this, (function ($) { 'use strict'; 41071 41072 $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 41073 41074 /** 41075 * -------------------------------------------------------------------------- 41076 * Bootstrap (v4.1.3): util.js 41077 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 41078 * -------------------------------------------------------------------------- 41079 */ 41080 41081 var Util = function ($$$1) { 41082 /** 41083 * ------------------------------------------------------------------------ 41084 * Private TransitionEnd Helpers 41085 * ------------------------------------------------------------------------ 41086 */ 41087 var TRANSITION_END = 'transitionend'; 41088 var MAX_UID = 1000000; 41089 var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) 41090 41091 function toType(obj) { 41092 return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); 41093 } 41094 41095 function getSpecialTransitionEndEvent() { 41096 return { 41097 bindType: TRANSITION_END, 41098 delegateType: TRANSITION_END, 41099 handle: function handle(event) { 41100 if ($$$1(event.target).is(this)) { 41101 return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params 41102 } 41103 41104 return undefined; // eslint-disable-line no-undefined 41105 } 41106 }; 41107 } 41108 41109 function transitionEndEmulator(duration) { 41110 var _this = this; 41111 41112 var called = false; 41113 $$$1(this).one(Util.TRANSITION_END, function () { 41114 called = true; 41115 }); 41116 setTimeout(function () { 41117 if (!called) { 41118 Util.triggerTransitionEnd(_this); 41119 } 41120 }, duration); 41121 return this; 41122 } 41123 41124 function setTransitionEndSupport() { 41125 $$$1.fn.emulateTransitionEnd = transitionEndEmulator; 41126 $$$1.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); 41127 } 41128 /** 41129 * -------------------------------------------------------------------------- 41130 * Public Util Api 41131 * -------------------------------------------------------------------------- 41132 */ 41133 41134 41135 var Util = { 41136 TRANSITION_END: 'bsTransitionEnd', 41137 getUID: function getUID(prefix) { 41138 do { 41139 // eslint-disable-next-line no-bitwise 41140 prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here 41141 } while (document.getElementById(prefix)); 41142 41143 return prefix; 41144 }, 41145 getSelectorFromElement: function getSelectorFromElement(element) { 41146 var selector = element.getAttribute('data-target'); 41147 41148 if (!selector || selector === '#') { 41149 selector = element.getAttribute('href') || ''; 41150 } 41151 41152 try { 41153 return document.querySelector(selector) ? selector : null; 41154 } catch (err) { 41155 return null; 41156 } 41157 }, 41158 getTransitionDurationFromElement: function getTransitionDurationFromElement(element) { 41159 if (!element) { 41160 return 0; 41161 } // Get transition-duration of the element 41162 41163 41164 var transitionDuration = $$$1(element).css('transition-duration'); 41165 var floatTransitionDuration = parseFloat(transitionDuration); // Return 0 if element or transition duration is not found 41166 41167 if (!floatTransitionDuration) { 41168 return 0; 41169 } // If multiple durations are defined, take the first 41170 41171 41172 transitionDuration = transitionDuration.split(',')[0]; 41173 return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER; 41174 }, 41175 reflow: function reflow(element) { 41176 return element.offsetHeight; 41177 }, 41178 triggerTransitionEnd: function triggerTransitionEnd(element) { 41179 $$$1(element).trigger(TRANSITION_END); 41180 }, 41181 // TODO: Remove in v5 41182 supportsTransitionEnd: function supportsTransitionEnd() { 41183 return Boolean(TRANSITION_END); 41184 }, 41185 isElement: function isElement(obj) { 41186 return (obj[0] || obj).nodeType; 41187 }, 41188 typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { 41189 for (var property in configTypes) { 41190 if (Object.prototype.hasOwnProperty.call(configTypes, property)) { 41191 var expectedTypes = configTypes[property]; 41192 var value = config[property]; 41193 var valueType = value && Util.isElement(value) ? 'element' : toType(value); 41194 41195 if (!new RegExp(expectedTypes).test(valueType)) { 41196 throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); 41197 } 41198 } 41199 } 41200 } 41201 }; 41202 setTransitionEndSupport(); 41203 return Util; 41204 }($); 41205 41206 return Util; 41207 41208}))); 41209//# sourceMappingURL=util.js.map 41210 41211;(function (global, factory) { 41212 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : 41213 typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : 41214 (global.Modal = factory(global.jQuery,global.Util)); 41215}(this, (function ($,Util) { 'use strict'; 41216 41217 $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 41218 Util = Util && Util.hasOwnProperty('default') ? Util['default'] : Util; 41219 41220 function _defineProperties(target, props) { 41221 for (var i = 0; i < props.length; i++) { 41222 var descriptor = props[i]; 41223 descriptor.enumerable = descriptor.enumerable || false; 41224 descriptor.configurable = true; 41225 if ("value" in descriptor) descriptor.writable = true; 41226 Object.defineProperty(target, descriptor.key, descriptor); 41227 } 41228 } 41229 41230 function _createClass(Constructor, protoProps, staticProps) { 41231 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 41232 if (staticProps) _defineProperties(Constructor, staticProps); 41233 return Constructor; 41234 } 41235 41236 function _defineProperty(obj, key, value) { 41237 if (key in obj) { 41238 Object.defineProperty(obj, key, { 41239 value: value, 41240 enumerable: true, 41241 configurable: true, 41242 writable: true 41243 }); 41244 } else { 41245 obj[key] = value; 41246 } 41247 41248 return obj; 41249 } 41250 41251 function _objectSpread(target) { 41252 for (var i = 1; i < arguments.length; i++) { 41253 var source = arguments[i] != null ? arguments[i] : {}; 41254 var ownKeys = Object.keys(source); 41255 41256 if (typeof Object.getOwnPropertySymbols === 'function') { 41257 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { 41258 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 41259 })); 41260 } 41261 41262 ownKeys.forEach(function (key) { 41263 _defineProperty(target, key, source[key]); 41264 }); 41265 } 41266 41267 return target; 41268 } 41269 41270 /** 41271 * -------------------------------------------------------------------------- 41272 * Bootstrap (v4.1.3): modal.js 41273 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 41274 * -------------------------------------------------------------------------- 41275 */ 41276 41277 var Modal = function ($$$1) { 41278 /** 41279 * ------------------------------------------------------------------------ 41280 * Constants 41281 * ------------------------------------------------------------------------ 41282 */ 41283 var NAME = 'modal'; 41284 var VERSION = '4.1.3'; 41285 var DATA_KEY = 'bs.modal'; 41286 var EVENT_KEY = "." + DATA_KEY; 41287 var DATA_API_KEY = '.data-api'; 41288 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 41289 var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key 41290 41291 var Default = { 41292 backdrop: true, 41293 keyboard: true, 41294 focus: true, 41295 show: true 41296 }; 41297 var DefaultType = { 41298 backdrop: '(boolean|string)', 41299 keyboard: 'boolean', 41300 focus: 'boolean', 41301 show: 'boolean' 41302 }; 41303 var Event = { 41304 HIDE: "hide" + EVENT_KEY, 41305 HIDDEN: "hidden" + EVENT_KEY, 41306 SHOW: "show" + EVENT_KEY, 41307 SHOWN: "shown" + EVENT_KEY, 41308 FOCUSIN: "focusin" + EVENT_KEY, 41309 RESIZE: "resize" + EVENT_KEY, 41310 CLICK_DISMISS: "click.dismiss" + EVENT_KEY, 41311 KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY, 41312 MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY, 41313 MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY, 41314 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY 41315 }; 41316 var ClassName = {
41317 SCROLLBAR_MEASURER: 'modal-scrollbar-measure', 41318 BACKDROP: 'modal-backdrop', 41319 OPEN: 'modal-open', 41320 FADE: 'fade', 41321 SHOW: 'show' 41322 }; 41323 var Selector = { 41324 DIALOG: '.modal-dialog', 41325 DATA_TOGGLE: '[data-toggle="modal"]', 41326 DATA_DISMISS: '[data-dismiss="modal"]', 41327 FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', 41328 STICKY_CONTENT: '.sticky-top' 41329 /** 41330 * ------------------------------------------------------------------------ 41331 * Class Definition 41332 * ------------------------------------------------------------------------ 41333 */ 41334 41335 }; 41336 41337 var Modal = 41338 /*#__PURE__*/ 41339 function () { 41340 function Modal(element, config) { 41341 this._config = this._getConfig(config); 41342 this._element = element; 41343 this._dialog = element.querySelector(Selector.DIALOG); 41344 this._backdrop = null; 41345 this._isShown = false; 41346 this._isBodyOverflowing = false; 41347 this._ignoreBackdropClick = false; 41348 this._scrollbarWidth = 0; 41349 } // Getters 41350 41351 41352 var _proto = Modal.prototype; 41353 41354 // Public 41355 _proto.toggle = function toggle(relatedTarget) { 41356 return this._isShown ? this.hide() : this.show(relatedTarget); 41357 }; 41358 41359 _proto.show = function show(relatedTarget) { 41360 var _this = this; 41361 41362 if (this._isTransitioning || this._isShown) { 41363 return; 41364 } 41365 41366 if ($$$1(this._element).hasClass(ClassName.FADE)) { 41367 this._isTransitioning = true; 41368 } 41369 41370 var showEvent = $$$1.Event(Event.SHOW, { 41371 relatedTarget: relatedTarget 41372 }); 41373 $$$1(this._element).trigger(showEvent); 41374 41375 if (this._isShown || showEvent.isDefaultPrevented()) { 41376 return; 41377 } 41378 41379 this._isShown = true; 41380 41381 this._checkScrollbar(); 41382 41383 this._setScrollbar(); 41384 41385 this._adjustDialog(); 41386 41387 $$$1(document.body).addClass(ClassName.OPEN); 41388 41389 this._setEscapeEvent(); 41390 41391 this._setResizeEvent(); 41392 41393 $$$1(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) { 41394 return _this.hide(event); 41395 }); 41396 $$$1(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () { 41397 $$$1(_this._element).one(Event.MOUSEUP_DISMISS, function (event) { 41398 if ($$$1(event.target).is(_this._element)) { 41399 _this._ignoreBackdropClick = true; 41400 } 41401 }); 41402 }); 41403 41404 this._showBackdrop(function () { 41405 return _this._showElement(relatedTarget); 41406 }); 41407 }; 41408 41409 _proto.hide = function hide(event) { 41410 var _this2 = this; 41411 41412 if (event) { 41413 event.preventDefault(); 41414 } 41415 41416 if (this._isTransitioning || !this._isShown) { 41417 return; 41418 } 41419 41420 var hideEvent = $$$1.Event(Event.HIDE); 41421 $$$1(this._element).trigger(hideEvent); 41422 41423 if (!this._isShown || hideEvent.isDefaultPrevented()) { 41424 return; 41425 } 41426 41427 this._isShown = false; 41428 var transition = $$$1(this._element).hasClass(ClassName.FADE); 41429 41430 if (transition) { 41431 this._isTransitioning = true; 41432 } 41433 41434 this._setEscapeEvent(); 41435 41436 this._setResizeEvent(); 41437 41438 $$$1(document).off(Event.FOCUSIN); 41439 $$$1(this._element).removeClass(ClassName.SHOW); 41440 $$$1(this._element).off(Event.CLICK_DISMISS); 41441 $$$1(this._dialog).off(Event.MOUSEDOWN_DISMISS); 41442 41443 if (transition) { 41444 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 41445 $$$1(this._element).one(Util.TRANSITION_END, function (event) { 41446 return _this2._hideModal(event); 41447 }).emulateTransitionEnd(transitionDuration); 41448 } else { 41449 this._hideModal(); 41450 } 41451 }; 41452 41453 _proto.dispose = function dispose() { 41454 $$$1.removeData(this._element, DATA_KEY); 41455 $$$1(window, document, this._element, this._backdrop).off(EVENT_KEY); 41456 this._config = null; 41457 this._element = null; 41458 this._dialog = null; 41459 this._backdrop = null; 41460 this._isShown = null; 41461 this._isBodyOverflowing = null; 41462 this._ignoreBackdropClick = null; 41463 this._scrollbarWidth = null; 41464 }; 41465 41466 _proto.handleUpdate = function handleUpdate() { 41467 this._adjustDialog(); 41468 }; // Private 41469 41470 41471 _proto._getConfig = function _getConfig(config) { 41472 config = _objectSpread({}, Default, config); 41473 Util.typeCheckConfig(NAME, config, DefaultType); 41474 return config; 41475 }; 41476 41477 _proto._showElement = function _showElement(relatedTarget) { 41478 var _this3 = this; 41479 41480 var transition = $$$1(this._element).hasClass(ClassName.FADE); 41481 41482 if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { 41483 // Don't move modal's DOM position 41484 document.body.appendChild(this._element); 41485 } 41486 41487 this._element.style.display = 'block'; 41488 41489 this._element.removeAttribute('aria-hidden'); 41490 41491 this._element.scrollTop = 0; 41492 41493 if (transition) { 41494 Util.reflow(this._element); 41495 } 41496 41497 $$$1(this._element).addClass(ClassName.SHOW); 41498 41499 if (this._config.focus) { 41500 this._enforceFocus(); 41501 } 41502 41503 var shownEvent = $$$1.Event(Event.SHOWN, { 41504 relatedTarget: relatedTarget 41505 }); 41506 41507 var transitionComplete = function transitionComplete() { 41508 if (_this3._config.focus) { 41509 _this3._element.focus(); 41510 } 41511 41512 _this3._isTransitioning = false;
41513 $$$1(_this3._element).trigger(shownEvent); 41514 }; 41515 41516 if (transition) { 41517 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 41518 $$$1(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration); 41519 } else { 41520 transitionComplete(); 41521 } 41522 }; 41523 41524 _proto._enforceFocus = function _enforceFocus() { 41525 var _this4 = this; 41526 41527 $$$1(document).off(Event.FOCUSIN) // Guard against infinite focus loop 41528 .on(Event.FOCUSIN, function (event) { 41529 if (document !== event.target && _this4._element !== event.target && $$$1(_this4._element).has(event.target).length === 0) { 41530 _this4._element.focus(); 41531 } 41532 }); 41533 }; 41534 41535 _proto._setEscapeEvent = function _setEscapeEvent() { 41536 var _this5 = this; 41537 41538 if (this._isShown && this._config.keyboard) { 41539 $$$1(this._element).on(Event.KEYDOWN_DISMISS, function (event) { 41540 if (event.which === ESCAPE_KEYCODE) { 41541 event.preventDefault(); 41542 41543 _this5.hide(); 41544 } 41545 }); 41546 } else if (!this._isShown) { 41547 $$$1(this._element).off(Event.KEYDOWN_DISMISS); 41548 } 41549 }; 41550 41551 _proto._setResizeEvent = function _setResizeEvent() { 41552 var _this6 = this; 41553 41554 if (this._isShown) { 41555 $$$1(window).on(Event.RESIZE, function (event) { 41556 return _this6.handleUpdate(event); 41557 }); 41558 } else { 41559 $$$1(window).off(Event.RESIZE); 41560 } 41561 }; 41562 41563 _proto._hideModal = function _hideModal() { 41564 var _this7 = this; 41565 41566 this._element.style.display = 'none'; 41567 41568 this._element.setAttribute('aria-hidden', true); 41569 41570 this._isTransitioning = false; 41571 41572 this._showBackdrop(function () { 41573 $$$1(document.body).removeClass(ClassName.OPEN); 41574 41575 _this7._resetAdjustments(); 41576 41577 _this7._resetScrollbar(); 41578 41579 $$$1(_this7._element).trigger(Event.HIDDEN); 41580 }); 41581 }; 41582 41583 _proto._removeBackdrop = function _removeBackdrop() { 41584 if (this._backdrop) { 41585 $$$1(this._backdrop).remove(); 41586 this._backdrop = null; 41587 } 41588 }; 41589 41590 _proto._showBackdrop = function _showBackdrop(callback) { 41591 var _this8 = this; 41592 41593 var animate = $$$1(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : ''; 41594 41595 if (this._isShown && this._config.backdrop) { 41596 this._backdrop = document.createElement('div'); 41597 this._backdrop.className = ClassName.BACKDROP; 41598 41599 if (animate) { 41600 this._backdrop.classList.add(animate); 41601 } 41602 41603 $$$1(this._backdrop).appendTo(document.body); 41604 $$$1(this._element).on(Event.CLICK_DISMISS, function (event) { 41605 if (_this8._ignoreBackdropClick) { 41606 _this8._ignoreBackdropClick = false; 41607 return; 41608 } 41609 41610 if (event.target !== event.currentTarget) { 41611 return; 41612 } 41613 41614 if (_this8._config.backdrop === 'static') { 41615 _this8._element.focus(); 41616 } else { 41617 _this8.hide(); 41618 } 41619 }); 41620 41621 if (animate) { 41622 Util.reflow(this._backdrop); 41623 } 41624 41625 $$$1(this._backdrop).addClass(ClassName.SHOW); 41626 41627 if (!callback) { 41628 return; 41629 } 41630 41631 if (!animate) { 41632 callback(); 41633 return; 41634 } 41635 41636 var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); 41637 $$$1(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration); 41638 } else if (!this._isShown && this._backdrop) { 41639 $$$1(this._backdrop).removeClass(ClassName.SHOW); 41640 41641 var callbackRemove = function callbackRemove() { 41642 _this8._removeBackdrop(); 41643 41644 if (callback) { 41645 callback(); 41646 } 41647 }; 41648 41649 if ($$$1(this._element).hasClass(ClassName.FADE)) { 41650 var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); 41651 41652 $$$1(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration); 41653 } else { 41654 callbackRemove(); 41655 } 41656 } else if (callback) { 41657 callback(); 41658 } 41659 }; // ---------------------------------------------------------------------- 41660 // the following methods are used to handle overflowing modals 41661 // todo (fat): these should probably be refactored out of modal.js 41662 // ---------------------------------------------------------------------- 41663 41664
41665 _proto._adjustDialog = function _adjustDialog() { 41666 var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 41667 41668 if (!this._isBodyOverflowing && isModalOverflowing) { 41669 this._element.style.paddingLeft = this._scrollbarWidth + "px"; 41670 } 41671 41672 if (this._isBodyOverflowing && !isModalOverflowing) { 41673 this._element.style.paddingRight = this._scrollbarWidth + "px"; 41674 } 41675 }; 41676 41677 _proto._resetAdjustments = function _resetAdjustments() { 41678 this._element.style.paddingLeft = ''; 41679 this._element.style.paddingRight = ''; 41680 }; 41681 41682 _proto._checkScrollbar = function _checkScrollbar() { 41683 var rect = document.body.getBoundingClientRect(); 41684 this._isBodyOverflowing = rect.left + rect.right < window.innerWidth; 41685 this._scrollbarWidth = this._getScrollbarWidth(); 41686 }; 41687 41688 _proto._setScrollbar = function _setScrollbar() { 41689 var _this9 = this; 41690 41691 if (this._isBodyOverflowing) { 41692 // Note: DOMNode.style.paddingRight returns the actual value or '' if not set 41693 // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set 41694 var fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT)); 41695 var stickyContent = [].slice.call(document.querySelectorAll(Selector.STICKY_CONTENT)); // Adjust fixed content padding 41696 41697 $$$1(fixedContent).each(function (index, element) { 41698 var actualPadding = element.style.paddingRight; 41699 var calculatedPadding = $$$1(element).css('padding-right'); 41700 $$$1(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + "px"); 41701 }); // Adjust sticky content margin 41702 41703 $$$1(stickyContent).each(function (index, element) { 41704 var actualMargin = element.style.marginRight; 41705 var calculatedMargin = $$$1(element).css('margin-right'); 41706 $$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + "px"); 41707 }); // Adjust body padding 41708 41709 var actualPadding = document.body.style.paddingRight; 41710 var calculatedPadding = $$$1(document.body).css('padding-right'); 41711 $$$1(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px"); 41712 } 41713 }; 41714 41715 _proto._resetScrollbar = function _resetScrollbar() { 41716 // Restore fixed content padding 41717 var fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT)); 41718 $$$1(fixedContent).each(function (index, element) { 41719 var padding = $$$1(element).data('padding-right'); 41720 $$$1(element).removeData('padding-right'); 41721 element.style.paddingRight = padding ? padding : ''; 41722 }); // Restore sticky content 41723 41724 var elements = [].slice.call(document.querySelectorAll("" + Selector.STICKY_CONTENT)); 41725 $$$1(elements).each(function (index, element) { 41726 var margin = $$$1(element).data('margin-right'); 41727 41728 if (typeof margin !== 'undefined') { 41729 $$$1(element).css('margin-right', margin).removeData('margin-right'); 41730 } 41731 }); // Restore body padding 41732 41733 var padding = $$$1(document.body).data('padding-right'); 41734 $$$1(document.body).removeData('padding-right'); 41735 document.body.style.paddingRight = padding ? padding : ''; 41736 }; 41737 41738 _proto._getScrollbarWidth = function _getScrollbarWidth() { 41739 // thx d.walsh 41740 var scrollDiv = document.createElement('div'); 41741 scrollDiv.className = ClassName.SCROLLBAR_MEASURER; 41742 document.body.appendChild(scrollDiv); 41743 var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; 41744 document.body.removeChild(scrollDiv); 41745 return scrollbarWidth; 41746 }; // Static 41747 41748 41749 Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) { 41750 return this.each(function () { 41751 var data = $$$1(this).data(DATA_KEY); 41752 41753 var _config = _objectSpread({}, Default, $$$1(this).data(), typeof config === 'object' && config ? config : {}); 41754 41755 if (!data) { 41756 data = new Modal(this, _config); 41757 $$$1(this).data(DATA_KEY, data); 41758 } 41759 41760 if (typeof config === 'string') { 41761 if (typeof data[config] === 'undefined') {
41762 throw new TypeError("No method named \"" + config + "\""); 41763 } 41764 41765 data[config](relatedTarget); 41766 } else if (_config.show) { 41767 data.show(relatedTarget); 41768 } 41769 }); 41770 }; 41771 41772 _createClass(Modal, null, [{ 41773 key: "VERSION", 41774 get: function get() { 41775 return VERSION; 41776 } 41777 }, { 41778 key: "Default", 41779 get: function get() { 41780 return Default; 41781 } 41782 }]); 41783 41784 return Modal; 41785 }(); 41786 /** 41787 * ------------------------------------------------------------------------ 41788 * Data Api implementation 41789 * ------------------------------------------------------------------------ 41790 */ 41791 41792 41793 $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { 41794 var _this10 = this; 41795 41796 var target; 41797 var selector = Util.getSelectorFromElement(this); 41798 41799 if (selector) { 41800 target = document.querySelector(selector); 41801 } 41802 41803 var config = $$$1(target).data(DATA_KEY) ? 'toggle' : _objectSpread({}, $$$1(target).data(), $$$1(this).data()); 41804 41805 if (this.tagName === 'A' || this.tagName === 'AREA') { 41806 event.preventDefault(); 41807 } 41808 41809 var $target = $$$1(target).one(Event.SHOW, function (showEvent) { 41810 if (showEvent.isDefaultPrevented()) { 41811 // Only register focus restorer if modal will actually get shown 41812 return; 41813 } 41814 41815 $target.one(Event.HIDDEN, function () { 41816 if ($$$1(_this10).is(':visible')) { 41817 _this10.focus(); 41818 } 41819 }); 41820 }); 41821 41822 Modal._jQueryInterface.call($$$1(target), config, this); 41823 }); 41824 /** 41825 * ------------------------------------------------------------------------ 41826 * jQuery 41827 * ------------------------------------------------------------------------ 41828 */ 41829 41830 $$$1.fn[NAME] = Modal._jQueryInterface; 41831 $$$1.fn[NAME].Constructor = Modal; 41832 41833 $$$1.fn[NAME].noConflict = function () { 41834 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 41835 return Modal._jQueryInterface; 41836 }; 41837 41838 return Modal; 41839 }($); 41840 41841 return Modal; 41842 41843}))); 41844//# sourceMappingURL=modal.js.map 41845 41846;(function (global, factory) { 41847 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : 41848 typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : 41849 (global.Dropdown = factory(global.jQuery,global.Popper,global.Util)); 41850}(this, (function ($,Popper,Util) { 'use strict'; 41851 41852 $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 41853 Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper; 41854 Util = Util && Util.hasOwnProperty('default') ? Util['default'] : Util; 41855 41856 function _defineProperties(target, props) { 41857 for (var i = 0; i < props.length; i++) { 41858 var descriptor = props[i]; 41859 descriptor.enumerable = descriptor.enumerable || false; 41860 descriptor.configurable = true; 41861 if ("value" in descriptor) descriptor.writable = true; 41862 Object.defineProperty(target, descriptor.key, descriptor); 41863 } 41864 } 41865 41866 function _createClass(Constructor, protoProps, staticProps) { 41867 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 41868 if (staticProps) _defineProperties(Constructor, staticProps); 41869 return Constructor; 41870 } 41871 41872 function _defineProperty(obj, key, value) { 41873 if (key in obj) { 41874 Object.defineProperty(obj, key, { 41875 value: value, 41876 enumerable: true, 41877 configurable: true, 41878 writable: true 41879 }); 41880 } else { 41881 obj[key] = value; 41882 } 41883 41884 return obj; 41885 } 41886 41887 function _objectSpread(target) { 41888 for (var i = 1; i < arguments.length; i++) { 41889 var source = arguments[i] != null ? arguments[i] : {}; 41890 var ownKeys = Object.keys(source); 41891 41892 if (typeof Object.getOwnPropertySymbols === 'function') { 41893 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { 41894 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 41895 })); 41896 } 41897 41898 ownKeys.forEach(function (key) { 41899 _defineProperty(target, key, source[key]); 41900 }); 41901 } 41902 41903 return target; 41904 } 41905 41906 /** 41907 * -------------------------------------------------------------------------- 41908 * Bootstrap (v4.1.3): dropdown.js 41909 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 41910 * -------------------------------------------------------------------------- 41911 */ 41912 41913 var Dropdown = function ($$$1) { 41914 /** 41915 * ------------------------------------------------------------------------ 41916 * Constants 41917 * ------------------------------------------------------------------------ 41918 */ 41919 var NAME = 'dropdown'; 41920 var VERSION = '4.1.3'; 41921 var DATA_KEY = 'bs.dropdown'; 41922 var EVENT_KEY = "." + DATA_KEY; 41923 var DATA_API_KEY = '.data-api'; 41924 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 41925 var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key 41926 41927 var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key 41928 41929 var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key 41930 41931 var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key 41932 41933 var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key 41934 41935 var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) 41936 41937 var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE); 41938 var Event = { 41939 HIDE: "hide" + EVENT_KEY, 41940 HIDDEN: "hidden" + EVENT_KEY, 41941 SHOW: "show" + EVENT_KEY, 41942 SHOWN: "shown" + EVENT_KEY, 41943 CLICK: "click" + EVENT_KEY, 41944 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY, 41945 KEYDOWN_DATA_API: "keydown" + EVENT_KEY + DATA_API_KEY, 41946 KEYUP_DATA_API: "keyup" + EVENT_KEY + DATA_API_KEY 41947 }; 41948 var ClassName = { 41949 DISABLED: 'disabled', 41950 SHOW: 'show', 41951 DROPUP: 'dropup', 41952 DROPRIGHT: 'dropright', 41953 DROPLEFT: 'dropleft', 41954 MENURIGHT: 'dropdown-menu-right', 41955 MENULEFT: 'dropdown-menu-left', 41956 POSITION_STATIC: 'position-static' 41957 }; 41958 var Selector = { 41959 DATA_TOGGLE: '[data-toggle="dropdown"]', 41960 FORM_CHILD: '.dropdown form', 41961 MENU: '.dropdown-menu', 41962 NAVBAR_NAV: '.navbar-nav', 41963 VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' 41964 }; 41965 var AttachmentMap = { 41966 TOP: 'top-start', 41967 TOPEND: 'top-end', 41968 BOTTOM: 'bottom-start', 41969 BOTTOMEND: 'bottom-end', 41970 RIGHT: 'right-start', 41971 RIGHTEND: 'right-end', 41972 LEFT: 'left-start', 41973 LEFTEND: 'left-end' 41974 }; 41975 var Default = { 41976 offset: 0, 41977 flip: true, 41978 boundary: 'scrollParent', 41979 reference: 'toggle', 41980 display: 'dynamic' 41981 }; 41982 var DefaultType = { 41983 offset: '(number|string|function)', 41984 flip: 'boolean', 41985 boundary: '(string|element)', 41986 reference: '(string|element)', 41987 display: 'string' 41988 /** 41989 * ------------------------------------------------------------------------ 41990 * Class Definition 41991 * ------------------------------------------------------------------------ 41992 */ 41993 41994 }; 41995 41996 var Dropdown = 41997 /*#__PURE__*/ 41998 function () { 41999 function Dropdown(element, config) { 42000 this._element = element; 42001 this._popper = null; 42002 this._config = this._getConfig(config); 42003 this._menu = this._getMenuElement(); 42004 this._inNavbar = this._detectNavbar(); 42005 42006 this._addEventListeners(); 42007 } // Getters 42008 42009 42010 var _proto = Dropdown.prototype; 42011 42012 // Public
42013 _proto.toggle = function toggle() { 42014 if (this._element.disabled || $$$1(this._element).hasClass(ClassName.DISABLED)) { 42015 return; 42016 } 42017 42018 var parent = Dropdown._getParentFromElement(this._element); 42019 42020 var isActive = $$$1(this._menu).hasClass(ClassName.SHOW); 42021 42022 Dropdown._clearMenus(); 42023 42024 if (isActive) { 42025 return; 42026 } 42027 42028 var relatedTarget = { 42029 relatedTarget: this._element 42030 }; 42031 var showEvent = $$$1.Event(Event.SHOW, relatedTarget); 42032 $$$1(parent).trigger(showEvent); 42033 42034 if (showEvent.isDefaultPrevented()) { 42035 return; 42036 } // Disable totally Popper.js for Dropdown in Navbar 42037 42038 42039 if (!this._inNavbar) { 42040 /** 42041 * Check for Popper dependency 42042 * Popper - https://popper.js.org 42043 */ 42044 if (typeof Popper === 'undefined') { 42045 throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)'); 42046 } 42047 42048 var referenceElement = this._element; 42049 42050 if (this._config.reference === 'parent') { 42051 referenceElement = parent; 42052 } else if (Util.isElement(this._config.reference)) { 42053 referenceElement = this._config.reference; // Check if it's jQuery element 42054 42055 if (typeof this._config.reference.jquery !== 'undefined') { 42056 referenceElement = this._config.reference[0]; 42057 } 42058 } // If boundary is not `scrollParent`, then set position to `static` 42059 // to allow the menu to "escape" the scroll parent's boundaries 42060 // https://github.com/twbs/bootstrap/issues/24251 42061 42062 42063 if (this._config.boundary !== 'scrollParent') { 42064 $$$1(parent).addClass(ClassName.POSITION_STATIC); 42065 } 42066 42067 this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); 42068 } // If this is a touch-enabled device we add extra 42069 // empty mouseover listeners to the body's immediate children; 42070 // only needed because of broken event delegation on iOS 42071 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 42072 42073 42074 if ('ontouchstart' in document.documentElement && $$$1(parent).closest(Selector.NAVBAR_NAV).length === 0) { 42075 $$$1(document.body).children().on('mouseover', null, $$$1.noop); 42076 } 42077 42078 this._element.focus(); 42079 42080 this._element.setAttribute('aria-expanded', true); 42081 42082 $$$1(this._menu).toggleClass(ClassName.SHOW); 42083 $$$1(parent).toggleClass(ClassName.SHOW).trigger($$$1.Event(Event.SHOWN, relatedTarget)); 42084 }; 42085 42086 _proto.dispose = function dispose() { 42087 $$$1.removeData(this._element, DATA_KEY); 42088 $$$1(this._element).off(EVENT_KEY); 42089 this._element = null; 42090 this._menu = null; 42091 42092 if (this._popper !== null) { 42093 this._popper.destroy(); 42094 42095 this._popper = null; 42096 } 42097 }; 42098 42099 _proto.update = function update() { 42100 this._inNavbar = this._detectNavbar(); 42101 42102 if (this._popper !== null) { 42103 this._popper.scheduleUpdate(); 42104 } 42105 }; // Private 42106 42107 42108 _proto._addEventListeners = function _addEventListeners() { 42109 var _this = this; 42110 42111 $$$1(this._element).on(Event.CLICK, function (event) { 42112 event.preventDefault(); 42113 event.stopPropagation(); 42114 42115 _this.toggle(); 42116 }); 42117 }; 42118 42119 _proto._getConfig = function _getConfig(config) { 42120 config = _objectSpread({}, this.constructor.Default, $$$1(this._element).data(), config); 42121 Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); 42122 return config; 42123 }; 42124 42125 _proto._getMenuElement = function _getMenuElement() { 42126 if (!this._menu) { 42127 var parent = Dropdown._getParentFromElement(this._element); 42128 42129 if (parent) { 42130 this._menu = parent.querySelector(Selector.MENU); 42131 } 42132 } 42133 42134 return this._menu; 42135 }; 42136 42137 _proto._getPlacement = function _getPlacement() { 42138 var $parentDropdown = $$$1(this._element.parentNode); 42139 var placement = AttachmentMap.BOTTOM; // Handle dropup 42140 42141 if ($parentDropdown.hasClass(ClassName.DROPUP)) { 42142 placement = AttachmentMap.TOP; 42143 42144 if ($$$1(this._menu).hasClass(ClassName.MENURIGHT)) { 42145 placement = AttachmentMap.TOPEND; 42146 } 42147 } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) { 42148 placement = AttachmentMap.RIGHT; 42149 } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) { 42150 placement = AttachmentMap.LEFT; 42151 } else if ($$$1(this._menu).hasClass(ClassName.MENURIGHT)) { 42152 placement = AttachmentMap.BOTTOMEND; 42153 } 42154 42155 return placement; 42156 }; 42157 42158 _proto._detectNavbar = function _detectNavbar() { 42159 return $$$1(this._element).closest('.navbar').length > 0; 42160 }; 42161 42162 _proto._getPopperConfig = function _getPopperConfig() { 42163 var _this2 = this; 42164 42165 var offsetConf = {}; 42166 42167 if (typeof this._config.offset === 'function') { 42168 offsetConf.fn = function (data) { 42169 data.offsets = _objectSpread({}, data.offsets, _this2._config.offset(data.offsets) || {}); 42170 return data; 42171 }; 42172 } else { 42173 offsetConf.offset = this._config.offset; 42174 } 42175 42176 var popperConfig = { 42177 placement: this._getPlacement(), 42178 modifiers: { 42179 offset: offsetConf, 42180 flip: { 42181 enabled: this._config.flip 42182 }, 42183 preventOverflow: {
42184 boundariesElement: this._config.boundary 42185 } 42186 } // Disable Popper.js if we have a static display 42187 42188 }; 42189 42190 if (this._config.display === 'static') { 42191 popperConfig.modifiers.applyStyle = { 42192 enabled: false 42193 }; 42194 } 42195 42196 return popperConfig; 42197 }; // Static 42198 42199 42200 Dropdown._jQueryInterface = function _jQueryInterface(config) { 42201 return this.each(function () { 42202 var data = $$$1(this).data(DATA_KEY); 42203 42204 var _config = typeof config === 'object' ? config : null; 42205 42206 if (!data) { 42207 data = new Dropdown(this, _config); 42208 $$$1(this).data(DATA_KEY, data); 42209 } 42210 42211 if (typeof config === 'string') { 42212 if (typeof data[config] === 'undefined') { 42213 throw new TypeError("No method named \"" + config + "\""); 42214 } 42215 42216 data[config](); 42217 } 42218 }); 42219 }; 42220 42221 Dropdown._clearMenus = function _clearMenus(event) { 42222 if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { 42223 return; 42224 } 42225 42226 var toggles = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE)); 42227 42228 for (var i = 0, len = toggles.length; i < len; i++) { 42229 var parent = Dropdown._getParentFromElement(toggles[i]); 42230 42231 var context = $$$1(toggles[i]).data(DATA_KEY); 42232 var relatedTarget = { 42233 relatedTarget: toggles[i] 42234 }; 42235 42236 if (event && event.type === 'click') { 42237 relatedTarget.clickEvent = event; 42238 } 42239 42240 if (!context) { 42241 continue; 42242 } 42243 42244 var dropdownMenu = context._menu; 42245 42246 if (!$$$1(parent).hasClass(ClassName.SHOW)) { 42247 continue; 42248 } 42249 42250 if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $$$1.contains(parent, event.target)) { 42251 continue; 42252 } 42253 42254 var hideEvent = $$$1.Event(Event.HIDE, relatedTarget); 42255 $$$1(parent).trigger(hideEvent); 42256 42257 if (hideEvent.isDefaultPrevented()) { 42258 continue; 42259 } // If this is a touch-enabled device we remove the extra 42260 // empty mouseover listeners we added for iOS support 42261 42262 42263 if ('ontouchstart' in document.documentElement) { 42264 $$$1(document.body).children().off('mouseover', null, $$$1.noop); 42265 } 42266 42267 toggles[i].setAttribute('aria-expanded', 'false'); 42268 $$$1(dropdownMenu).removeClass(ClassName.SHOW); 42269 $$$1(parent).removeClass(ClassName.SHOW).trigger($$$1.Event(Event.HIDDEN, relatedTarget)); 42270 } 42271 }; 42272 42273 Dropdown._getParentFromElement = function _getParentFromElement(element) { 42274 var parent; 42275 var selector = Util.getSelectorFromElement(element); 42276 42277 if (selector) { 42278 parent = document.querySelector(selector); 42279 } 42280 42281 return parent || element.parentNode; 42282 }; // eslint-disable-next-line complexity 42283 42284 42285 Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { 42286 // If not input/textarea: 42287 // - And not a key in REGEXP_KEYDOWN => not a dropdown command 42288 // If input/textarea: 42289 // - If space key => not a dropdown command 42290 // - If key is other than escape 42291 // - If key is not up or down => not a dropdown command 42292 // - If trigger inside the menu => not a dropdown command 42293 if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $$$1(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { 42294 return; 42295 } 42296 42297 event.preventDefault(); 42298 event.stopPropagation(); 42299 42300 if (this.disabled || $$$1(this).hasClass(ClassName.DISABLED)) { 42301 return; 42302 } 42303 42304 var parent = Dropdown._getParentFromElement(this); 42305 42306 var isActive = $$$1(parent).hasClass(ClassName.SHOW); 42307 42308 if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { 42309 if (event.which === ESCAPE_KEYCODE) { 42310 var toggle = parent.querySelector(Selector.DATA_TOGGLE); 42311 $$$1(toggle).trigger('focus'); 42312 } 42313 42314 $$$1(this).trigger('click'); 42315 return; 42316 } 42317 42318 var items = [].slice.call(parent.querySelectorAll(Selector.VISIBLE_ITEMS)); 42319 42320 if (items.length === 0) { 42321 return; 42322 } 42323 42324 var index = items.indexOf(event.target); 42325 42326 if (event.which === ARROW_UP_KEYCODE && index > 0) { 42327 // Up 42328 index--; 42329 } 42330 42331 if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { 42332 // Down 42333 index++; 42334 } 42335 42336 if (index < 0) { 42337 index = 0; 42338 } 42339 42340 items[index].focus(); 42341 }; 42342 42343 _createClass(Dropdown, null, [{ 42344 key: "VERSION", 42345 get: function get() { 42346 return VERSION; 42347 } 42348 }, { 42349 key: "Default", 42350 get: function get() { 42351 return Default; 42352 } 42353 }, { 42354 key: "DefaultType", 42355 get: function get() { 42356 return DefaultType; 42357 } 42358 }]); 42359 42360 return Dropdown; 42361 }(); 42362 /** 42363 * ------------------------------------------------------------------------ 42364 * Data Api implementation 42365 * ------------------------------------------------------------------------ 42366 */ 42367 42368 42369 $$$1(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { 42370 event.preventDefault(); 42371 event.stopPropagation(); 42372 42373 Dropdown._jQueryInterface.call($$$1(this), 'toggle'); 42374 }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) { 42375 e.stopPropagation(); 42376 }); 42377 /** 42378 * ------------------------------------------------------------------------ 42379 * jQuery 42380 * ------------------------------------------------------------------------ 42381 */ 42382 42383 $$$1.fn[NAME] = Dropdown._jQueryInterface; 42384 $$$1.fn[NAME].Constructor = Dropdown; 42385 42386 $$$1.fn[NAME].noConflict = function () { 42387 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 42388 return Dropdown._jQueryInterface; 42389 }; 42390 42391 return Dropdown; 42392 }($, Popper); 42393 42394 return Dropdown; 42395 42396}))); 42397//# sourceMappingURL=dropdown.js.map 42398 42399;(function (global, factory) { 42400 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : 42401 typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : 42402 (global.Tooltip = factory(global.jQuery,global.Popper,global.Util)); 42403}(this, (function ($,Popper,Util) { 'use strict'; 42404 42405 $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 42406 Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper; 42407 Util = Util && Util.hasOwnProperty('default') ? Util['default'] : Util; 42408 42409 function _defineProperties(target, props) { 42410 for (var i = 0; i < props.length; i++) { 42411 var descriptor = props[i]; 42412 descriptor.enumerable = descriptor.enumerable || false; 42413 descriptor.configurable = true; 42414 if ("value" in descriptor) descriptor.writable = true; 42415 Object.defineProperty(target, descriptor.key, descriptor); 42416 } 42417 } 42418 42419 function _createClass(Constructor, protoProps, staticProps) { 42420 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 42421 if (staticProps) _defineProperties(Constructor, staticProps); 42422 return Constructor; 42423 } 42424 42425 function _defineProperty(obj, key, value) { 42426 if (key in obj) { 42427 Object.defineProperty(obj, key, { 42428 value: value, 42429 enumerable: true, 42430 configurable: true, 42431 writable: true 42432 }); 42433 } else { 42434 obj[key] = value; 42435 } 42436 42437 return obj; 42438 } 42439 42440 function _objectSpread(target) { 42441 for (var i = 1; i < arguments.length; i++) { 42442 var source = arguments[i] != null ? arguments[i] : {}; 42443 var ownKeys = Object.keys(source); 42444 42445 if (typeof Object.getOwnPropertySymbols === 'function') { 42446 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { 42447 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 42448 })); 42449 } 42450 42451 ownKeys.forEach(function (key) { 42452 _defineProperty(target, key, source[key]); 42453 }); 42454 } 42455 42456 return target; 42457 } 42458 42459 /** 42460 * -------------------------------------------------------------------------- 42461 * Bootstrap (v4.1.3): tooltip.js 42462 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 42463 * -------------------------------------------------------------------------- 42464 */ 42465 42466 var Tooltip = function ($$$1) { 42467 /** 42468 * ------------------------------------------------------------------------ 42469 * Constants 42470 * ------------------------------------------------------------------------ 42471 */ 42472 var NAME = 'tooltip'; 42473 var VERSION = '4.1.3'; 42474 var DATA_KEY = 'bs.tooltip'; 42475 var EVENT_KEY = "." + DATA_KEY; 42476 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 42477 var CLASS_PREFIX = 'bs-tooltip'; 42478 var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); 42479 var DefaultType = { 42480 animation: 'boolean', 42481 template: 'string', 42482 title: '(string|element|function)', 42483 trigger: 'string', 42484 delay: '(number|object)', 42485 html: 'boolean', 42486 selector: '(string|boolean)', 42487 placement: '(string|function)', 42488 offset: '(number|string)', 42489 container: '(string|element|boolean)', 42490 fallbackPlacement: '(string|array)', 42491 boundary: '(string|element)' 42492 }; 42493 var AttachmentMap = { 42494 AUTO: 'auto', 42495 TOP: 'top', 42496 RIGHT: 'right', 42497 BOTTOM: 'bottom', 42498 LEFT: 'left' 42499 }; 42500 var Default = { 42501 animation: true, 42502 template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', 42503 trigger: 'hover focus', 42504 title: '', 42505 delay: 0, 42506 html: false, 42507 selector: false, 42508 placement: 'top', 42509 offset: 0, 42510 container: false, 42511 fallbackPlacement: 'flip', 42512 boundary: 'scrollParent' 42513 }; 42514 var HoverState = { 42515 SHOW: 'show', 42516 OUT: 'out' 42517 }; 42518 var Event = { 42519 HIDE: "hide" + EVENT_KEY, 42520 HIDDEN: "hidden" + EVENT_KEY, 42521 SHOW: "show" + EVENT_KEY, 42522 SHOWN: "shown" + EVENT_KEY, 42523 INSERTED: "inserted" + EVENT_KEY, 42524 CLICK: "click" + EVENT_KEY, 42525 FOCUSIN: "focusin" + EVENT_KEY, 42526 FOCUSOUT: "focusout" + EVENT_KEY, 42527 MOUSEENTER: "mouseenter" + EVENT_KEY, 42528 MOUSELEAVE: "mouseleave" + EVENT_KEY 42529 }; 42530 var ClassName = { 42531 FADE: 'fade', 42532 SHOW: 'show' 42533 }; 42534 var Selector = { 42535 TOOLTIP: '.tooltip', 42536 TOOLTIP_INNER: '.tooltip-inner', 42537 ARROW: '.arrow' 42538 }; 42539 var Trigger = {
42540 HOVER: 'hover', 42541 FOCUS: 'focus', 42542 CLICK: 'click', 42543 MANUAL: 'manual' 42544 /** 42545 * ------------------------------------------------------------------------ 42546 * Class Definition 42547 * ------------------------------------------------------------------------ 42548 */ 42549 42550 }; 42551 42552 var Tooltip = 42553 /*#__PURE__*/ 42554 function () { 42555 function Tooltip(element, config) { 42556 /** 42557 * Check for Popper dependency 42558 * Popper - https://popper.js.org 42559 */ 42560 if (typeof Popper === 'undefined') { 42561 throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)'); 42562 } // private 42563 42564 42565 this._isEnabled = true; 42566 this._timeout = 0; 42567 this._hoverState = ''; 42568 this._activeTrigger = {}; 42569 this._popper = null; // Protected 42570 42571 this.element = element; 42572 this.config = this._getConfig(config); 42573 this.tip = null; 42574 42575 this._setListeners(); 42576 } // Getters 42577 42578 42579 var _proto = Tooltip.prototype; 42580 42581 // Public 42582 _proto.enable = function enable() { 42583 this._isEnabled = true; 42584 }; 42585 42586 _proto.disable = function disable() { 42587 this._isEnabled = false; 42588 }; 42589 42590 _proto.toggleEnabled = function toggleEnabled() { 42591 this._isEnabled = !this._isEnabled; 42592 }; 42593 42594 _proto.toggle = function toggle(event) { 42595 if (!this._isEnabled) { 42596 return; 42597 } 42598 42599 if (event) { 42600 var dataKey = this.constructor.DATA_KEY; 42601 var context = $$$1(event.currentTarget).data(dataKey); 42602 42603 if (!context) { 42604 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 42605 $$$1(event.currentTarget).data(dataKey, context); 42606 } 42607 42608 context._activeTrigger.click = !context._activeTrigger.click; 42609 42610 if (context._isWithActiveTrigger()) { 42611 context._enter(null, context); 42612 } else { 42613 context._leave(null, context); 42614 } 42615 } else { 42616 if ($$$1(this.getTipElement()).hasClass(ClassName.SHOW)) { 42617 this._leave(null, this); 42618 42619 return; 42620 } 42621 42622 this._enter(null, this); 42623 } 42624 }; 42625 42626 _proto.dispose = function dispose() { 42627 clearTimeout(this._timeout); 42628 $$$1.removeData(this.element, this.constructor.DATA_KEY); 42629 $$$1(this.element).off(this.constructor.EVENT_KEY); 42630 $$$1(this.element).closest('.modal').off('hide.bs.modal'); 42631 42632 if (this.tip) { 42633 $$$1(this.tip).remove(); 42634 } 42635 42636 this._isEnabled = null; 42637 this._timeout = null; 42638 this._hoverState = null; 42639 this._activeTrigger = null; 42640 42641 if (this._popper !== null) { 42642 this._popper.destroy(); 42643 } 42644 42645 this._popper = null; 42646 this.element = null; 42647 this.config = null; 42648 this.tip = null; 42649 }; 42650 42651 _proto.show = function show() { 42652 var _this = this; 42653 42654 if ($$$1(this.element).css('display') === 'none') { 42655 throw new Error('Please use show on visible elements'); 42656 } 42657 42658 var showEvent = $$$1.Event(this.constructor.Event.SHOW); 42659 42660 if (this.isWithContent() && this._isEnabled) { 42661 $$$1(this.element).trigger(showEvent); 42662 var isInTheDom = $$$1.contains(this.element.ownerDocument.documentElement, this.element); 42663 42664 if (showEvent.isDefaultPrevented() || !isInTheDom) { 42665 return; 42666 } 42667 42668 var tip = this.getTipElement(); 42669 var tipId = Util.getUID(this.constructor.NAME);
42670 tip.setAttribute('id', tipId); 42671 this.element.setAttribute('aria-describedby', tipId); 42672 this.setContent(); 42673 42674 if (this.config.animation) { 42675 $$$1(tip).addClass(ClassName.FADE); 42676 } 42677 42678 var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; 42679 42680 var attachment = this._getAttachment(placement); 42681 42682 this.addAttachmentClass(attachment); 42683 var container = this.config.container === false ? document.body : $$$1(document).find(this.config.container); 42684 $$$1(tip).data(this.constructor.DATA_KEY, this); 42685 42686 if (!$$$1.contains(this.element.ownerDocument.documentElement, this.tip)) { 42687 $$$1(tip).appendTo(container); 42688 } 42689 42690 $$$1(this.element).trigger(this.constructor.Event.INSERTED); 42691 this._popper = new Popper(this.element, tip, { 42692 placement: attachment, 42693 modifiers: { 42694 offset: { 42695 offset: this.config.offset 42696 }, 42697 flip: { 42698 behavior: this.config.fallbackPlacement 42699 }, 42700 arrow: { 42701 element: Selector.ARROW 42702 }, 42703 preventOverflow: { 42704 boundariesElement: this.config.boundary 42705 } 42706 }, 42707 onCreate: function onCreate(data) { 42708 if (data.originalPlacement !== data.placement) { 42709 _this._handlePopperPlacementChange(data); 42710 } 42711 }, 42712 onUpdate: function onUpdate(data) { 42713 _this._handlePopperPlacementChange(data); 42714 } 42715 }); 42716 $$$1(tip).addClass(ClassName.SHOW); // If this is a touch-enabled device we add extra 42717 // empty mouseover listeners to the body's immediate children; 42718 // only needed because of broken event delegation on iOS 42719 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 42720 42721 if ('ontouchstart' in document.documentElement) { 42722 $$$1(document.body).children().on('mouseover', null, $$$1.noop); 42723 } 42724 42725 var complete = function complete() { 42726 if (_this.config.animation) { 42727 _this._fixTransition(); 42728 } 42729 42730 var prevHoverState = _this._hoverState; 42731 _this._hoverState = null; 42732 $$$1(_this.element).trigger(_this.constructor.Event.SHOWN); 42733 42734 if (prevHoverState === HoverState.OUT) { 42735 _this._leave(null, _this); 42736 } 42737 }; 42738 42739 if ($$$1(this.tip).hasClass(ClassName.FADE)) { 42740 var transitionDuration = Util.getTransitionDurationFromElement(this.tip); 42741 $$$1(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 42742 } else { 42743 complete(); 42744 } 42745 } 42746 }; 42747 42748 _proto.hide = function hide(callback) { 42749 var _this2 = this; 42750 42751 var tip = this.getTipElement(); 42752 var hideEvent = $$$1.Event(this.constructor.Event.HIDE); 42753 42754 var complete = function complete() { 42755 if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) { 42756 tip.parentNode.removeChild(tip); 42757 } 42758 42759 _this2._cleanTipClass(); 42760 42761 _this2.element.removeAttribute('aria-describedby'); 42762 42763 $$$1(_this2.element).trigger(_this2.constructor.Event.HIDDEN); 42764 42765 if (_this2._popper !== null) { 42766 _this2._popper.destroy(); 42767 } 42768 42769 if (callback) { 42770 callback(); 42771 } 42772 }; 42773 42774 $$$1(this.element).trigger(hideEvent); 42775 42776 if (hideEvent.isDefaultPrevented()) { 42777 return; 42778 } 42779 42780 $$$1(tip).removeClass(ClassName.SHOW); // If this is a touch-enabled device we remove the extra 42781 // empty mouseover listeners we added for iOS support 42782 42783 if ('ontouchstart' in document.documentElement) { 42784 $$$1(document.body).children().off('mouseover', null, $$$1.noop); 42785 } 42786 42787 this._activeTrigger[Trigger.CLICK] = false;
42788 this._activeTrigger[Trigger.FOCUS] = false; 42789 this._activeTrigger[Trigger.HOVER] = false; 42790 42791 if ($$$1(this.tip).hasClass(ClassName.FADE)) { 42792 var transitionDuration = Util.getTransitionDurationFromElement(tip); 42793 $$$1(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 42794 } else { 42795 complete(); 42796 } 42797 42798 this._hoverState = ''; 42799 }; 42800 42801 _proto.update = function update() { 42802 if (this._popper !== null) { 42803 this._popper.scheduleUpdate(); 42804 } 42805 }; // Protected 42806 42807 42808 _proto.isWithContent = function isWithContent() { 42809 return Boolean(this.getTitle()); 42810 }; 42811 42812 _proto.addAttachmentClass = function addAttachmentClass(attachment) { 42813 $$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); 42814 }; 42815 42816 _proto.getTipElement = function getTipElement() { 42817 this.tip = this.tip || $$$1(this.config.template)[0]; 42818 return this.tip; 42819 }; 42820 42821 _proto.setContent = function setContent() { 42822 var tip = this.getTipElement(); 42823 this.setElementContent($$$1(tip.querySelectorAll(Selector.TOOLTIP_INNER)), this.getTitle()); 42824 $$$1(tip).removeClass(ClassName.FADE + " " + ClassName.SHOW); 42825 }; 42826 42827 _proto.setElementContent = function setElementContent($element, content) { 42828 var html = this.config.html; 42829 42830 if (typeof content === 'object' && (content.nodeType || content.jquery)) { 42831 // Content is a DOM node or a jQuery 42832 if (html) { 42833 if (!$$$1(content).parent().is($element)) { 42834 $element.empty().append(content); 42835 } 42836 } else { 42837 $element.text($$$1(content).text()); 42838 } 42839 } else { 42840 $element[html ? 'html' : 'text'](content); 42841 } 42842 }; 42843 42844 _proto.getTitle = function getTitle() { 42845 var title = this.element.getAttribute('data-original-title'); 42846 42847 if (!title) { 42848 title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; 42849 } 42850 42851 return title; 42852 }; // Private 42853 42854 42855 _proto._getAttachment = function _getAttachment(placement) { 42856 return AttachmentMap[placement.toUpperCase()]; 42857 }; 42858 42859 _proto._setListeners = function _setListeners() { 42860 var _this3 = this; 42861 42862 var triggers = this.config.trigger.split(' '); 42863 triggers.forEach(function (trigger) { 42864 if (trigger === 'click') { 42865 $$$1(_this3.element).on(_this3.constructor.Event.CLICK, _this3.config.selector, function (event) { 42866 return _this3.toggle(event); 42867 }); 42868 } else if (trigger !== Trigger.MANUAL) { 42869 var eventIn = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSEENTER : _this3.constructor.Event.FOCUSIN; 42870 var eventOut = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSELEAVE : _this3.constructor.Event.FOCUSOUT; 42871 $$$1(_this3.element).on(eventIn, _this3.config.selector, function (event) { 42872 return _this3._enter(event); 42873 }).on(eventOut, _this3.config.selector, function (event) { 42874 return _this3._leave(event); 42875 }); 42876 } 42877 42878 $$$1(_this3.element).closest('.modal').on('hide.bs.modal', function () { 42879 return _this3.hide(); 42880 }); 42881 }); 42882 42883 if (this.config.selector) { 42884 this.config = _objectSpread({}, this.config, { 42885 trigger: 'manual', 42886 selector: '' 42887 }); 42888 } else { 42889 this._fixTitle(); 42890 } 42891 }; 42892 42893 _proto._fixTitle = function _fixTitle() { 42894 var titleType = typeof this.element.getAttribute('data-original-title'); 42895 42896 if (this.element.getAttribute('title') || titleType !== 'string') { 42897 this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); 42898 this.element.setAttribute('title', ''); 42899 } 42900 }; 42901 42902 _proto._enter = function _enter(event, context) { 42903 var dataKey = this.constructor.DATA_KEY; 42904 context = context || $$$1(event.currentTarget).data(dataKey); 42905 42906 if (!context) { 42907 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 42908 $$$1(event.currentTarget).data(dataKey, context); 42909 } 42910 42911 if (event) { 42912 context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true; 42913 } 42914 42915 if ($$$1(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) { 42916 context._hoverState = HoverState.SHOW; 42917 return; 42918 } 42919 42920 clearTimeout(context._timeout); 42921 context._hoverState = HoverState.SHOW; 42922 42923 if (!context.config.delay || !context.config.delay.show) { 42924 context.show(); 42925 return; 42926 } 42927 42928 context._timeout = setTimeout(function () { 42929 if (context._hoverState === HoverState.SHOW) { 42930 context.show(); 42931 } 42932 }, context.config.delay.show); 42933 }; 42934 42935 _proto._leave = function _leave(event, context) { 42936 var dataKey = this.constructor.DATA_KEY; 42937 context = context || $$$1(event.currentTarget).data(dataKey); 42938 42939 if (!context) { 42940 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 42941 $$$1(event.currentTarget).data(dataKey, context); 42942 } 42943 42944 if (event) { 42945 context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;
42946 } 42947 42948 if (context._isWithActiveTrigger()) { 42949 return; 42950 } 42951 42952 clearTimeout(context._timeout); 42953 context._hoverState = HoverState.OUT; 42954 42955 if (!context.config.delay || !context.config.delay.hide) { 42956 context.hide(); 42957 return; 42958 } 42959 42960 context._timeout = setTimeout(function () { 42961 if (context._hoverState === HoverState.OUT) { 42962 context.hide(); 42963 } 42964 }, context.config.delay.hide); 42965 }; 42966 42967 _proto._isWithActiveTrigger = function _isWithActiveTrigger() { 42968 for (var trigger in this._activeTrigger) { 42969 if (this._activeTrigger[trigger]) { 42970 return true; 42971 } 42972 } 42973 42974 return false; 42975 }; 42976 42977 _proto._getConfig = function _getConfig(config) { 42978 config = _objectSpread({}, this.constructor.Default, $$$1(this.element).data(), typeof config === 'object' && config ? config : {}); 42979 42980 if (typeof config.delay === 'number') { 42981 config.delay = { 42982 show: config.delay, 42983 hide: config.delay 42984 }; 42985 } 42986 42987 if (typeof config.title === 'number') { 42988 config.title = config.title.toString(); 42989 } 42990 42991 if (typeof config.content === 'number') { 42992 config.content = config.content.toString(); 42993 } 42994 42995 Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); 42996 return config; 42997 }; 42998 42999 _proto._getDelegateConfig = function _getDelegateConfig() { 43000 var config = {}; 43001 43002 if (this.config) { 43003 for (var key in this.config) { 43004 if (this.constructor.Default[key] !== this.config[key]) { 43005 config[key] = this.config[key]; 43006 } 43007 } 43008 } 43009 43010 return config; 43011 }; 43012 43013 _proto._cleanTipClass = function _cleanTipClass() { 43014 var $tip = $$$1(this.getTipElement()); 43015 var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); 43016 43017 if (tabClass !== null && tabClass.length) { 43018 $tip.removeClass(tabClass.join('')); 43019 } 43020 }; 43021 43022 _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) { 43023 var popperInstance = popperData.instance; 43024 this.tip = popperInstance.popper; 43025 43026 this._cleanTipClass(); 43027 43028 this.addAttachmentClass(this._getAttachment(popperData.placement)); 43029 }; 43030 43031 _proto._fixTransition = function _fixTransition() { 43032 var tip = this.getTipElement(); 43033 var initConfigAnimation = this.config.animation; 43034 43035 if (tip.getAttribute('x-placement') !== null) { 43036 return; 43037 } 43038 43039 $$$1(tip).removeClass(ClassName.FADE); 43040 this.config.animation = false; 43041 this.hide(); 43042 this.show(); 43043 this.config.animation = initConfigAnimation; 43044 }; // Static 43045 43046 43047 Tooltip._jQueryInterface = function _jQueryInterface(config) { 43048 return this.each(function () { 43049 var data = $$$1(this).data(DATA_KEY); 43050 43051 var _config = typeof config === 'object' && config; 43052 43053 if (!data && /dispose|hide/.test(config)) { 43054 return; 43055 } 43056 43057 if (!data) { 43058 data = new Tooltip(this, _config); 43059 $$$1(this).data(DATA_KEY, data); 43060 } 43061 43062 if (typeof config === 'string') { 43063 if (typeof data[config] === 'undefined') { 43064 throw new TypeError("No method named \"" + config + "\""); 43065 } 43066 43067 data[config](); 43068 } 43069 }); 43070 }; 43071 43072 _createClass(Tooltip, null, [{ 43073 key: "VERSION", 43074 get: function get() { 43075 return VERSION; 43076 } 43077 }, { 43078 key: "Default", 43079 get: function get() { 43080 return Default; 43081 } 43082 }, { 43083 key: "NAME", 43084 get: function get() { 43085 return NAME; 43086 } 43087 }, { 43088 key: "DATA_KEY", 43089 get: function get() { 43090 return DATA_KEY; 43091 } 43092 }, { 43093 key: "Event", 43094 get: function get() { 43095 return Event; 43096 } 43097 }, { 43098 key: "EVENT_KEY", 43099 get: function get() { 43100 return EVENT_KEY; 43101 } 43102 }, { 43103 key: "DefaultType", 43104 get: function get() { 43105 return DefaultType; 43106 } 43107 }]); 43108 43109 return Tooltip; 43110 }(); 43111 /** 43112 * ------------------------------------------------------------------------ 43113 * jQuery 43114 * ------------------------------------------------------------------------ 43115 */ 43116 43117 43118 $$$1.fn[NAME] = Tooltip._jQueryInterface; 43119 $$$1.fn[NAME].Constructor = Tooltip; 43120 43121 $$$1.fn[NAME].noConflict = function () { 43122 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 43123 return Tooltip._jQueryInterface; 43124 }; 43125 43126 return Tooltip; 43127 }($, Popper); 43128 43129 return Tooltip; 43130 43131}))); 43132//# sourceMappingURL=tooltip.js.map 43133 43134;(function (global, factory) { 43135 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : 43136 typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : 43137 (global.Collapse = factory(global.jQuery,global.Util)); 43138}(this, (function ($,Util) { 'use strict'; 43139 43140 $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 43141 Util = Util && Util.hasOwnProperty('default') ? Util['default'] : Util; 43142 43143 function _defineProperties(target, props) { 43144 for (var i = 0; i < props.length; i++) { 43145 var descriptor = props[i]; 43146 descriptor.enumerable = descriptor.enumerable || false; 43147 descriptor.configurable = true; 43148 if ("value" in descriptor) descriptor.writable = true; 43149 Object.defineProperty(target, descriptor.key, descriptor); 43150 } 43151 } 43152 43153 function _createClass(Constructor, protoProps, staticProps) { 43154 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 43155 if (staticProps) _defineProperties(Constructor, staticProps); 43156 return Constructor; 43157 } 43158 43159 function _defineProperty(obj, key, value) { 43160 if (key in obj) { 43161 Object.defineProperty(obj, key, { 43162 value: value, 43163 enumerable: true, 43164 configurable: true, 43165 writable: true 43166 }); 43167 } else { 43168 obj[key] = value; 43169 } 43170 43171 return obj; 43172 } 43173 43174 function _objectSpread(target) { 43175 for (var i = 1; i < arguments.length; i++) { 43176 var source = arguments[i] != null ? arguments[i] : {}; 43177 var ownKeys = Object.keys(source); 43178 43179 if (typeof Object.getOwnPropertySymbols === 'function') { 43180 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { 43181 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 43182 })); 43183 } 43184 43185 ownKeys.forEach(function (key) { 43186 _defineProperty(target, key, source[key]); 43187 }); 43188 } 43189 43190 return target; 43191 } 43192 43193 /** 43194 * -------------------------------------------------------------------------- 43195 * Bootstrap (v4.1.3): collapse.js 43196 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 43197 * -------------------------------------------------------------------------- 43198 */ 43199 43200 var Collapse = function ($$$1) { 43201 /** 43202 * ------------------------------------------------------------------------ 43203 * Constants 43204 * ------------------------------------------------------------------------ 43205 */ 43206 var NAME = 'collapse'; 43207 var VERSION = '4.1.3'; 43208 var DATA_KEY = 'bs.collapse'; 43209 var EVENT_KEY = "." + DATA_KEY; 43210 var DATA_API_KEY = '.data-api'; 43211 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 43212 var Default = { 43213 toggle: true, 43214 parent: '' 43215 }; 43216 var DefaultType = { 43217 toggle: 'boolean', 43218 parent: '(string|element)' 43219 }; 43220 var Event = { 43221 SHOW: "show" + EVENT_KEY, 43222 SHOWN: "shown" + EVENT_KEY, 43223 HIDE: "hide" + EVENT_KEY, 43224 HIDDEN: "hidden" + EVENT_KEY, 43225 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY 43226 }; 43227 var ClassName = { 43228 SHOW: 'show', 43229 COLLAPSE: 'collapse', 43230 COLLAPSING: 'collapsing', 43231 COLLAPSED: 'collapsed' 43232 }; 43233 var Dimension = { 43234 WIDTH: 'width', 43235 HEIGHT: 'height' 43236 }; 43237 var Selector = { 43238 ACTIVES: '.show, .collapsing', 43239 DATA_TOGGLE: '[data-toggle="collapse"]' 43240 /** 43241 * ------------------------------------------------------------------------ 43242 * Class Definition 43243 * ------------------------------------------------------------------------ 43244 */ 43245 43246 }; 43247 43248 var Collapse = 43249 /*#__PURE__*/ 43250 function () { 43251 function Collapse(element, config) { 43252 this._isTransitioning = false;
43253 this._element = element; 43254 this._config = this._getConfig(config); 43255 this._triggerArray = $$$1.makeArray(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]"))); 43256 var toggleList = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE)); 43257 43258 for (var i = 0, len = toggleList.length; i < len; i++) { 43259 var elem = toggleList[i]; 43260 var selector = Util.getSelectorFromElement(elem); 43261 var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) { 43262 return foundElem === element; 43263 }); 43264 43265 if (selector !== null && filterElement.length > 0) { 43266 this._selector = selector; 43267 43268 this._triggerArray.push(elem); 43269 } 43270 } 43271 43272 this._parent = this._config.parent ? this._getParent() : null; 43273 43274 if (!this._config.parent) { 43275 this._addAriaAndCollapsedClass(this._element, this._triggerArray); 43276 } 43277 43278 if (this._config.toggle) { 43279 this.toggle(); 43280 } 43281 } // Getters 43282 43283 43284 var _proto = Collapse.prototype; 43285 43286 // Public 43287 _proto.toggle = function toggle() { 43288 if ($$$1(this._element).hasClass(ClassName.SHOW)) { 43289 this.hide(); 43290 } else { 43291 this.show(); 43292 } 43293 }; 43294 43295 _proto.show = function show() { 43296 var _this = this; 43297 43298 if (this._isTransitioning || $$$1(this._element).hasClass(ClassName.SHOW)) { 43299 return; 43300 } 43301 43302 var actives; 43303 var activesData; 43304 43305 if (this._parent) { 43306 actives = [].slice.call(this._parent.querySelectorAll(Selector.ACTIVES)).filter(function (elem) { 43307 return elem.getAttribute('data-parent') === _this._config.parent; 43308 }); 43309 43310 if (actives.length === 0) { 43311 actives = null; 43312 } 43313 } 43314 43315 if (actives) { 43316 activesData = $$$1(actives).not(this._selector).data(DATA_KEY); 43317 43318 if (activesData && activesData._isTransitioning) { 43319 return; 43320 } 43321 } 43322 43323 var startEvent = $$$1.Event(Event.SHOW); 43324 $$$1(this._element).trigger(startEvent); 43325 43326 if (startEvent.isDefaultPrevented()) { 43327 return; 43328 } 43329 43330 if (actives) { 43331 Collapse._jQueryInterface.call($$$1(actives).not(this._selector), 'hide'); 43332 43333 if (!activesData) { 43334 $$$1(actives).data(DATA_KEY, null); 43335 } 43336 } 43337 43338 var dimension = this._getDimension(); 43339 43340 $$$1(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING); 43341 this._element.style[dimension] = 0; 43342 43343 if (this._triggerArray.length) { 43344 $$$1(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true); 43345 } 43346 43347 this.setTransitioning(true); 43348 43349 var complete = function complete() { 43350 $$$1(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.SHOW); 43351 _this._element.style[dimension] = ''; 43352 43353 _this.setTransitioning(false); 43354 43355 $$$1(_this._element).trigger(Event.SHOWN); 43356 }; 43357 43358 var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); 43359 var scrollSize = "scroll" + capitalizedDimension; 43360 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 43361 $$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 43362 this._element.style[dimension] = this._element[scrollSize] + "px"; 43363 }; 43364 43365 _proto.hide = function hide() { 43366 var _this2 = this; 43367 43368 if (this._isTransitioning || !$$$1(this._element).hasClass(ClassName.SHOW)) { 43369 return; 43370 } 43371 43372 var startEvent = $$$1.Event(Event.HIDE); 43373 $$$1(this._element).trigger(startEvent); 43374 43375 if (startEvent.isDefaultPrevented()) { 43376 return; 43377 } 43378 43379 var dimension = this._getDimension(); 43380 43381 this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px"; 43382 Util.reflow(this._element); 43383 $$$1(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW); 43384 var triggerArrayLength = this._triggerArray.length; 43385 43386 if (triggerArrayLength > 0) { 43387 for (var i = 0; i < triggerArrayLength; i++) { 43388 var trigger = this._triggerArray[i]; 43389 var selector = Util.getSelectorFromElement(trigger); 43390 43391 if (selector !== null) { 43392 var $elem = $$$1([].slice.call(document.querySelectorAll(selector))); 43393 43394 if (!$elem.hasClass(ClassName.SHOW)) { 43395 $$$1(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false); 43396 } 43397 } 43398 } 43399 } 43400 43401 this.setTransitioning(true); 43402 43403 var complete = function complete() { 43404 _this2.setTransitioning(false); 43405 43406 $$$1(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN); 43407 }; 43408 43409 this._element.style[dimension] = ''; 43410 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 43411 $$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 43412 }; 43413 43414 _proto.setTransitioning = function setTransitioning(isTransitioning) { 43415 this._isTransitioning = isTransitioning; 43416 }; 43417 43418 _proto.dispose = function dispose() { 43419 $$$1.removeData(this._element, DATA_KEY); 43420 this._config = null; 43421 this._parent = null; 43422 this._element = null; 43423 this._triggerArray = null; 43424 this._isTransitioning = null; 43425 }; // Private 43426 43427 43428 _proto._getConfig = function _getConfig(config) { 43429 config = _objectSpread({}, Default, config); 43430 config.toggle = Boolean(config.toggle); // Coerce string values 43431 43432 Util.typeCheckConfig(NAME, config, DefaultType); 43433 return config; 43434 }; 43435 43436 _proto._getDimension = function _getDimension() { 43437 var hasWidth = $$$1(this._element).hasClass(Dimension.WIDTH); 43438 return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; 43439 }; 43440 43441 _proto._getParent = function _getParent() { 43442 var _this3 = this; 43443 43444 var parent = null; 43445 43446 if (Util.isElement(this._config.parent)) { 43447 parent = this._config.parent; // It's a jQuery object 43448 43449 if (typeof this._config.parent.jquery !== 'undefined') { 43450 parent = this._config.parent[0]; 43451 } 43452 } else { 43453 parent = document.querySelector(this._config.parent); 43454 } 43455 43456 var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]"; 43457 var children = [].slice.call(parent.querySelectorAll(selector)); 43458 $$$1(children).each(function (i, element) { 43459 _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); 43460 }); 43461 return parent; 43462 }; 43463 43464 _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { 43465 if (element) { 43466 var isOpen = $$$1(element).hasClass(ClassName.SHOW); 43467 43468 if (triggerArray.length) { 43469 $$$1(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); 43470 } 43471 } 43472 }; // Static 43473 43474 43475 Collapse._getTargetFromElement = function _getTargetFromElement(element) { 43476 var selector = Util.getSelectorFromElement(element); 43477 return selector ? document.querySelector(selector) : null; 43478 }; 43479 43480 Collapse._jQueryInterface = function _jQueryInterface(config) { 43481 return this.each(function () { 43482 var $this = $$$1(this); 43483 var data = $this.data(DATA_KEY); 43484 43485 var _config = _objectSpread({}, Default, $this.data(), typeof config === 'object' && config ? config : {}); 43486 43487 if (!data && _config.toggle && /show|hide/.test(config)) { 43488 _config.toggle = false;
43489 } 43490 43491 if (!data) { 43492 data = new Collapse(this, _config); 43493 $this.data(DATA_KEY, data); 43494 } 43495 43496 if (typeof config === 'string') { 43497 if (typeof data[config] === 'undefined') { 43498 throw new TypeError("No method named \"" + config + "\""); 43499 } 43500 43501 data[config](); 43502 } 43503 }); 43504 }; 43505 43506 _createClass(Collapse, null, [{ 43507 key: "VERSION", 43508 get: function get() { 43509 return VERSION; 43510 } 43511 }, { 43512 key: "Default", 43513 get: function get() { 43514 return Default; 43515 } 43516 }]); 43517 43518 return Collapse; 43519 }(); 43520 /** 43521 * ------------------------------------------------------------------------ 43522 * Data Api implementation 43523 * ------------------------------------------------------------------------ 43524 */ 43525 43526 43527 $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { 43528 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element 43529 if (event.currentTarget.tagName === 'A') { 43530 event.preventDefault(); 43531 } 43532 43533 var $trigger = $$$1(this); 43534 var selector = Util.getSelectorFromElement(this); 43535 var selectors = [].slice.call(document.querySelectorAll(selector)); 43536 $$$1(selectors).each(function () { 43537 var $target = $$$1(this); 43538 var data = $target.data(DATA_KEY); 43539 var config = data ? 'toggle' : $trigger.data(); 43540 43541 Collapse._jQueryInterface.call($target, config); 43542 }); 43543 }); 43544 /** 43545 * ------------------------------------------------------------------------ 43546 * jQuery 43547 * ------------------------------------------------------------------------ 43548 */ 43549 43550 $$$1.fn[NAME] = Collapse._jQueryInterface; 43551 $$$1.fn[NAME].Constructor = Collapse; 43552 43553 $$$1.fn[NAME].noConflict = function () { 43554 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 43555 return Collapse._jQueryInterface; 43556 }; 43557 43558 return Collapse; 43559 }($); 43560 43561 return Collapse; 43562 43563}))); 43564//# sourceMappingURL=collapse.js.map 43565 43566;(function (global, factory) { 43567 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./tooltip.js')) : 43568 typeof define === 'function' && define.amd ? define(['jquery', './tooltip.js'], factory) : 43569 (global.Popover = factory(global.jQuery,global.Tooltip)); 43570}(this, (function ($,Tooltip) { 'use strict'; 43571 43572 $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 43573 Tooltip = Tooltip && Tooltip.hasOwnProperty('default') ? Tooltip['default'] : Tooltip; 43574 43575 function _defineProperties(target, props) { 43576 for (var i = 0; i < props.length; i++) { 43577 var descriptor = props[i]; 43578 descriptor.enumerable = descriptor.enumerable || false; 43579 descriptor.configurable = true; 43580 if ("value" in descriptor) descriptor.writable = true; 43581 Object.defineProperty(target, descriptor.key, descriptor); 43582 } 43583 } 43584 43585 function _createClass(Constructor, protoProps, staticProps) { 43586 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 43587 if (staticProps) _defineProperties(Constructor, staticProps); 43588 return Constructor; 43589 } 43590 43591 function _defineProperty(obj, key, value) { 43592 if (key in obj) { 43593 Object.defineProperty(obj, key, { 43594 value: value, 43595 enumerable: true, 43596 configurable: true, 43597 writable: true 43598 }); 43599 } else { 43600 obj[key] = value; 43601 } 43602 43603 return obj; 43604 } 43605 43606 function _objectSpread(target) { 43607 for (var i = 1; i < arguments.length; i++) { 43608 var source = arguments[i] != null ? arguments[i] : {}; 43609 var ownKeys = Object.keys(source); 43610 43611 if (typeof Object.getOwnPropertySymbols === 'function') { 43612 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { 43613 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 43614 })); 43615 } 43616 43617 ownKeys.forEach(function (key) { 43618 _defineProperty(target, key, source[key]); 43619 }); 43620 } 43621 43622 return target; 43623 } 43624 43625 function _inheritsLoose(subClass, superClass) { 43626 subClass.prototype = Object.create(superClass.prototype); 43627 subClass.prototype.constructor = subClass; 43628 subClass.__proto__ = superClass; 43629 } 43630 43631 /** 43632 * -------------------------------------------------------------------------- 43633 * Bootstrap (v4.1.3): popover.js 43634 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 43635 * -------------------------------------------------------------------------- 43636 */ 43637 43638 var Popover = function ($$$1) { 43639 /** 43640 * ------------------------------------------------------------------------ 43641 * Constants 43642 * ------------------------------------------------------------------------ 43643 */ 43644 var NAME = 'popover'; 43645 var VERSION = '4.1.3'; 43646 var DATA_KEY = 'bs.popover'; 43647 var EVENT_KEY = "." + DATA_KEY; 43648 var JQUERY_NO_CONFLICT = $$$1.fn[NAME];
43649 var CLASS_PREFIX = 'bs-popover'; 43650 var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); 43651 43652 var Default = _objectSpread({}, Tooltip.Default, { 43653 placement: 'right', 43654 trigger: 'click', 43655 content: '', 43656 template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>' 43657 }); 43658 43659 var DefaultType = _objectSpread({}, Tooltip.DefaultType, { 43660 content: '(string|element|function)' 43661 }); 43662 43663 var ClassName = { 43664 FADE: 'fade', 43665 SHOW: 'show' 43666 }; 43667 var Selector = { 43668 TITLE: '.popover-header', 43669 CONTENT: '.popover-body' 43670 }; 43671 var Event = { 43672 HIDE: "hide" + EVENT_KEY, 43673 HIDDEN: "hidden" + EVENT_KEY, 43674 SHOW: "show" + EVENT_KEY, 43675 SHOWN: "shown" + EVENT_KEY, 43676 INSERTED: "inserted" + EVENT_KEY, 43677 CLICK: "click" + EVENT_KEY, 43678 FOCUSIN: "focusin" + EVENT_KEY, 43679 FOCUSOUT: "focusout" + EVENT_KEY, 43680 MOUSEENTER: "mouseenter" + EVENT_KEY, 43681 MOUSELEAVE: "mouseleave" + EVENT_KEY 43682 /** 43683 * ------------------------------------------------------------------------ 43684 * Class Definition 43685 * ------------------------------------------------------------------------ 43686 */ 43687 43688 }; 43689 43690 var Popover = 43691 /*#__PURE__*/ 43692 function (_Tooltip) { 43693 _inheritsLoose(Popover, _Tooltip); 43694 43695 function Popover() { 43696 return _Tooltip.apply(this, arguments) || this; 43697 } 43698 43699 var _proto = Popover.prototype; 43700 43701 // Overrides 43702 _proto.isWithContent = function isWithContent() { 43703 return this.getTitle() || this._getContent(); 43704 }; 43705 43706 _proto.addAttachmentClass = function addAttachmentClass(attachment) { 43707 $$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); 43708 }; 43709 43710 _proto.getTipElement = function getTipElement() { 43711 this.tip = this.tip || $$$1(this.config.template)[0]; 43712 return this.tip; 43713 }; 43714 43715 _proto.setContent = function setContent() { 43716 var $tip = $$$1(this.getTipElement()); // We use append for html objects to maintain js events 43717 43718 this.setElementContent($tip.find(Selector.TITLE), this.getTitle()); 43719 43720 var content = this._getContent(); 43721 43722 if (typeof content === 'function') { 43723 content = content.call(this.element); 43724 } 43725 43726 this.setElementContent($tip.find(Selector.CONTENT), content); 43727 $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW); 43728 }; // Private 43729 43730 43731 _proto._getContent = function _getContent() { 43732 return this.element.getAttribute('data-content') || this.config.content; 43733 }; 43734 43735 _proto._cleanTipClass = function _cleanTipClass() { 43736 var $tip = $$$1(this.getTipElement()); 43737 var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); 43738 43739 if (tabClass !== null && tabClass.length > 0) { 43740 $tip.removeClass(tabClass.join('')); 43741 } 43742 }; // Static 43743 43744 43745 Popover._jQueryInterface = function _jQueryInterface(config) { 43746 return this.each(function () { 43747 var data = $$$1(this).data(DATA_KEY); 43748 43749 var _config = typeof config === 'object' ? config : null; 43750 43751 if (!data && /destroy|hide/.test(config)) { 43752 return; 43753 } 43754 43755 if (!data) { 43756 data = new Popover(this, _config); 43757 $$$1(this).data(DATA_KEY, data); 43758 } 43759 43760 if (typeof config === 'string') { 43761 if (typeof data[config] === 'undefined') { 43762 throw new TypeError("No method named \"" + config + "\""); 43763 } 43764 43765 data[config](); 43766 } 43767 }); 43768 }; 43769 43770 _createClass(Popover, null, [{ 43771 key: "VERSION", 43772 // Getters 43773 get: function get() { 43774 return VERSION; 43775 } 43776 }, { 43777 key: "Default", 43778 get: function get() { 43779 return Default; 43780 } 43781 }, { 43782 key: "NAME", 43783 get: function get() { 43784 return NAME; 43785 } 43786 }, { 43787 key: "DATA_KEY", 43788 get: function get() { 43789 return DATA_KEY; 43790 } 43791 }, { 43792 key: "Event", 43793 get: function get() { 43794 return Event; 43795 } 43796 }, { 43797 key: "EVENT_KEY", 43798 get: function get() { 43799 return EVENT_KEY; 43800 } 43801 }, { 43802 key: "DefaultType", 43803 get: function get() { 43804 return DefaultType; 43805 } 43806 }]); 43807 43808 return Popover; 43809 }(Tooltip); 43810 /** 43811 * ------------------------------------------------------------------------ 43812 * jQuery 43813 * ------------------------------------------------------------------------ 43814 */ 43815 43816 43817 $$$1.fn[NAME] = Popover._jQueryInterface; 43818 $$$1.fn[NAME].Constructor = Popover; 43819 43820 $$$1.fn[NAME].noConflict = function () { 43821 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 43822 return Popover._jQueryInterface; 43823 }; 43824 43825 return Popover; 43826 }($); 43827 43828 return Popover; 43829 43830}))); 43831//# sourceMappingURL=popover.js.map 43832 43833;/** 43834 * Super simple wysiwyg editor v0.8.10 43835 * https://summernote.org 43836 * 43837 * Copyright 2013- Alan Hong. and other contributors 43838 * summernote may be freely distributed under the MIT license. 43839 * 43840 * Date: 2018-02-20T00:34Z 43841 */ 43842(function (global, factory) { 43843 typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) : 43844 typeof define === 'function' && define.amd ? define(['jquery'], factory) : 43845 (factory(global.jQuery)); 43846}(this, (function ($$1) { 'use strict'; 43847 43848$$1 = $$1 && $$1.hasOwnProperty('default') ? $$1['default'] : $$1; 43849 43850var Renderer = /** @class */ (function () {
43851 function Renderer(markup, children, options, callback) { 43852 this.markup = markup; 43853 this.children = children; 43854 this.options = options; 43855 this.callback = callback; 43856 } 43857 Renderer.prototype.render = function ($parent) { 43858 var $node = $$1(this.markup); 43859 if (this.options && this.options.contents) { 43860 $node.html(this.options.contents); 43861 } 43862 if (this.options && this.options.className) { 43863 $node.addClass(this.options.className); 43864 } 43865 if (this.options && this.options.data) { 43866 $$1.each(this.options.data, function (k, v) { 43867 $node.attr('data-' + k, v); 43868 }); 43869 } 43870 if (this.options && this.options.click) { 43871 $node.on('click', this.options.click); 43872 } 43873 if (this.children) { 43874 var $container_1 = $node.find('.note-children-container'); 43875 this.children.forEach(function (child) { 43876 child.render($container_1.length ? $container_1 : $node); 43877 }); 43878 } 43879 if (this.callback) { 43880 this.callback($node, this.options); 43881 } 43882 if (this.options && this.options.callback) { 43883 this.options.callback($node); 43884 } 43885 if ($parent) { 43886 $parent.append($node); 43887 } 43888 return $node; 43889 }; 43890 return Renderer; 43891}()); 43892var renderer = { 43893 create: function (markup, callback) { 43894 return function () { 43895 var options = typeof arguments[1] === 'object' ? arguments[1] : arguments[0]; 43896 var children = $$1.isArray(arguments[0]) ? arguments[0] : []; 43897 if (options && options.children) { 43898 children = options.children; 43899 } 43900 return new Renderer(markup, children, options, callback); 43901 }; 43902 } 43903}; 43904 43905var editor = renderer.create('<div class="note-editor note-frame panel"/>'); 43906var toolbar = renderer.create('<div class="note-toolbar-wrapper panel-default"><div class="note-toolbar panel-heading" role="toolbar"></div></div>'); 43907var editingArea = renderer.create('<div class="note-editing-area"/>'); 43908var codable = renderer.create('<textarea class="note-codable" role="textbox" aria-multiline="true"/>'); 43909var editable = renderer.create('<div class="note-editable" contentEditable="true" role="textbox" aria-multiline="true"/>'); 43910var statusbar = renderer.create([ 43911 '<output class="note-status-output" aria-live="polite"/>', 43912 '<div class="note-statusbar" role="status">', 43913 ' <div class="note-resizebar" role="seperator" aria-orientation="horizontal" aria-label="Resize">', 43914 ' <div class="note-icon-bar"/>', 43915 ' <div class="note-icon-bar"/>', 43916 ' <div class="note-icon-bar"/>', 43917 ' </div>', 43918 '</div>' 43919].join('')); 43920var airEditor = renderer.create('<div class="note-editor"/>'); 43921var airEditable = renderer.create([ 43922 ' <output class="note-status-output" aria-live="polite"/>', 43923 '<div class="note-editable" contentEditable="true" role="textbox" aria-multiline="true"/>' 43924].join('')); 43925var buttonGroup = renderer.create('<div class="note-btn-group btn-group">'); 43926var dropdown = renderer.create('<ul class="dropdown-menu" role="list">', function ($node, options) { 43927 var markup = $$1.isArray(options.items) ? options.items.map(function (item) { 43928 var value = (typeof item === 'string') ? item : (item.value || ''); 43929 var content = options.template ? options.template(item) : item; 43930 var option = (typeof item === 'object') ? item.option : undefined; 43931 var dataValue = 'data-value="' + value + '"'; 43932 var dataOption = (option !== undefined) ? ' data-option="' + option + '"' : ''; 43933 return '<li role="listitem" aria-label="' + item + '"><a href="#" ' + (dataValue + dataOption) + '>' + content + '</a></li>'; 43934 }).join('') : options.items; 43935 $node.html(markup).attr({ 'aria-label': options.title }); 43936}); 43937var dropdownButtonContents = function (contents, options) { 43938 return contents + ' ' + icon(options.icons.caret, 'span'); 43939}; 43940var dropdownCheck = renderer.create('<ul class="dropdown-menu note-check" role="list">', function ($node, options) { 43941 var markup = $$1.isArray(options.items) ? options.items.map(function (item) { 43942 var value = (typeof item === 'string') ? item : (item.value || ''); 43943 var content = options.template ? options.template(item) : item; 43944 return '<li role="listitem" aria-label="' + item + '"><a href="#" data-value="' + value + '">' + icon(options.checkClassName) + ' ' + content + '</a></li>'; 43945 }).join('') : options.items; 43946 $node.html(markup).attr({ 'aria-label': options.title }); 43947}); 43948var palette = renderer.create('<div class="note-color-palette"/>', function ($node, options) { 43949 var contents = []; 43950 for (var row = 0, rowSize = options.colors.length; row < rowSize; row++) { 43951 var eventName = options.eventName; 43952 var colors = options.colors[row]; 43953 var colorsName = options.colorsName[row]; 43954 var buttons = []; 43955 for (var col = 0, colSize = colors.length; col < colSize; col++) { 43956 var color = colors[col]; 43957 var colorName = colorsName[col]; 43958 buttons.push([ 43959 '<button type="button" class="note-color-btn"', 43960 'style="background-color:', color, '" ', 43961 'data-event="', eventName, '" ', 43962 'data-value="', color, '" ', 43963 'title="', colorName, '" ', 43964 'aria-label="', colorName, '" ', 43965 'data-toggle="button" tabindex="-1"></button>' 43966 ].join('')); 43967 } 43968 contents.push('<div class="note-color-row">' + buttons.join('') + '</div>'); 43969 } 43970 $node.html(contents.join('')); 43971 if (options.tooltip) { 43972 $node.find('.note-color-btn').tooltip({ 43973 container: options.container, 43974 trigger: 'hover', 43975 placement: 'bottom' 43976 }); 43977 } 43978}); 43979var dialog = renderer.create('<div class="modal" aria-hidden="false" tabindex="-1" role="dialog"/>', function ($node, options) { 43980 if (options.fade) { 43981 $node.addClass('fade'); 43982 } 43983 $node.attr({ 43984 'aria-label': options.title 43985 }); 43986 $node.html([ 43987 '<div class="modal-dialog">', 43988 ' <div class="modal-content">', 43989 (options.title 43990 ? ' <div class="modal-header">' + 43991 ' <button type="button" class="close" data-dismiss="modal" aria-label="Close" aria-hidden="true">×</button>' + 43992 ' <h4 class="modal-title">' + options.title + '</h4>' + 43993 ' </div>' : ''), 43994 ' <div class="modal-body">' + options.body + '</div>', 43995 (options.footer 43996 ? ' <div class="modal-footer">' + options.footer + '</div>' : ''), 43997 ' </div>', 43998 '</div>' 43999 ].join('')); 44000}); 44001var popover = renderer.create([ 44002 '<div class="note-popover popover in">', 44003 ' <div class="arrow"/>', 44004 ' <div class="popover-content note-children-container"/>', 44005 '</div>' 44006].join(''), function ($node, options) { 44007 var direction = typeof options.direction !== 'undefined' ? options.direction : 'bottom'; 44008 $node.addClass(direction); 44009 if (options.hideArrow) { 44010 $node.find('.arrow').hide(); 44011 } 44012}); 44013var checkbox = renderer.create('<div class="checkbox"></div>', function ($node, options) { 44014 $node.html([ 44015 ' <label' + (options.id ? ' for="' + options.id + '"' : '') + '>', 44016 ' <input role="checkbox" type="checkbox"' + (options.id ? ' id="' + options.id + '"' : ''), 44017 (options.checked ? ' checked' : ''), 44018 ' aria-checked="' + (options.checked ? 'true' : 'false') + '"/>', 44019 (options.text ? options.text : ''), 44020 '</label>' 44021 ].join('')); 44022}); 44023var icon = function (iconClassName, tagName) { 44024 tagName = tagName || 'i'; 44025 return '<' + tagName + ' class="' + iconClassName + '"/>'; 44026}; 44027var ui = { 44028 editor: editor, 44029 toolbar: toolbar, 44030 editingArea: editingArea, 44031 codable: codable, 44032 editable: editable, 44033 statusbar: statusbar, 44034 airEditor: airEditor, 44035 airEditable: airEditable, 44036 buttonGroup: buttonGroup, 44037 dropdown: dropdown, 44038 dropdownButtonContents: dropdownButtonContents, 44039 dropdownCheck: dropdownCheck, 44040 palette: palette, 44041 dialog: dialog, 44042 popover: popover, 44043 checkbox: checkbox, 44044 icon: icon, 44045 options: {}, 44046 button: function ($node, options) { 44047 return renderer.create('<button type="button" class="note-btn btn btn-default btn-sm" role="button" tabindex="-1">', function ($node, options) { 44048 if (options && options.tooltip) { 44049 $node.attr({ 44050 title: options.tooltip, 44051 'aria-label': options.tooltip 44052 }).tooltip({ 44053 container: options.container, 44054 trigger: 'hover', 44055 placement: 'bottom' 44056 }); 44057 } 44058 })($node, options); 44059 }, 44060 toggleBtn: function ($btn, isEnable) { 44061 $btn.toggleClass('disabled', !isEnable); 44062 $btn.attr('disabled', !isEnable); 44063 }, 44064 toggleBtnActive: function ($btn, isActive) { 44065 $btn.toggleClass('active', isActive); 44066 }, 44067 onDialogShown: function ($dialog, handler) { 44068 $dialog.one('shown.bs.modal', handler); 44069 }, 44070 onDialogHidden: function ($dialog, handler) { 44071 $dialog.one('hidden.bs.modal', handler); 44072 }, 44073 showDialog: function ($dialog) { 44074 $dialog.modal('show'); 44075 }, 44076 hideDialog: function ($dialog) { 44077 $dialog.modal('hide'); 44078 }, 44079 createLayout: function ($note, options) { 44080 var $editor = (options.airMode ? ui.airEditor([ 44081 ui.editingArea([ 44082 ui.airEditable() 44083 ]) 44084 ]) : ui.editor([ 44085 ui.toolbar(), 44086 ui.editingArea([ 44087 ui.codable(), 44088 ui.editable() 44089 ]), 44090 ui.statusbar() 44091 ])).render(); 44092 $editor.insertAfter($note); 44093 return { 44094 note: $note, 44095 editor: $editor, 44096 toolbar: $editor.find('.note-toolbar'), 44097 editingArea: $editor.find('.note-editing-area'), 44098 editable: $editor.find('.note-editable'), 44099 codable: $editor.find('.note-codable'), 44100 statusbar: $editor.find('.note-statusbar') 44101 }; 44102 }, 44103 removeLayout: function ($note, layoutInfo) { 44104 $note.html(layoutInfo.editable.html()); 44105 layoutInfo.editor.remove(); 44106 $note.show(); 44107 } 44108}; 44109 44110/** 44111 * @class core.func 44112 * 44113 * func utils (for high-order func's arg) 44114 * 44115 * @singleton 44116 * @alternateClassName func 44117 */ 44118function eq(itemA) { 44119 return function (itemB) { 44120 return itemA === itemB; 44121 }; 44122} 44123function eq2(itemA, itemB) { 44124 return itemA === itemB; 44125} 44126function peq2(propName) { 44127 return function (itemA, itemB) { 44128 return itemA[propName] === itemB[propName]; 44129 }; 44130} 44131function ok() { 44132 return true; 44133} 44134function fail() { 44135 return false;
44136} 44137function not(f) { 44138 return function () { 44139 return !f.apply(f, arguments); 44140 }; 44141} 44142function and(fA, fB) { 44143 return function (item) { 44144 return fA(item) && fB(item); 44145 }; 44146} 44147function self(a) { 44148 return a; 44149} 44150function invoke(obj, method) { 44151 return function () { 44152 return obj[method].apply(obj, arguments); 44153 }; 44154} 44155var idCounter = 0; 44156/** 44157 * generate a globally-unique id 44158 * 44159 * @param {String} [prefix] 44160 */ 44161function uniqueId(prefix) { 44162 var id = ++idCounter + ''; 44163 return prefix ? prefix + id : id; 44164} 44165/** 44166 * returns bnd (bounds) from rect 44167 * 44168 * - IE Compatibility Issue: http://goo.gl/sRLOAo 44169 * - Scroll Issue: http://goo.gl/sNjUc 44170 * 44171 * @param {Rect} rect 44172 * @return {Object} bounds 44173 * @return {Number} bounds.top 44174 * @return {Number} bounds.left 44175 * @return {Number} bounds.width 44176 * @return {Number} bounds.height 44177 */ 44178function rect2bnd(rect) { 44179 var $document = $(document); 44180 return { 44181 top: rect.top + $document.scrollTop(), 44182 left: rect.left + $document.scrollLeft(), 44183 width: rect.right - rect.left, 44184 height: rect.bottom - rect.top 44185 }; 44186} 44187/** 44188 * returns a copy of the object where the keys have become the values and the values the keys. 44189 * @param {Object} obj 44190 * @return {Object} 44191 */ 44192function invertObject(obj) { 44193 var inverted = {}; 44194 for (var key in obj) { 44195 if (obj.hasOwnProperty(key)) { 44196 inverted[obj[key]] = key; 44197 } 44198 } 44199 return inverted; 44200} 44201/** 44202 * @param {String} namespace 44203 * @param {String} [prefix] 44204 * @return {String} 44205 */ 44206function namespaceToCamel(namespace, prefix) { 44207 prefix = prefix || ''; 44208 return prefix + namespace.split('.').map(function (name) { 44209 return name.substring(0, 1).toUpperCase() + name.substring(1); 44210 }).join(''); 44211} 44212/** 44213 * Returns a function, that, as long as it continues to be invoked, will not 44214 * be triggered. The function will be called after it stops being called for 44215 * N milliseconds. If `immediate` is passed, trigger the function on the 44216 * leading edge, instead of the trailing. 44217 * @param {Function} func 44218 * @param {Number} wait 44219 * @param {Boolean} immediate 44220 * @return {Function} 44221 */ 44222function debounce(func, wait, immediate) { 44223 var _this = this; 44224 var timeout; 44225 return function () { 44226 var context = _this; 44227 var args = arguments; 44228 var later = function () { 44229 timeout = null; 44230 if (!immediate) { 44231 func.apply(context, args); 44232 } 44233 }; 44234 var callNow = immediate && !timeout; 44235 clearTimeout(timeout); 44236 timeout = setTimeout(later, wait); 44237 if (callNow) { 44238 func.apply(context, args); 44239 } 44240 }; 44241} 44242var func = { 44243 eq: eq, 44244 eq2: eq2, 44245 peq2: peq2, 44246 ok: ok, 44247 fail: fail, 44248 self: self, 44249 not: not, 44250 and: and, 44251 invoke: invoke, 44252 uniqueId: uniqueId, 44253 rect2bnd: rect2bnd, 44254 invertObject: invertObject, 44255 namespaceToCamel: namespaceToCamel, 44256 debounce: debounce 44257}; 44258 44259/** 44260 * returns the first item of an array. 44261 * 44262 * @param {Array} array 44263 */ 44264function head(array) { 44265 return array[0]; 44266} 44267/** 44268 * returns the last item of an array. 44269 * 44270 * @param {Array} array 44271 */ 44272function last(array) { 44273 return array[array.length - 1]; 44274} 44275/** 44276 * returns everything but the last entry of the array. 44277 * 44278 * @param {Array} array 44279 */ 44280function initial(array) { 44281 return array.slice(0, array.length - 1); 44282} 44283/** 44284 * returns the rest of the items in an array. 44285 * 44286 * @param {Array} array 44287 */ 44288function tail(array) { 44289 return array.slice(1); 44290} 44291/** 44292 * returns item of array 44293 */ 44294function find(array, pred) { 44295 for (var idx = 0, len = array.length; idx < len; idx++) { 44296 var item = array[idx]; 44297 if (pred(item)) { 44298 return item; 44299 } 44300 } 44301} 44302/** 44303 * returns true if all of the values in the array pass the predicate truth test. 44304 */ 44305function all(array, pred) { 44306 for (var idx = 0, len = array.length; idx < len; idx++) { 44307 if (!pred(array[idx])) { 44308 return false; 44309 } 44310 } 44311 return true; 44312} 44313/** 44314 * returns index of item 44315 */ 44316function indexOf(array, item) { 44317 return $$1.inArray(item, array); 44318} 44319/** 44320 * returns true if the value is present in the list. 44321 */ 44322function contains(array, item) { 44323 return indexOf(array, item) !== -1; 44324} 44325/** 44326 * get sum from a list 44327 * 44328 * @param {Array} array - array 44329 * @param {Function} fn - iterator 44330 */ 44331function sum(array, fn) { 44332 fn = fn || func.self; 44333 return array.reduce(function (memo, v) { 44334 return memo + fn(v); 44335 }, 0); 44336} 44337/** 44338 * returns a copy of the collection with array type. 44339 * @param {Collection} collection - collection eg) node.childNodes, ... 44340 */ 44341function from(collection) { 44342 var result = []; 44343 var length = collection.length; 44344 var idx = -1; 44345 while (++idx < length) { 44346 result[idx] = collection[idx]; 44347 } 44348 return result; 44349} 44350/** 44351 * returns whether list is empty or not 44352 */ 44353function isEmpty$1(array) { 44354 return !array || !array.length; 44355} 44356/** 44357 * cluster elements by predicate function. 44358 * 44359 * @param {Array} array - array 44360 * @param {Function} fn - predicate function for cluster rule 44361 * @param {Array[]} 44362 */ 44363function clusterBy(array, fn) { 44364 if (!array.length) { 44365 return []; 44366 } 44367 var aTail = tail(array); 44368 return aTail.reduce(function (memo, v) { 44369 var aLast = last(memo); 44370 if (fn(last(aLast), v)) { 44371 aLast[aLast.length] = v; 44372 } 44373 else { 44374 memo[memo.length] = [v]; 44375 } 44376 return memo; 44377 }, [[head(array)]]); 44378} 44379/** 44380 * returns a copy of the array with all false values removed 44381 * 44382 * @param {Array} array - array 44383 * @param {Function} fn - predicate function for cluster rule 44384 */ 44385function compact(array) { 44386 var aResult = []; 44387 for (var idx = 0, len = array.length; idx < len; idx++) { 44388 if (array[idx]) { 44389 aResult.push(array[idx]); 44390 } 44391 } 44392 return aResult; 44393} 44394/** 44395 * produces a duplicate-free version of the array 44396 * 44397 * @param {Array} array 44398 */ 44399function unique(array) { 44400 var results = []; 44401 for (var idx = 0, len = array.length; idx < len; idx++) { 44402 if (!contains(results, array[idx])) { 44403 results.push(array[idx]); 44404 } 44405 } 44406 return results; 44407} 44408/** 44409 * returns next item. 44410 * @param {Array} array 44411 */ 44412function next(array, item) { 44413 var idx = indexOf(array, item); 44414 if (idx === -1) { 44415 return null; 44416 } 44417 return array[idx + 1]; 44418} 44419/** 44420 * returns prev item. 44421 * @param {Array} array 44422 */ 44423function prev(array, item) { 44424 var idx = indexOf(array, item); 44425 if (idx === -1) { 44426 return null; 44427 } 44428 return array[idx - 1]; 44429} 44430/** 44431 * @class core.list 44432 * 44433 * list utils 44434 * 44435 * @singleton 44436 * @alternateClassName list 44437 */ 44438var lists = { 44439 head: head, 44440 last: last, 44441 initial: initial, 44442 tail: tail, 44443 prev: prev, 44444 next: next, 44445 find: find, 44446 contains: contains, 44447 all: all, 44448 sum: sum, 44449 from: from, 44450 isEmpty: isEmpty$1, 44451 clusterBy: clusterBy, 44452 compact: compact, 44453 unique: unique 44454}; 44455 44456var isSupportAmd = typeof define === 'function' && define.amd; // eslint-disable-line 44457/** 44458 * returns whether font is installed or not. 44459 * 44460 * @param {String} fontName 44461 * @return {Boolean} 44462 */ 44463function isFontInstalled(fontName) { 44464 var testFontName = fontName === 'Comic Sans MS' ? 'Courier New' : 'Comic Sans MS'; 44465 var $tester = $$1('<div>').css({ 44466 position: 'absolute', 44467 left: '-9999px', 44468 top: '-9999px', 44469 fontSize: '200px' 44470 }).text('mmmmmmmmmwwwwwww').appendTo(document.body); 44471 var originalWidth = $tester.css('fontFamily', testFontName).width(); 44472 var width = $tester.css('fontFamily', fontName + ',' + testFontName).width(); 44473 $tester.remove(); 44474 return originalWidth !== width; 44475} 44476var userAgent = navigator.userAgent; 44477var isMSIE = /MSIE|Trident/i.test(userAgent); 44478var browserVersion; 44479if (isMSIE) { 44480 var matches = /MSIE (\d+[.]\d+)/.exec(userAgent); 44481 if (matches) { 44482 browserVersion = parseFloat(matches[1]); 44483 } 44484 matches = /Trident\/.*rv:([0-9]{1,}[.0-9]{0,})/.exec(userAgent); 44485 if (matches) { 44486 browserVersion = parseFloat(matches[1]); 44487 } 44488} 44489var isEdge = /Edge\/\d+/.test(userAgent); 44490var hasCodeMirror = !!window.CodeMirror; 44491if (!hasCodeMirror && isSupportAmd) { 44492 // Webpack 44493 if (typeof __webpack_require__ === 'function') { 44494 try { 44495 // If CodeMirror can't be resolved, `require.resolve` will throw an 44496 // exception and `hasCodeMirror` won't be set to `true`.
44497 require.resolve('codemirror'); 44498 hasCodeMirror = true; 44499 } 44500 catch (e) { 44501 // do nothing 44502 } 44503 } 44504 else if (typeof require !== 'undefined') { 44505 // Browserify 44506 if (typeof require.resolve !== 'undefined') { 44507 try { 44508 // If CodeMirror can't be resolved, `require.resolve` will throw an 44509 // exception and `hasCodeMirror` won't be set to `true`. 44510 require.resolve('codemirror'); 44511 hasCodeMirror = true; 44512 } 44513 catch (e) { 44514 // do nothing 44515 } 44516 // Almond/Require 44517 } 44518 else if (typeof require.specified !== 'undefined') { 44519 hasCodeMirror = require.specified('codemirror'); 44520 } 44521 } 44522} 44523var isSupportTouch = (('ontouchstart' in window) || 44524 (navigator.MaxTouchPoints > 0) || 44525 (navigator.msMaxTouchPoints > 0)); 44526// [workaround] IE doesn't have input events for contentEditable 44527// - see: https://goo.gl/4bfIvA 44528var inputEventName = (isMSIE || isEdge) ? 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted' : 'input'; 44529/** 44530 * @class core.env 44531 * 44532 * Object which check platform and agent 44533 * 44534 * @singleton 44535 * @alternateClassName env 44536 */ 44537var env = { 44538 isMac: navigator.appVersion.indexOf('Mac') > -1, 44539 isMSIE: isMSIE, 44540 isEdge: isEdge, 44541 isFF: !isEdge && /firefox/i.test(userAgent), 44542 isPhantom: /PhantomJS/i.test(userAgent), 44543 isWebkit: !isEdge && /webkit/i.test(userAgent), 44544 isChrome: !isEdge && /chrome/i.test(userAgent), 44545 isSafari: !isEdge && /safari/i.test(userAgent), 44546 browserVersion: browserVersion, 44547 jqueryVersion: parseFloat($$1.fn.jquery), 44548 isSupportAmd: isSupportAmd, 44549 isSupportTouch: isSupportTouch, 44550 hasCodeMirror: hasCodeMirror, 44551 isFontInstalled: isFontInstalled, 44552 isW3CRangeSupport: !!document.createRange, 44553 inputEventName: inputEventName 44554}; 44555 44556var NBSP_CHAR = String.fromCharCode(160); 44557var ZERO_WIDTH_NBSP_CHAR = '\ufeff'; 44558/** 44559 * @method isEditable 44560 * 44561 * returns whether node is `note-editable` or not. 44562 * 44563 * @param {Node} node 44564 * @return {Boolean} 44565 */ 44566function isEditable(node) { 44567 return node && $$1(node).hasClass('note-editable'); 44568} 44569/** 44570 * @method isControlSizing 44571 * 44572 * returns whether node is `note-control-sizing` or not. 44573 * 44574 * @param {Node} node 44575 * @return {Boolean} 44576 */ 44577function isControlSizing(node) { 44578 return node && $$1(node).hasClass('note-control-sizing'); 44579} 44580/** 44581 * @method makePredByNodeName 44582 * 44583 * returns predicate which judge whether nodeName is same 44584 * 44585 * @param {String} nodeName 44586 * @return {Function} 44587 */ 44588function makePredByNodeName(nodeName) { 44589 nodeName = nodeName.toUpperCase(); 44590 return function (node) { 44591 return node && node.nodeName.toUpperCase() === nodeName; 44592 }; 44593} 44594/** 44595 * @method isText 44596 * 44597 * 44598 * 44599 * @param {Node} node 44600 * @return {Boolean} true if node's type is text(3) 44601 */ 44602function isText(node) { 44603 return node && node.nodeType === 3; 44604} 44605/** 44606 * @method isElement 44607 * 44608 * 44609 * 44610 * @param {Node} node 44611 * @return {Boolean} true if node's type is element(1) 44612 */ 44613function isElement(node) { 44614 return node && node.nodeType === 1; 44615} 44616/** 44617 * ex) br, col, embed, hr, img, input, ... 44618 * @see http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements 44619 */ 44620function isVoid(node) { 44621 return node && /^BR|^IMG|^HR|^IFRAME|^BUTTON|^INPUT/.test(node.nodeName.toUpperCase()); 44622} 44623function isPara(node) { 44624 if (isEditable(node)) { 44625 return false; 44626 } 44627 // Chrome(v31.0), FF(v25.0.1) use DIV for paragraph 44628 return node && /^DIV|^P|^LI|^H[1-7]/.test(node.nodeName.toUpperCase()); 44629} 44630function isHeading(node) { 44631 return node && /^H[1-7]/.test(node.nodeName.toUpperCase()); 44632} 44633var isPre = makePredByNodeName('PRE'); 44634var isLi = makePredByNodeName('LI'); 44635function isPurePara(node) { 44636 return isPara(node) && !isLi(node); 44637} 44638var isTable = makePredByNodeName('TABLE'); 44639var isData = makePredByNodeName('DATA'); 44640function isInline(node) { 44641 return !isBodyContainer(node) && 44642 !isList(node) && 44643 !isHr(node) && 44644 !isPara(node) && 44645 !isTable(node) && 44646 !isBlockquote(node) && 44647 !isData(node); 44648} 44649function isList(node) { 44650 return node && /^UL|^OL/.test(node.nodeName.toUpperCase()); 44651} 44652var isHr = makePredByNodeName('HR'); 44653function isCell(node) { 44654 return node && /^TD|^TH/.test(node.nodeName.toUpperCase()); 44655} 44656var isBlockquote = makePredByNodeName('BLOCKQUOTE'); 44657function isBodyContainer(node) { 44658 return isCell(node) || isBlockquote(node) || isEditable(node); 44659} 44660var isAnchor = makePredByNodeName('A'); 44661function isParaInline(node) { 44662 return isInline(node) && !!ancestor(node, isPara); 44663} 44664function isBodyInline(node) { 44665 return isInline(node) && !ancestor(node, isPara); 44666} 44667var isBody = makePredByNodeName('BODY'); 44668/** 44669 * returns whether nodeB is closest sibling of nodeA 44670 * 44671 * @param {Node} nodeA 44672 * @param {Node} nodeB 44673 * @return {Boolean} 44674 */ 44675function isClosestSibling(nodeA, nodeB) { 44676 return nodeA.nextSibling === nodeB || 44677 nodeA.previousSibling === nodeB; 44678} 44679/** 44680 * returns array of closest siblings with node 44681 * 44682 * @param {Node} node 44683 * @param {function} [pred] - predicate function 44684 * @return {Node[]} 44685 */ 44686function withClosestSiblings(node, pred) { 44687 pred = pred || func.ok; 44688 var siblings = []; 44689 if (node.previousSibling && pred(node.previousSibling)) { 44690 siblings.push(node.previousSibling); 44691 } 44692 siblings.push(node); 44693 if (node.nextSibling && pred(node.nextSibling)) { 44694 siblings.push(node.nextSibling); 44695 } 44696 return siblings; 44697} 44698/** 44699 * blank HTML for cursor position 44700 * - [workaround] old IE only works with 44701 * - [workaround] IE11 and other browser works with bogus br 44702 */ 44703var blankHTML = env.isMSIE && env.browserVersion < 11 ? ' ' : '<br>'; 44704/** 44705 * @method nodeLength 44706 * 44707 * returns #text's text size or element's childNodes size 44708 * 44709 * @param {Node} node 44710 */ 44711function nodeLength(node) { 44712 if (isText(node)) { 44713 return node.nodeValue.length; 44714 } 44715 if (node) { 44716 return node.childNodes.length; 44717 } 44718 return 0; 44719} 44720/** 44721 * returns whether node is empty or not. 44722 * 44723 * @param {Node} node 44724 * @return {Boolean} 44725 */ 44726function isEmpty(node) { 44727 var len = nodeLength(node); 44728 if (len === 0) { 44729 return true; 44730 } 44731 else if (!isText(node) && len === 1 && node.innerHTML === blankHTML) { 44732 // ex) <p><br></p>, <span><br></span> 44733 return true; 44734 } 44735 else if (lists.all(node.childNodes, isText) && node.innerHTML === '') { 44736 // ex) <p></p>, <span></span> 44737 return true; 44738 } 44739 return false;
vendor: 7,012 bytes, lines 44740-45044
44740} 44741/** 44742 * padding blankHTML if node is empty (for cursor position) 44743 */ 44744function paddingBlankHTML(node) { 44745 if (!isVoid(node) && !nodeLength(node)) { 44746 node.innerHTML = blankHTML; 44747 } 44748} 44749/** 44750 * find nearest ancestor predicate hit 44751 * 44752 * @param {Node} node 44753 * @param {Function} pred - predicate function 44754 */ 44755function ancestor(node, pred) { 44756 while (node) { 44757 if (pred(node)) { 44758 return node; 44759 } 44760 if (isEditable(node)) { 44761 break; 44762 } 44763 node = node.parentNode; 44764 } 44765 return null; 44766} 44767/** 44768 * find nearest ancestor only single child blood line and predicate hit 44769 * 44770 * @param {Node} node 44771 * @param {Function} pred - predicate function 44772 */ 44773function singleChildAncestor(node, pred) { 44774 node = node.parentNode; 44775 while (node) { 44776 if (nodeLength(node) !== 1) { 44777 break; 44778 } 44779 if (pred(node)) { 44780 return node; 44781 } 44782 if (isEditable(node)) { 44783 break; 44784 } 44785 node = node.parentNode; 44786 } 44787 return null; 44788} 44789/** 44790 * returns new array of ancestor nodes (until predicate hit). 44791 * 44792 * @param {Node} node 44793 * @param {Function} [optional] pred - predicate function 44794 */ 44795function listAncestor(node, pred) { 44796 pred = pred || func.fail; 44797 var ancestors = []; 44798 ancestor(node, function (el) { 44799 if (!isEditable(el)) { 44800 ancestors.push(el); 44801 } 44802 return pred(el); 44803 }); 44804 return ancestors; 44805} 44806/** 44807 * find farthest ancestor predicate hit 44808 */ 44809function lastAncestor(node, pred) { 44810 var ancestors = listAncestor(node); 44811 return lists.last(ancestors.filter(pred)); 44812} 44813/** 44814 * returns common ancestor node between two nodes. 44815 * 44816 * @param {Node} nodeA 44817 * @param {Node} nodeB 44818 */ 44819function commonAncestor(nodeA, nodeB) { 44820 var ancestors = listAncestor(nodeA); 44821 for (var n = nodeB; n; n = n.parentNode) { 44822 if ($$1.inArray(n, ancestors) > -1) { 44823 return n; 44824 } 44825 } 44826 return null; // difference document area 44827} 44828/** 44829 * listing all previous siblings (until predicate hit). 44830 * 44831 * @param {Node} node 44832 * @param {Function} [optional] pred - predicate function 44833 */ 44834function listPrev(node, pred) { 44835 pred = pred || func.fail; 44836 var nodes = []; 44837 while (node) { 44838 if (pred(node)) { 44839 break; 44840 } 44841 nodes.push(node); 44842 node = node.previousSibling; 44843 } 44844 return nodes; 44845} 44846/** 44847 * listing next siblings (until predicate hit). 44848 * 44849 * @param {Node} node 44850 * @param {Function} [pred] - predicate function 44851 */ 44852function listNext(node, pred) { 44853 pred = pred || func.fail; 44854 var nodes = []; 44855 while (node) { 44856 if (pred(node)) { 44857 break; 44858 } 44859 nodes.push(node); 44860 node = node.nextSibling; 44861 } 44862 return nodes; 44863} 44864/** 44865 * listing descendant nodes 44866 * 44867 * @param {Node} node 44868 * @param {Function} [pred] - predicate function 44869 */ 44870function listDescendant(node, pred) { 44871 var descendants = []; 44872 pred = pred || func.ok; 44873 // start DFS(depth first search) with node 44874 (function fnWalk(current) { 44875 if (node !== current && pred(current)) { 44876 descendants.push(current); 44877 } 44878 for (var idx = 0, len = current.childNodes.length; idx < len; idx++) { 44879 fnWalk(current.childNodes[idx]); 44880 } 44881 })(node); 44882 return descendants; 44883} 44884/** 44885 * wrap node with new tag. 44886 * 44887 * @param {Node} node 44888 * @param {Node} tagName of wrapper 44889 * @return {Node} - wrapper 44890 */ 44891function wrap(node, wrapperName) { 44892 var parent = node.parentNode; 44893 var wrapper = $$1('<' + wrapperName + '>')[0]; 44894 parent.insertBefore(wrapper, node); 44895 wrapper.appendChild(node); 44896 return wrapper; 44897} 44898/** 44899 * insert node after preceding 44900 * 44901 * @param {Node} node 44902 * @param {Node} preceding - predicate function 44903 */ 44904function insertAfter(node, preceding) { 44905 var next = preceding.nextSibling; 44906 var parent = preceding.parentNode; 44907 if (next) { 44908 parent.insertBefore(node, next); 44909 } 44910 else { 44911 parent.appendChild(node); 44912 } 44913 return node; 44914} 44915/** 44916 * append elements. 44917 * 44918 * @param {Node} node 44919 * @param {Collection} aChild 44920 */ 44921function appendChildNodes(node, aChild) { 44922 $$1.each(aChild, function (idx, child) { 44923 node.appendChild(child); 44924 }); 44925 return node; 44926} 44927/** 44928 * returns whether boundaryPoint is left edge or not. 44929 * 44930 * @param {BoundaryPoint} point 44931 * @return {Boolean} 44932 */ 44933function isLeftEdgePoint(point) { 44934 return point.offset === 0; 44935} 44936/** 44937 * returns whether boundaryPoint is right edge or not. 44938 * 44939 * @param {BoundaryPoint} point 44940 * @return {Boolean} 44941 */ 44942function isRightEdgePoint(point) { 44943 return point.offset === nodeLength(point.node); 44944} 44945/** 44946 * returns whether boundaryPoint is edge or not. 44947 * 44948 * @param {BoundaryPoint} point 44949 * @return {Boolean} 44950 */ 44951function isEdgePoint(point) { 44952 return isLeftEdgePoint(point) || isRightEdgePoint(point); 44953} 44954/** 44955 * returns whether node is left edge of ancestor or not. 44956 * 44957 * @param {Node} node 44958 * @param {Node} ancestor 44959 * @return {Boolean} 44960 */ 44961function isLeftEdgeOf(node, ancestor) { 44962 while (node && node !== ancestor) { 44963 if (position(node) !== 0) { 44964 return false; 44965 } 44966 node = node.parentNode; 44967 } 44968 return true; 44969} 44970/** 44971 * returns whether node is right edge of ancestor or not. 44972 * 44973 * @param {Node} node 44974 * @param {Node} ancestor 44975 * @return {Boolean} 44976 */ 44977function isRightEdgeOf(node, ancestor) { 44978 if (!ancestor) { 44979 return false; 44980 } 44981 while (node && node !== ancestor) { 44982 if (position(node) !== nodeLength(node.parentNode) - 1) { 44983 return false; 44984 } 44985 node = node.parentNode; 44986 } 44987 return true; 44988} 44989/** 44990 * returns whether point is left edge of ancestor or not. 44991 * @param {BoundaryPoint} point 44992 * @param {Node} ancestor 44993 * @return {Boolean} 44994 */ 44995function isLeftEdgePointOf(point, ancestor) { 44996 return isLeftEdgePoint(point) && isLeftEdgeOf(point.node, ancestor); 44997} 44998/** 44999 * returns whether point is right edge of ancestor or not. 45000 * @param {BoundaryPoint} point 45001 * @param {Node} ancestor 45002 * @return {Boolean} 45003 */ 45004function isRightEdgePointOf(point, ancestor) { 45005 return isRightEdgePoint(point) && isRightEdgeOf(point.node, ancestor); 45006} 45007/** 45008 * returns offset from parent. 45009 * 45010 * @param {Node} node 45011 */ 45012function position(node) { 45013 var offset = 0; 45014 while ((node = node.previousSibling)) { 45015 offset += 1; 45016 } 45017 return offset; 45018} 45019function hasChildren(node) { 45020 return !!(node && node.childNodes && node.childNodes.length); 45021} 45022/** 45023 * returns previous boundaryPoint 45024 * 45025 * @param {BoundaryPoint} point 45026 * @param {Boolean} isSkipInnerOffset 45027 * @return {BoundaryPoint} 45028 */ 45029function prevPoint(point, isSkipInnerOffset) { 45030 var node; 45031 var offset; 45032 if (point.offset === 0) { 45033 if (isEditable(point.node)) { 45034 return null; 45035 } 45036 node = point.node.parentNode; 45037 offset = position(point.node); 45038 } 45039 else if (hasChildren(point.node)) { 45040 node = point.node.childNodes[point.offset - 1]; 45041 offset = nodeLength(node); 45042 } 45043 else { 45044 node = point.node;
vendor: 3,065 bytes, lines 45045-45170
45045 offset = isSkipInnerOffset ? 0 : point.offset - 1; 45046 } 45047 return { 45048 node: node, 45049 offset: offset 45050 }; 45051} 45052/** 45053 * returns next boundaryPoint 45054 * 45055 * @param {BoundaryPoint} point 45056 * @param {Boolean} isSkipInnerOffset 45057 * @return {BoundaryPoint} 45058 */ 45059function nextPoint(point, isSkipInnerOffset) { 45060 var node, offset; 45061 if (nodeLength(point.node) === point.offset) { 45062 if (isEditable(point.node)) { 45063 return null; 45064 } 45065 node = point.node.parentNode; 45066 offset = position(point.node) + 1; 45067 } 45068 else if (hasChildren(point.node)) { 45069 node = point.node.childNodes[point.offset]; 45070 offset = 0; 45071 } 45072 else { 45073 node = point.node; 45074 offset = isSkipInnerOffset ? nodeLength(point.node) : point.offset + 1; 45075 } 45076 return { 45077 node: node, 45078 offset: offset 45079 }; 45080} 45081/** 45082 * returns whether pointA and pointB is same or not. 45083 * 45084 * @param {BoundaryPoint} pointA 45085 * @param {BoundaryPoint} pointB 45086 * @return {Boolean} 45087 */ 45088function isSamePoint(pointA, pointB) { 45089 return pointA.node === pointB.node && pointA.offset === pointB.offset; 45090} 45091/** 45092 * returns whether point is visible (can set cursor) or not. 45093 * 45094 * @param {BoundaryPoint} point 45095 * @return {Boolean} 45096 */ 45097function isVisiblePoint(point) { 45098 if (isText(point.node) || !hasChildren(point.node) || isEmpty(point.node)) { 45099 return true; 45100 } 45101 var leftNode = point.node.childNodes[point.offset - 1]; 45102 var rightNode = point.node.childNodes[point.offset]; 45103 if ((!leftNode || isVoid(leftNode)) && (!rightNode || isVoid(rightNode))) { 45104 return true; 45105 } 45106 return false; 45107} 45108/** 45109 * @method prevPointUtil 45110 * 45111 * @param {BoundaryPoint} point 45112 * @param {Function} pred 45113 * @return {BoundaryPoint} 45114 */ 45115function prevPointUntil(point, pred) { 45116 while (point) { 45117 if (pred(point)) { 45118 return point; 45119 } 45120 point = prevPoint(point); 45121 } 45122 return null; 45123} 45124/** 45125 * @method nextPointUntil 45126 * 45127 * @param {BoundaryPoint} point 45128 * @param {Function} pred 45129 * @return {BoundaryPoint} 45130 */ 45131function nextPointUntil(point, pred) { 45132 while (point) { 45133 if (pred(point)) { 45134 return point; 45135 } 45136 point = nextPoint(point); 45137 } 45138 return null; 45139} 45140/** 45141 * returns whether point has character or not. 45142 * 45143 * @param {Point} point 45144 * @return {Boolean} 45145 */ 45146function isCharPoint(point) { 45147 if (!isText(point.node)) { 45148 return false; 45149 } 45150 var ch = point.node.nodeValue.charAt(point.offset - 1); 45151 return ch && (ch !== ' ' && ch !== NBSP_CHAR); 45152} 45153/** 45154 * @method walkPoint 45155 * 45156 * @param {BoundaryPoint} startPoint 45157 * @param {BoundaryPoint} endPoint 45158 * @param {Function} handler 45159 * @param {Boolean} isSkipInnerOffset 45160 */ 45161function walkPoint(startPoint, endPoint, handler, isSkipInnerOffset) { 45162 var point = startPoint; 45163 while (point) { 45164 handler(point); 45165 if (isSamePoint(point, endPoint)) { 45166 break; 45167 } 45168 var isSkipOffset = isSkipInnerOffset && 45169 startPoint.node !== point.node && 45170 endPoint.node !== point.node;
45171 point = nextPoint(point, isSkipOffset); 45172 } 45173} 45174/** 45175 * @method makeOffsetPath 45176 * 45177 * return offsetPath(array of offset) from ancestor 45178 * 45179 * @param {Node} ancestor - ancestor node 45180 * @param {Node} node 45181 */ 45182function makeOffsetPath(ancestor, node) { 45183 var ancestors = listAncestor(node, func.eq(ancestor)); 45184 return ancestors.map(position).reverse(); 45185} 45186/** 45187 * @method fromOffsetPath 45188 * 45189 * return element from offsetPath(array of offset) 45190 * 45191 * @param {Node} ancestor - ancestor node 45192 * @param {array} offsets - offsetPath 45193 */ 45194function fromOffsetPath(ancestor, offsets) { 45195 var current = ancestor; 45196 for (var i = 0, len = offsets.length; i < len; i++) { 45197 if (current.childNodes.length <= offsets[i]) { 45198 current = current.childNodes[current.childNodes.length - 1]; 45199 } 45200 else { 45201 current = current.childNodes[offsets[i]]; 45202 } 45203 } 45204 return current; 45205} 45206/** 45207 * @method splitNode 45208 * 45209 * split element or #text 45210 * 45211 * @param {BoundaryPoint} point 45212 * @param {Object} [options] 45213 * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false 45214 * @param {Boolean} [options.isNotSplitEdgePoint] - default: false 45215 * @return {Node} right node of boundaryPoint 45216 */ 45217function splitNode(point, options) { 45218 var isSkipPaddingBlankHTML = options && options.isSkipPaddingBlankHTML; 45219 var isNotSplitEdgePoint = options && options.isNotSplitEdgePoint; 45220 // edge case 45221 if (isEdgePoint(point) && (isText(point.node) || isNotSplitEdgePoint)) { 45222 if (isLeftEdgePoint(point)) { 45223 return point.node;
vendor: 5,685 bytes, lines 45224-45427
45224 } 45225 else if (isRightEdgePoint(point)) { 45226 return point.node.nextSibling; 45227 } 45228 } 45229 // split #text 45230 if (isText(point.node)) { 45231 return point.node.splitText(point.offset); 45232 } 45233 else { 45234 var childNode = point.node.childNodes[point.offset]; 45235 var clone = insertAfter(point.node.cloneNode(false), point.node); 45236 appendChildNodes(clone, listNext(childNode)); 45237 if (!isSkipPaddingBlankHTML) { 45238 paddingBlankHTML(point.node); 45239 paddingBlankHTML(clone); 45240 } 45241 return clone; 45242 } 45243} 45244/** 45245 * @method splitTree 45246 * 45247 * split tree by point 45248 * 45249 * @param {Node} root - split root 45250 * @param {BoundaryPoint} point 45251 * @param {Object} [options] 45252 * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false 45253 * @param {Boolean} [options.isNotSplitEdgePoint] - default: false 45254 * @return {Node} right node of boundaryPoint 45255 */ 45256function splitTree(root, point, options) { 45257 // ex) [#text, <span>, <p>] 45258 var ancestors = listAncestor(point.node, func.eq(root)); 45259 if (!ancestors.length) { 45260 return null; 45261 } 45262 else if (ancestors.length === 1) { 45263 return splitNode(point, options); 45264 } 45265 return ancestors.reduce(function (node, parent) { 45266 if (node === point.node) { 45267 node = splitNode(point, options); 45268 } 45269 return splitNode({ 45270 node: parent, 45271 offset: node ? position(node) : nodeLength(parent) 45272 }, options); 45273 }); 45274} 45275/** 45276 * split point 45277 * 45278 * @param {Point} point 45279 * @param {Boolean} isInline 45280 * @return {Object} 45281 */ 45282function splitPoint(point, isInline) { 45283 // find splitRoot, container 45284 // - inline: splitRoot is a child of paragraph 45285 // - block: splitRoot is a child of bodyContainer 45286 var pred = isInline ? isPara : isBodyContainer; 45287 var ancestors = listAncestor(point.node, pred); 45288 var topAncestor = lists.last(ancestors) || point.node; 45289 var splitRoot, container; 45290 if (pred(topAncestor)) { 45291 splitRoot = ancestors[ancestors.length - 2]; 45292 container = topAncestor; 45293 } 45294 else { 45295 splitRoot = topAncestor; 45296 container = splitRoot.parentNode; 45297 } 45298 // if splitRoot is exists, split with splitTree 45299 var pivot = splitRoot && splitTree(splitRoot, point, { 45300 isSkipPaddingBlankHTML: isInline, 45301 isNotSplitEdgePoint: isInline 45302 }); 45303 // if container is point.node, find pivot with point.offset 45304 if (!pivot && container === point.node) { 45305 pivot = point.node.childNodes[point.offset]; 45306 } 45307 return { 45308 rightNode: pivot, 45309 container: container 45310 }; 45311} 45312function create(nodeName) { 45313 return document.createElement(nodeName); 45314} 45315function createText(text) { 45316 return document.createTextNode(text); 45317} 45318/** 45319 * @method remove 45320 * 45321 * remove node, (isRemoveChild: remove child or not) 45322 * 45323 * @param {Node} node 45324 * @param {Boolean} isRemoveChild 45325 */ 45326function remove(node, isRemoveChild) { 45327 if (!node || !node.parentNode) { 45328 return; 45329 } 45330 if (node.removeNode) { 45331 return node.removeNode(isRemoveChild); 45332 } 45333 var parent = node.parentNode; 45334 if (!isRemoveChild) { 45335 var nodes = []; 45336 for (var i = 0, len = node.childNodes.length; i < len; i++) { 45337 nodes.push(node.childNodes[i]); 45338 } 45339 for (var i = 0, len = nodes.length; i < len; i++) { 45340 parent.insertBefore(nodes[i], node); 45341 } 45342 } 45343 parent.removeChild(node); 45344} 45345/** 45346 * @method removeWhile 45347 * 45348 * @param {Node} node 45349 * @param {Function} pred 45350 */ 45351function removeWhile(node, pred) { 45352 while (node) { 45353 if (isEditable(node) || !pred(node)) { 45354 break; 45355 } 45356 var parent = node.parentNode; 45357 remove(node); 45358 node = parent; 45359 } 45360} 45361/** 45362 * @method replace 45363 * 45364 * replace node with provided nodeName 45365 * 45366 * @param {Node} node 45367 * @param {String} nodeName 45368 * @return {Node} - new node 45369 */ 45370function replace(node, nodeName) { 45371 if (node.nodeName.toUpperCase() === nodeName.toUpperCase()) { 45372 return node; 45373 } 45374 var newNode = create(nodeName); 45375 if (node.style.cssText) { 45376 newNode.style.cssText = node.style.cssText; 45377 } 45378 appendChildNodes(newNode, lists.from(node.childNodes)); 45379 insertAfter(newNode, node); 45380 remove(node); 45381 return newNode; 45382} 45383var isTextarea = makePredByNodeName('TEXTAREA'); 45384/** 45385 * @param {jQuery} $node 45386 * @param {Boolean} [stripLinebreaks] - default: false 45387 */ 45388function value($node, stripLinebreaks) { 45389 var val = isTextarea($node[0]) ? $node.val() : $node.html(); 45390 if (stripLinebreaks) { 45391 return val.replace(/[\n\r]/g, ''); 45392 } 45393 return val; 45394} 45395/** 45396 * @method html 45397 * 45398 * get the HTML contents of node 45399 * 45400 * @param {jQuery} $node 45401 * @param {Boolean} [isNewlineOnBlock] 45402 */ 45403function html($node, isNewlineOnBlock) { 45404 var markup = value($node); 45405 if (isNewlineOnBlock) { 45406 var regexTag = /<(\/?)(\b(?!!)[^>\s]*)(.*?)(\s*\/?>)/g; 45407 markup = markup.replace(regexTag, function (match, endSlash, name) { 45408 name = name.toUpperCase(); 45409 var isEndOfInlineContainer = /^DIV|^TD|^TH|^P|^LI|^H[1-7]/.test(name) && 45410 !!endSlash; 45411 var isBlockNode = /^BLOCKQUOTE|^TABLE|^TBODY|^TR|^HR|^UL|^OL/.test(name); 45412 return match + ((isEndOfInlineContainer || isBlockNode) ? '\n' : ''); 45413 }); 45414 markup = $$1.trim(markup); 45415 } 45416 return markup; 45417} 45418function posFromPlaceholder(placeholder) { 45419 var $placeholder = $$1(placeholder); 45420 var pos = $placeholder.offset(); 45421 var height = $placeholder.outerHeight(true); // include margin 45422 return { 45423 left: pos.left, 45424 top: pos.top + height 45425 }; 45426} 45427function attachEvents($node, events) {
45428 Object.keys(events).forEach(function (key) { 45429 $node.on(key, events[key]); 45430 }); 45431} 45432function detachEvents($node, events) { 45433 Object.keys(events).forEach(function (key) { 45434 $node.off(key, events[key]); 45435 }); 45436} 45437/** 45438 * @method isCustomStyleTag 45439 * 45440 * assert if a node contains a "note-styletag" class, 45441 * which implies that's a custom-made style tag node 45442 * 45443 * @param {Node} an HTML DOM node 45444 */ 45445function isCustomStyleTag(node) { 45446 return node && !isText(node) && lists.contains(node.classList, 'note-styletag'); 45447} 45448var dom = { 45449 /** @property {String} NBSP_CHAR */ 45450 NBSP_CHAR: NBSP_CHAR, 45451 /** @property {String} ZERO_WIDTH_NBSP_CHAR */ 45452 ZERO_WIDTH_NBSP_CHAR: ZERO_WIDTH_NBSP_CHAR, 45453 /** @property {String} blank */ 45454 blank: blankHTML, 45455 /** @property {String} emptyPara */ 45456 emptyPara: "<p>" + blankHTML + "</p>", 45457 makePredByNodeName: makePredByNodeName, 45458 isEditable: isEditable, 45459 isControlSizing: isControlSizing, 45460 isText: isText, 45461 isElement: isElement, 45462 isVoid: isVoid, 45463 isPara: isPara, 45464 isPurePara: isPurePara, 45465 isHeading: isHeading, 45466 isInline: isInline, 45467 isBlock: func.not(isInline), 45468 isBodyInline: isBodyInline, 45469 isBody: isBody, 45470 isParaInline: isParaInline, 45471 isPre: isPre, 45472 isList: isList, 45473 isTable: isTable, 45474 isData: isData, 45475 isCell: isCell, 45476 isBlockquote: isBlockquote, 45477 isBodyContainer: isBodyContainer, 45478 isAnchor: isAnchor, 45479 isDiv: makePredByNodeName('DIV'), 45480 isLi: isLi, 45481 isBR: makePredByNodeName('BR'), 45482 isSpan: makePredByNodeName('SPAN'), 45483 isB: makePredByNodeName('B'), 45484 isU: makePredByNodeName('U'), 45485 isS: makePredByNodeName('S'), 45486 isI: makePredByNodeName('I'), 45487 isImg: makePredByNodeName('IMG'), 45488 isTextarea: isTextarea, 45489 isEmpty: isEmpty, 45490 isEmptyAnchor: func.and(isAnchor, isEmpty), 45491 isClosestSibling: isClosestSibling, 45492 withClosestSiblings: withClosestSiblings, 45493 nodeLength: nodeLength, 45494 isLeftEdgePoint: isLeftEdgePoint, 45495 isRightEdgePoint: isRightEdgePoint, 45496 isEdgePoint: isEdgePoint, 45497 isLeftEdgeOf: isLeftEdgeOf, 45498 isRightEdgeOf: isRightEdgeOf, 45499 isLeftEdgePointOf: isLeftEdgePointOf, 45500 isRightEdgePointOf: isRightEdgePointOf, 45501 prevPoint: prevPoint, 45502 nextPoint: nextPoint, 45503 isSamePoint: isSamePoint, 45504 isVisiblePoint: isVisiblePoint, 45505 prevPointUntil: prevPointUntil, 45506 nextPointUntil: nextPointUntil, 45507 isCharPoint: isCharPoint, 45508 walkPoint: walkPoint, 45509 ancestor: ancestor, 45510 singleChildAncestor: singleChildAncestor, 45511 listAncestor: listAncestor, 45512 lastAncestor: lastAncestor, 45513 listNext: listNext, 45514 listPrev: listPrev, 45515 listDescendant: listDescendant, 45516 commonAncestor: commonAncestor, 45517 wrap: wrap, 45518 insertAfter: insertAfter, 45519 appendChildNodes: appendChildNodes, 45520 position: position, 45521 hasChildren: hasChildren, 45522 makeOffsetPath: makeOffsetPath, 45523 fromOffsetPath: fromOffsetPath, 45524 splitTree: splitTree, 45525 splitPoint: splitPoint, 45526 create: create, 45527 createText: createText, 45528 remove: remove, 45529 removeWhile: removeWhile, 45530 replace: replace, 45531 html: html, 45532 value: value, 45533 posFromPlaceholder: posFromPlaceholder, 45534 attachEvents: attachEvents, 45535 detachEvents: detachEvents, 45536 isCustomStyleTag: isCustomStyleTag 45537}; 45538 45539$$1.summernote = $$1.summernote || { 45540 lang: {} 45541}; 45542$$1.extend($$1.summernote.lang, { 45543 'en-US': { 45544 font: { 45545 bold: 'Bold', 45546 italic: 'Italic', 45547 underline: 'Underline', 45548 clear: 'Remove Font Style', 45549 height: 'Line Height', 45550 name: 'Font Family', 45551 strikethrough: 'Strikethrough', 45552 subscript: 'Subscript', 45553 superscript: 'Superscript', 45554 size: 'Font Size' 45555 }, 45556 image: { 45557 image: 'Picture', 45558 insert: 'Insert Image', 45559 resizeFull: 'Resize Full', 45560 resizeHalf: 'Resize Half', 45561 resizeQuarter: 'Resize Quarter', 45562 floatLeft: 'Float Left', 45563 floatRight: 'Float Right', 45564 floatNone: 'Float None', 45565 shapeRounded: 'Shape: Rounded', 45566 shapeCircle: 'Shape: Circle', 45567 shapeThumbnail: 'Shape: Thumbnail', 45568 shapeNone: 'Shape: None', 45569 dragImageHere: 'Drag image or text here', 45570 dropImage: 'Drop image or Text', 45571 selectFromFiles: 'Select from files', 45572 maximumFileSize: 'Maximum file size', 45573 maximumFileSizeError: 'Maximum file size exceeded.', 45574 url: 'Image URL', 45575 remove: 'Remove Image', 45576 original: 'Original' 45577 }, 45578 video: { 45579 video: 'Video', 45580 videoLink: 'Video Link', 45581 insert: 'Insert Video', 45582 url: 'Video URL', 45583 providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion or Youku)' 45584 }, 45585 link: { 45586 link: 'Link', 45587 insert: 'Insert Link', 45588 unlink: 'Unlink', 45589 edit: 'Edit', 45590 textToDisplay: 'Text to display', 45591 url: 'To what URL should this link go?', 45592 openInNewWindow: 'Open in new window' 45593 }, 45594 table: { 45595 table: 'Table', 45596 addRowAbove: 'Add row above', 45597 addRowBelow: 'Add row below', 45598 addColLeft: 'Add column left', 45599 addColRight: 'Add column right', 45600 delRow: 'Delete row', 45601 delCol: 'Delete column', 45602 delTable: 'Delete table' 45603 }, 45604 hr: { 45605 insert: 'Insert Horizontal Rule' 45606 }, 45607 style: { 45608 style: 'Style', 45609 p: 'Normal', 45610 blockquote: 'Quote', 45611 pre: 'Code', 45612 h1: 'Header 1', 45613 h2: 'Header 2', 45614 h3: 'Header 3', 45615 h4: 'Header 4', 45616 h5: 'Header 5', 45617 h6: 'Header 6' 45618 }, 45619 lists: { 45620 unordered: 'Unordered list', 45621 ordered: 'Ordered list' 45622 }, 45623 options: { 45624 help: 'Help', 45625 fullscreen: 'Full Screen', 45626 codeview: 'Code View' 45627 }, 45628 paragraph: { 45629 paragraph: 'Paragraph',
45630 outdent: 'Outdent', 45631 indent: 'Indent', 45632 left: 'Align left', 45633 center: 'Align center', 45634 right: 'Align right', 45635 justify: 'Justify full' 45636 }, 45637 color: { 45638 recent: 'Recent Color', 45639 more: 'More Color', 45640 background: 'Background Color', 45641 foreground: 'Foreground Color', 45642 transparent: 'Transparent', 45643 setTransparent: 'Set transparent', 45644 reset: 'Reset', 45645 resetToDefault: 'Reset to default' 45646 }, 45647 shortcut: { 45648 shortcuts: 'Keyboard shortcuts', 45649 close: 'Close', 45650 textFormatting: 'Text formatting', 45651 action: 'Action', 45652 paragraphFormatting: 'Paragraph formatting', 45653 documentStyle: 'Document Style', 45654 extraKeys: 'Extra keys' 45655 }, 45656 help: { 45657 'insertParagraph': 'Insert Paragraph', 45658 'undo': 'Undoes the last command', 45659 'redo': 'Redoes the last command', 45660 'tab': 'Tab', 45661 'untab': 'Untab', 45662 'bold': 'Set a bold style', 45663 'italic': 'Set a italic style', 45664 'underline': 'Set a underline style', 45665 'strikethrough': 'Set a strikethrough style', 45666 'removeFormat': 'Clean a style', 45667 'justifyLeft': 'Set left align', 45668 'justifyCenter': 'Set center align', 45669 'justifyRight': 'Set right align', 45670 'justifyFull': 'Set full align', 45671 'insertUnorderedList': 'Toggle unordered list', 45672 'insertOrderedList': 'Toggle ordered list', 45673 'outdent': 'Outdent on current paragraph', 45674 'indent': 'Indent on current paragraph', 45675 'formatPara': 'Change current block\'s format as a paragraph(P tag)', 45676 'formatH1': 'Change current block\'s format as H1', 45677 'formatH2': 'Change current block\'s format as H2', 45678 'formatH3': 'Change current block\'s format as H3', 45679 'formatH4': 'Change current block\'s format as H4', 45680 'formatH5': 'Change current block\'s format as H5', 45681 'formatH6': 'Change current block\'s format as H6', 45682 'insertHorizontalRule': 'Insert horizontal rule', 45683 'linkDialog.show': 'Show Link Dialog' 45684 }, 45685 history: { 45686 undo: 'Undo', 45687 redo: 'Redo' 45688 }, 45689 specialChar: { 45690 specialChar: 'SPECIAL CHARACTERS', 45691 select: 'Select Special characters' 45692 } 45693 } 45694}); 45695 45696var KEY_MAP = { 45697 'BACKSPACE': 8, 45698 'TAB': 9, 45699 'ENTER': 13, 45700 'SPACE': 32, 45701 'DELETE': 46, 45702 // Arrow 45703 'LEFT': 37, 45704 'UP': 38, 45705 'RIGHT': 39, 45706 'DOWN': 40, 45707 // Number: 0-9 45708 'NUM0': 48, 45709 'NUM1': 49, 45710 'NUM2': 50, 45711 'NUM3': 51, 45712 'NUM4': 52, 45713 'NUM5': 53, 45714 'NUM6': 54, 45715 'NUM7': 55, 45716 'NUM8': 56, 45717 // Alphabet: a-z 45718 'B': 66, 45719 'E': 69, 45720 'I': 73, 45721 'J': 74, 45722 'K': 75, 45723 'L': 76, 45724 'R': 82, 45725 'S': 83, 45726 'U': 85, 45727 'V': 86, 45728 'Y': 89, 45729 'Z': 90, 45730 'SLASH': 191, 45731 'LEFTBRACKET': 219, 45732 'BACKSLASH': 220, 45733 'RIGHTBRACKET': 221 45734}; 45735/** 45736 * @class core.key 45737 * 45738 * Object for keycodes. 45739 * 45740 * @singleton 45741 * @alternateClassName key 45742 */ 45743var key = { 45744 /** 45745 * @method isEdit 45746 * 45747 * @param {Number} keyCode 45748 * @return {Boolean} 45749 */ 45750 isEdit: function (keyCode) { 45751 return lists.contains([ 45752 KEY_MAP.BACKSPACE, 45753 KEY_MAP.TAB, 45754 KEY_MAP.ENTER, 45755 KEY_MAP.SPACE,
vendor: 3,533 bytes, lines 45756-45855
45756 KEY_MAP.DELETE 45757 ], keyCode); 45758 }, 45759 /** 45760 * @method isMove 45761 * 45762 * @param {Number} keyCode 45763 * @return {Boolean} 45764 */ 45765 isMove: function (keyCode) { 45766 return lists.contains([ 45767 KEY_MAP.LEFT, 45768 KEY_MAP.UP, 45769 KEY_MAP.RIGHT, 45770 KEY_MAP.DOWN 45771 ], keyCode); 45772 }, 45773 /** 45774 * @property {Object} nameFromCode 45775 * @property {String} nameFromCode.8 "BACKSPACE" 45776 */ 45777 nameFromCode: func.invertObject(KEY_MAP), 45778 code: KEY_MAP 45779}; 45780 45781/** 45782 * return boundaryPoint from TextRange, inspired by Andy Na's HuskyRange.js 45783 * 45784 * @param {TextRange} textRange 45785 * @param {Boolean} isStart 45786 * @return {BoundaryPoint} 45787 * 45788 * @see http://msdn.microsoft.com/en-us/library/ie/ms535872(v=vs.85).aspx 45789 */ 45790function textRangeToPoint(textRange, isStart) { 45791 var container = textRange.parentElement(); 45792 var offset; 45793 var tester = document.body.createTextRange(); 45794 var prevContainer; 45795 var childNodes = lists.from(container.childNodes); 45796 for (offset = 0; offset < childNodes.length; offset++) { 45797 if (dom.isText(childNodes[offset])) { 45798 continue; 45799 } 45800 tester.moveToElementText(childNodes[offset]); 45801 if (tester.compareEndPoints('StartToStart', textRange) >= 0) { 45802 break; 45803 } 45804 prevContainer = childNodes[offset]; 45805 } 45806 if (offset !== 0 && dom.isText(childNodes[offset - 1])) { 45807 var textRangeStart = document.body.createTextRange(); 45808 var curTextNode = null; 45809 textRangeStart.moveToElementText(prevContainer || container); 45810 textRangeStart.collapse(!prevContainer); 45811 curTextNode = prevContainer ? prevContainer.nextSibling : container.firstChild; 45812 var pointTester = textRange.duplicate(); 45813 pointTester.setEndPoint('StartToStart', textRangeStart); 45814 var textCount = pointTester.text.replace(/[\r\n]/g, '').length; 45815 while (textCount > curTextNode.nodeValue.length && curTextNode.nextSibling) { 45816 textCount -= curTextNode.nodeValue.length; 45817 curTextNode = curTextNode.nextSibling; 45818 } 45819 // [workaround] enforce IE to re-reference curTextNode, hack 45820 var dummy = curTextNode.nodeValue; // eslint-disable-line 45821 if (isStart && curTextNode.nextSibling && dom.isText(curTextNode.nextSibling) && 45822 textCount === curTextNode.nodeValue.length) { 45823 textCount -= curTextNode.nodeValue.length; 45824 curTextNode = curTextNode.nextSibling; 45825 } 45826 container = curTextNode; 45827 offset = textCount; 45828 } 45829 return { 45830 cont: container, 45831 offset: offset 45832 }; 45833} 45834/** 45835 * return TextRange from boundary point (inspired by google closure-library) 45836 * @param {BoundaryPoint} point 45837 * @return {TextRange} 45838 */ 45839function pointToTextRange(point) { 45840 var textRangeInfo = function (container, offset) { 45841 var node, isCollapseToStart; 45842 if (dom.isText(container)) { 45843 var prevTextNodes = dom.listPrev(container, func.not(dom.isText)); 45844 var prevContainer = lists.last(prevTextNodes).previousSibling; 45845 node = prevContainer || container.parentNode; 45846 offset += lists.sum(lists.tail(prevTextNodes), dom.nodeLength); 45847 isCollapseToStart = !prevContainer; 45848 } 45849 else { 45850 node = container.childNodes[offset] || container; 45851 if (dom.isText(node)) { 45852 return textRangeInfo(node, 0); 45853 } 45854 offset = 0; 45855 isCollapseToStart = false;
45856 } 45857 return { 45858 node: node, 45859 collapseToStart: isCollapseToStart, 45860 offset: offset 45861 }; 45862 }; 45863 var textRange = document.body.createTextRange(); 45864 var info = textRangeInfo(point.node, point.offset); 45865 textRange.moveToElementText(info.node); 45866 textRange.collapse(info.collapseToStart); 45867 textRange.moveStart('character', info.offset); 45868 return textRange; 45869} 45870/** 45871 * Wrapped Range 45872 * 45873 * @constructor 45874 * @param {Node} sc - start container 45875 * @param {Number} so - start offset 45876 * @param {Node} ec - end container 45877 * @param {Number} eo - end offset 45878 */ 45879var WrappedRange = /** @class */ (function () { 45880 function WrappedRange(sc, so, ec, eo) { 45881 this.sc = sc; 45882 this.so = so; 45883 this.ec = ec; 45884 this.eo = eo; 45885 // isOnEditable: judge whether range is on editable or not 45886 this.isOnEditable = this.makeIsOn(dom.isEditable); 45887 // isOnList: judge whether range is on list node or not 45888 this.isOnList = this.makeIsOn(dom.isList); 45889 // isOnAnchor: judge whether range is on anchor node or not 45890 this.isOnAnchor = this.makeIsOn(dom.isAnchor); 45891 // isOnCell: judge whether range is on cell node or not 45892 this.isOnCell = this.makeIsOn(dom.isCell); 45893 // isOnData: judge whether range is on data node or not 45894 this.isOnData = this.makeIsOn(dom.isData); 45895 } 45896 // nativeRange: get nativeRange from sc, so, ec, eo 45897 WrappedRange.prototype.nativeRange = function () { 45898 if (env.isW3CRangeSupport) { 45899 var w3cRange = document.createRange(); 45900 w3cRange.setStart(this.sc, this.so); 45901 w3cRange.setEnd(this.ec, this.eo); 45902 return w3cRange; 45903 } 45904 else { 45905 var textRange = pointToTextRange({ 45906 node: this.sc, 45907 offset: this.so 45908 }); 45909 textRange.setEndPoint('EndToEnd', pointToTextRange({ 45910 node: this.ec, 45911 offset: this.eo 45912 })); 45913 return textRange; 45914 } 45915 }; 45916 WrappedRange.prototype.getPoints = function () { 45917 return { 45918 sc: this.sc, 45919 so: this.so, 45920 ec: this.ec, 45921 eo: this.eo 45922 }; 45923 }; 45924 WrappedRange.prototype.getStartPoint = function () { 45925 return { 45926 node: this.sc, 45927 offset: this.so 45928 }; 45929 }; 45930 WrappedRange.prototype.getEndPoint = function () { 45931 return { 45932 node: this.ec, 45933 offset: this.eo 45934 }; 45935 }; 45936 /** 45937 * select update visible range 45938 */ 45939 WrappedRange.prototype.select = function () { 45940 var nativeRng = this.nativeRange(); 45941 if (env.isW3CRangeSupport) { 45942 var selection = document.getSelection(); 45943 if (selection.rangeCount > 0) { 45944 selection.removeAllRanges(); 45945 } 45946 selection.addRange(nativeRng); 45947 } 45948 else { 45949 nativeRng.select(); 45950 } 45951 return this; 45952 }; 45953 /** 45954 * Moves the scrollbar to start container(sc) of current range 45955 * 45956 * @return {WrappedRange} 45957 */ 45958 WrappedRange.prototype.scrollIntoView = function (container) { 45959 var height = $$1(container).height(); 45960 if (container.scrollTop + height < this.sc.offsetTop) { 45961 container.scrollTop += Math.abs(container.scrollTop + height - this.sc.offsetTop); 45962 } 45963 return this; 45964 }; 45965 /** 45966 * @return {WrappedRange} 45967 */ 45968 WrappedRange.prototype.normalize = function () { 45969 /** 45970 * @param {BoundaryPoint} point 45971 * @param {Boolean} isLeftToRight 45972 * @return {BoundaryPoint} 45973 */ 45974 var getVisiblePoint = function (point, isLeftToRight) { 45975 if ((dom.isVisiblePoint(point) && !dom.isEdgePoint(point)) || 45976 (dom.isVisiblePoint(point) && dom.isRightEdgePoint(point) && !isLeftToRight) || 45977 (dom.isVisiblePoint(point) && dom.isLeftEdgePoint(point) && isLeftToRight) || 45978 (dom.isVisiblePoint(point) && dom.isBlock(point.node) && dom.isEmpty(point.node))) { 45979 return point; 45980 } 45981 // point on block's edge 45982 var block = dom.ancestor(point.node, dom.isBlock); 45983 if (((dom.isLeftEdgePointOf(point, block) || dom.isVoid(dom.prevPoint(point).node)) && !isLeftToRight) || 45984 ((dom.isRightEdgePointOf(point, block) || dom.isVoid(dom.nextPoint(point).node)) && isLeftToRight)) { 45985 // returns point already on visible point 45986 if (dom.isVisiblePoint(point)) { 45987 return point; 45988 } 45989 // reverse direction 45990 isLeftToRight = !isLeftToRight; 45991 } 45992 var nextPoint = isLeftToRight ? dom.nextPointUntil(dom.nextPoint(point), dom.isVisiblePoint) 45993 : dom.prevPointUntil(dom.prevPoint(point), dom.isVisiblePoint); 45994 return nextPoint || point; 45995 }; 45996 var endPoint = getVisiblePoint(this.getEndPoint(), false); 45997 var startPoint = this.isCollapsed() ? endPoint : getVisiblePoint(this.getStartPoint(), true); 45998 return new WrappedRange(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset); 45999 }; 46000 /** 46001 * returns matched nodes on range 46002 * 46003 * @param {Function} [pred] - predicate function 46004 * @param {Object} [options] 46005 * @param {Boolean} [options.includeAncestor] 46006 * @param {Boolean} [options.fullyContains] 46007 * @return {Node[]} 46008 */ 46009 WrappedRange.prototype.nodes = function (pred, options) { 46010 pred = pred || func.ok; 46011 var includeAncestor = options && options.includeAncestor; 46012 var fullyContains = options && options.fullyContains;
vendor: 16,698 bytes, lines 46013-46516
46013 // TODO compare points and sort 46014 var startPoint = this.getStartPoint(); 46015 var endPoint = this.getEndPoint(); 46016 var nodes = []; 46017 var leftEdgeNodes = []; 46018 dom.walkPoint(startPoint, endPoint, function (point) { 46019 if (dom.isEditable(point.node)) { 46020 return; 46021 } 46022 var node; 46023 if (fullyContains) { 46024 if (dom.isLeftEdgePoint(point)) { 46025 leftEdgeNodes.push(point.node); 46026 } 46027 if (dom.isRightEdgePoint(point) && lists.contains(leftEdgeNodes, point.node)) { 46028 node = point.node; 46029 } 46030 } 46031 else if (includeAncestor) { 46032 node = dom.ancestor(point.node, pred); 46033 } 46034 else { 46035 node = point.node; 46036 } 46037 if (node && pred(node)) { 46038 nodes.push(node); 46039 } 46040 }, true); 46041 return lists.unique(nodes); 46042 }; 46043 /** 46044 * returns commonAncestor of range 46045 * @return {Element} - commonAncestor 46046 */ 46047 WrappedRange.prototype.commonAncestor = function () { 46048 return dom.commonAncestor(this.sc, this.ec); 46049 }; 46050 /** 46051 * returns expanded range by pred 46052 * 46053 * @param {Function} pred - predicate function 46054 * @return {WrappedRange} 46055 */ 46056 WrappedRange.prototype.expand = function (pred) { 46057 var startAncestor = dom.ancestor(this.sc, pred); 46058 var endAncestor = dom.ancestor(this.ec, pred); 46059 if (!startAncestor && !endAncestor) { 46060 return new WrappedRange(this.sc, this.so, this.ec, this.eo); 46061 } 46062 var boundaryPoints = this.getPoints(); 46063 if (startAncestor) { 46064 boundaryPoints.sc = startAncestor; 46065 boundaryPoints.so = 0; 46066 } 46067 if (endAncestor) { 46068 boundaryPoints.ec = endAncestor; 46069 boundaryPoints.eo = dom.nodeLength(endAncestor); 46070 } 46071 return new WrappedRange(boundaryPoints.sc, boundaryPoints.so, boundaryPoints.ec, boundaryPoints.eo); 46072 }; 46073 /** 46074 * @param {Boolean} isCollapseToStart 46075 * @return {WrappedRange} 46076 */ 46077 WrappedRange.prototype.collapse = function (isCollapseToStart) { 46078 if (isCollapseToStart) { 46079 return new WrappedRange(this.sc, this.so, this.sc, this.so); 46080 } 46081 else { 46082 return new WrappedRange(this.ec, this.eo, this.ec, this.eo); 46083 } 46084 }; 46085 /** 46086 * splitText on range 46087 */ 46088 WrappedRange.prototype.splitText = function () { 46089 var isSameContainer = this.sc === this.ec; 46090 var boundaryPoints = this.getPoints(); 46091 if (dom.isText(this.ec) && !dom.isEdgePoint(this.getEndPoint())) { 46092 this.ec.splitText(this.eo); 46093 } 46094 if (dom.isText(this.sc) && !dom.isEdgePoint(this.getStartPoint())) { 46095 boundaryPoints.sc = this.sc.splitText(this.so); 46096 boundaryPoints.so = 0; 46097 if (isSameContainer) { 46098 boundaryPoints.ec = boundaryPoints.sc; 46099 boundaryPoints.eo = this.eo - this.so; 46100 } 46101 } 46102 return new WrappedRange(boundaryPoints.sc, boundaryPoints.so, boundaryPoints.ec, boundaryPoints.eo); 46103 }; 46104 /** 46105 * delete contents on range 46106 * @return {WrappedRange} 46107 */ 46108 WrappedRange.prototype.deleteContents = function () { 46109 if (this.isCollapsed()) { 46110 return this; 46111 } 46112 var rng = this.splitText(); 46113 var nodes = rng.nodes(null, { 46114 fullyContains: true 46115 }); 46116 // find new cursor point 46117 var point = dom.prevPointUntil(rng.getStartPoint(), function (point) { 46118 return !lists.contains(nodes, point.node); 46119 }); 46120 var emptyParents = []; 46121 $$1.each(nodes, function (idx, node) { 46122 // find empty parents 46123 var parent = node.parentNode; 46124 if (point.node !== parent && dom.nodeLength(parent) === 1) { 46125 emptyParents.push(parent); 46126 } 46127 dom.remove(node, false); 46128 }); 46129 // remove empty parents 46130 $$1.each(emptyParents, function (idx, node) { 46131 dom.remove(node, false); 46132 }); 46133 return new WrappedRange(point.node, point.offset, point.node, point.offset).normalize(); 46134 }; 46135 /** 46136 * makeIsOn: return isOn(pred) function 46137 */ 46138 WrappedRange.prototype.makeIsOn = function (pred) { 46139 return function () { 46140 var ancestor = dom.ancestor(this.sc, pred); 46141 return !!ancestor && (ancestor === dom.ancestor(this.ec, pred)); 46142 }; 46143 }; 46144 /** 46145 * @param {Function} pred 46146 * @return {Boolean} 46147 */ 46148 WrappedRange.prototype.isLeftEdgeOf = function (pred) { 46149 if (!dom.isLeftEdgePoint(this.getStartPoint())) { 46150 return false; 46151 } 46152 var node = dom.ancestor(this.sc, pred); 46153 return node && dom.isLeftEdgeOf(this.sc, node); 46154 }; 46155 /** 46156 * returns whether range was collapsed or not 46157 */ 46158 WrappedRange.prototype.isCollapsed = function () { 46159 return this.sc === this.ec && this.so === this.eo; 46160 }; 46161 /** 46162 * wrap inline nodes which children of body with paragraph 46163 * 46164 * @return {WrappedRange} 46165 */ 46166 WrappedRange.prototype.wrapBodyInlineWithPara = function () { 46167 if (dom.isBodyContainer(this.sc) && dom.isEmpty(this.sc)) { 46168 this.sc.innerHTML = dom.emptyPara; 46169 return new WrappedRange(this.sc.firstChild, 0, this.sc.firstChild, 0); 46170 } 46171 /** 46172 * [workaround] firefox often create range on not visible point. so normalize here. 46173 * - firefox: |<p>text</p>| 46174 * - chrome: <p>|text|</p> 46175 */ 46176 var rng = this.normalize(); 46177 if (dom.isParaInline(this.sc) || dom.isPara(this.sc)) { 46178 return rng; 46179 } 46180 // find inline top ancestor 46181 var topAncestor; 46182 if (dom.isInline(rng.sc)) { 46183 var ancestors = dom.listAncestor(rng.sc, func.not(dom.isInline)); 46184 topAncestor = lists.last(ancestors); 46185 if (!dom.isInline(topAncestor)) { 46186 topAncestor = ancestors[ancestors.length - 2] || rng.sc.childNodes[rng.so]; 46187 } 46188 } 46189 else { 46190 topAncestor = rng.sc.childNodes[rng.so > 0 ? rng.so - 1 : 0]; 46191 } 46192 // siblings not in paragraph 46193 var inlineSiblings = dom.listPrev(topAncestor, dom.isParaInline).reverse(); 46194 inlineSiblings = inlineSiblings.concat(dom.listNext(topAncestor.nextSibling, dom.isParaInline)); 46195 // wrap with paragraph 46196 if (inlineSiblings.length) { 46197 var para = dom.wrap(lists.head(inlineSiblings), 'p'); 46198 dom.appendChildNodes(para, lists.tail(inlineSiblings)); 46199 } 46200 return this.normalize(); 46201 }; 46202 /** 46203 * insert node at current cursor 46204 * 46205 * @param {Node} node 46206 * @return {Node} 46207 */ 46208 WrappedRange.prototype.insertNode = function (node) { 46209 var rng = this.wrapBodyInlineWithPara().deleteContents(); 46210 var info = dom.splitPoint(rng.getStartPoint(), dom.isInline(node)); 46211 if (info.rightNode) { 46212 info.rightNode.parentNode.insertBefore(node, info.rightNode); 46213 } 46214 else { 46215 info.container.appendChild(node); 46216 } 46217 return node; 46218 }; 46219 /** 46220 * insert html at current cursor 46221 */ 46222 WrappedRange.prototype.pasteHTML = function (markup) { 46223 var contentsContainer = $$1('<div></div>').html(markup)[0]; 46224 var childNodes = lists.from(contentsContainer.childNodes); 46225 var rng = this.wrapBodyInlineWithPara().deleteContents(); 46226 return childNodes.reverse().map(function (childNode) { 46227 return rng.insertNode(childNode); 46228 }).reverse(); 46229 }; 46230 /** 46231 * returns text in range 46232 * 46233 * @return {String} 46234 */ 46235 WrappedRange.prototype.toString = function () { 46236 var nativeRng = this.nativeRange(); 46237 return env.isW3CRangeSupport ? nativeRng.toString() : nativeRng.text; 46238 }; 46239 /** 46240 * returns range for word before cursor 46241 * 46242 * @param {Boolean} [findAfter] - find after cursor, default: false 46243 * @return {WrappedRange} 46244 */ 46245 WrappedRange.prototype.getWordRange = function (findAfter) { 46246 var endPoint = this.getEndPoint(); 46247 if (!dom.isCharPoint(endPoint)) { 46248 return this; 46249 } 46250 var startPoint = dom.prevPointUntil(endPoint, function (point) { 46251 return !dom.isCharPoint(point); 46252 }); 46253 if (findAfter) { 46254 endPoint = dom.nextPointUntil(endPoint, function (point) { 46255 return !dom.isCharPoint(point); 46256 }); 46257 } 46258 return new WrappedRange(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset); 46259 }; 46260 /** 46261 * create offsetPath bookmark 46262 * 46263 * @param {Node} editable 46264 */ 46265 WrappedRange.prototype.bookmark = function (editable) { 46266 return { 46267 s: { 46268 path: dom.makeOffsetPath(editable, this.sc), 46269 offset: this.so 46270 }, 46271 e: { 46272 path: dom.makeOffsetPath(editable, this.ec), 46273 offset: this.eo 46274 } 46275 }; 46276 }; 46277 /** 46278 * create offsetPath bookmark base on paragraph 46279 * 46280 * @param {Node[]} paras 46281 */ 46282 WrappedRange.prototype.paraBookmark = function (paras) { 46283 return { 46284 s: { 46285 path: lists.tail(dom.makeOffsetPath(lists.head(paras), this.sc)), 46286 offset: this.so 46287 }, 46288 e: { 46289 path: lists.tail(dom.makeOffsetPath(lists.last(paras), this.ec)), 46290 offset: this.eo 46291 } 46292 }; 46293 }; 46294 /** 46295 * getClientRects 46296 * @return {Rect[]} 46297 */ 46298 WrappedRange.prototype.getClientRects = function () { 46299 var nativeRng = this.nativeRange(); 46300 return nativeRng.getClientRects(); 46301 }; 46302 return WrappedRange; 46303}()); 46304/** 46305 * Data structure 46306 * * BoundaryPoint: a point of dom tree 46307 * * BoundaryPoints: two boundaryPoints corresponding to the start and the end of the Range 46308 * 46309 * See to http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position 46310 */ 46311var range = { 46312 /** 46313 * create Range Object From arguments or Browser Selection 46314 * 46315 * @param {Node} sc - start container 46316 * @param {Number} so - start offset 46317 * @param {Node} ec - end container 46318 * @param {Number} eo - end offset 46319 * @return {WrappedRange} 46320 */ 46321 create: function (sc, so, ec, eo) { 46322 if (arguments.length === 4) { 46323 return new WrappedRange(sc, so, ec, eo); 46324 } 46325 else if (arguments.length === 2) { 46326 ec = sc; 46327 eo = so; 46328 return new WrappedRange(sc, so, ec, eo); 46329 } 46330 else { 46331 var wrappedRange = this.createFromSelection(); 46332 if (!wrappedRange && arguments.length === 1) { 46333 wrappedRange = this.createFromNode(arguments[0]); 46334 return wrappedRange.collapse(dom.emptyPara === arguments[0].innerHTML); 46335 } 46336 return wrappedRange; 46337 } 46338 }, 46339 createFromSelection: function () { 46340 var sc, so, ec, eo; 46341 if (env.isW3CRangeSupport) { 46342 var selection = document.getSelection(); 46343 if (!selection || selection.rangeCount === 0) { 46344 return null; 46345 } 46346 else if (dom.isBody(selection.anchorNode)) { 46347 // Firefox: returns entire body as range on initialization. 46348 // We won't never need it. 46349 return null; 46350 } 46351 var nativeRng = selection.getRangeAt(0); 46352 sc = nativeRng.startContainer; 46353 so = nativeRng.startOffset; 46354 ec = nativeRng.endContainer; 46355 eo = nativeRng.endOffset; 46356 } 46357 else { 46358 var textRange = document.selection.createRange(); 46359 var textRangeEnd = textRange.duplicate(); 46360 textRangeEnd.collapse(false); 46361 var textRangeStart = textRange; 46362 textRangeStart.collapse(true); 46363 var startPoint = textRangeToPoint(textRangeStart, true); 46364 var endPoint = textRangeToPoint(textRangeEnd, false); 46365 // same visible point case: range was collapsed. 46366 if (dom.isText(startPoint.node) && dom.isLeftEdgePoint(startPoint) && 46367 dom.isTextNode(endPoint.node) && dom.isRightEdgePoint(endPoint) && 46368 endPoint.node.nextSibling === startPoint.node) { 46369 startPoint = endPoint; 46370 } 46371 sc = startPoint.cont; 46372 so = startPoint.offset; 46373 ec = endPoint.cont; 46374 eo = endPoint.offset; 46375 } 46376 return new WrappedRange(sc, so, ec, eo); 46377 }, 46378 /** 46379 * @method 46380 * 46381 * create WrappedRange from node 46382 * 46383 * @param {Node} node 46384 * @return {WrappedRange} 46385 */ 46386 createFromNode: function (node) { 46387 var sc = node; 46388 var so = 0; 46389 var ec = node; 46390 var eo = dom.nodeLength(ec); 46391 // browsers can't target a picture or void node 46392 if (dom.isVoid(sc)) { 46393 so = dom.listPrev(sc).length - 1; 46394 sc = sc.parentNode; 46395 } 46396 if (dom.isBR(ec)) { 46397 eo = dom.listPrev(ec).length - 1; 46398 ec = ec.parentNode; 46399 } 46400 else if (dom.isVoid(ec)) { 46401 eo = dom.listPrev(ec).length; 46402 ec = ec.parentNode; 46403 } 46404 return this.create(sc, so, ec, eo); 46405 }, 46406 /** 46407 * create WrappedRange from node after position 46408 * 46409 * @param {Node} node 46410 * @return {WrappedRange} 46411 */ 46412 createFromNodeBefore: function (node) { 46413 return this.createFromNode(node).collapse(true); 46414 }, 46415 /** 46416 * create WrappedRange from node after position 46417 * 46418 * @param {Node} node 46419 * @return {WrappedRange} 46420 */ 46421 createFromNodeAfter: function (node) { 46422 return this.createFromNode(node).collapse(); 46423 }, 46424 /** 46425 * @method 46426 * 46427 * create WrappedRange from bookmark 46428 * 46429 * @param {Node} editable 46430 * @param {Object} bookmark 46431 * @return {WrappedRange} 46432 */ 46433 createFromBookmark: function (editable, bookmark) { 46434 var sc = dom.fromOffsetPath(editable, bookmark.s.path); 46435 var so = bookmark.s.offset; 46436 var ec = dom.fromOffsetPath(editable, bookmark.e.path); 46437 var eo = bookmark.e.offset; 46438 return new WrappedRange(sc, so, ec, eo); 46439 }, 46440 /** 46441 * @method 46442 * 46443 * create WrappedRange from paraBookmark 46444 * 46445 * @param {Object} bookmark 46446 * @param {Node[]} paras 46447 * @return {WrappedRange} 46448 */ 46449 createFromParaBookmark: function (bookmark, paras) { 46450 var so = bookmark.s.offset; 46451 var eo = bookmark.e.offset; 46452 var sc = dom.fromOffsetPath(lists.head(paras), bookmark.s.path); 46453 var ec = dom.fromOffsetPath(lists.last(paras), bookmark.e.path); 46454 return new WrappedRange(sc, so, ec, eo); 46455 } 46456}; 46457 46458/** 46459 * @method readFileAsDataURL 46460 * 46461 * read contents of file as representing URL 46462 * 46463 * @param {File} file 46464 * @return {Promise} - then: dataUrl 46465 */ 46466function readFileAsDataURL(file) { 46467 return $$1.Deferred(function (deferred) { 46468 $$1.extend(new FileReader(), { 46469 onload: function (e) { 46470 var dataURL = e.target.result; 46471 deferred.resolve(dataURL); 46472 }, 46473 onerror: function (err) { 46474 deferred.reject(err); 46475 } 46476 }).readAsDataURL(file); 46477 }).promise(); 46478} 46479/** 46480 * @method createImage 46481 * 46482 * create `<image>` from url string 46483 * 46484 * @param {String} url 46485 * @return {Promise} - then: $image 46486 */ 46487function createImage(url) { 46488 return $$1.Deferred(function (deferred) { 46489 var $img = $$1('<img>'); 46490 $img.one('load', function () { 46491 $img.off('error abort'); 46492 deferred.resolve($img); 46493 }).one('error abort', function () { 46494 $img.off('load').detach(); 46495 deferred.reject($img); 46496 }).css({ 46497 display: 'none' 46498 }).appendTo(document.body).attr('src', url); 46499 }).promise(); 46500} 46501 46502var History = /** @class */ (function () { 46503 function History($editable) { 46504 this.stack = []; 46505 this.stackOffset = -1; 46506 this.$editable = $editable; 46507 this.editable = $editable[0]; 46508 } 46509 History.prototype.makeSnapshot = function () { 46510 var rng = range.create(this.editable); 46511 var emptyBookmark = { s: { path: [], offset: 0 }, e: { path: [], offset: 0 } }; 46512 return { 46513 contents: this.$editable.html(), 46514 bookmark: (rng ? rng.bookmark(this.editable) : emptyBookmark) 46515 }; 46516 };
46517 History.prototype.applySnapshot = function (snapshot) { 46518 if (snapshot.contents !== null) { 46519 this.$editable.html(snapshot.contents); 46520 } 46521 if (snapshot.bookmark !== null) { 46522 range.createFromBookmark(this.editable, snapshot.bookmark).select(); 46523 } 46524 }; 46525 /** 46526 * @method rewind 46527 * Rewinds the history stack back to the first snapshot taken. 46528 * Leaves the stack intact, so that "Redo" can still be used. 46529 */ 46530 History.prototype.rewind = function () { 46531 // Create snap shot if not yet recorded 46532 if (this.$editable.html() !== this.stack[this.stackOffset].contents) { 46533 this.recordUndo(); 46534 } 46535 // Return to the first available snapshot. 46536 this.stackOffset = 0; 46537 // Apply that snapshot. 46538 this.applySnapshot(this.stack[this.stackOffset]); 46539 }; 46540 /** 46541 * @method reset 46542 * Resets the history stack completely; reverting to an empty editor. 46543 */ 46544 History.prototype.reset = function () { 46545 // Clear the stack. 46546 this.stack = []; 46547 // Restore stackOffset to its original value. 46548 this.stackOffset = -1; 46549 // Clear the editable area. 46550 this.$editable.html(''); 46551 // Record our first snapshot (of nothing). 46552 this.recordUndo(); 46553 }; 46554 /** 46555 * undo 46556 */ 46557 History.prototype.undo = function () { 46558 // Create snap shot if not yet recorded 46559 if (this.$editable.html() !== this.stack[this.stackOffset].contents) { 46560 this.recordUndo(); 46561 } 46562 if (this.stackOffset > 0) { 46563 this.stackOffset--; 46564 this.applySnapshot(this.stack[this.stackOffset]); 46565 } 46566 }; 46567 /** 46568 * redo 46569 */ 46570 History.prototype.redo = function () { 46571 if (this.stack.length - 1 > this.stackOffset) { 46572 this.stackOffset++; 46573 this.applySnapshot(this.stack[this.stackOffset]); 46574 } 46575 }; 46576 /** 46577 * recorded undo 46578 */ 46579 History.prototype.recordUndo = function () { 46580 this.stackOffset++; 46581 // Wash out stack after stackOffset 46582 if (this.stack.length > this.stackOffset) { 46583 this.stack = this.stack.slice(0, this.stackOffset); 46584 } 46585 // Create new snapshot and push it to the end 46586 this.stack.push(this.makeSnapshot()); 46587 }; 46588 return History; 46589}()); 46590 46591var Style = /** @class */ (function () { 46592 function Style() { 46593 } 46594 /** 46595 * @method jQueryCSS 46596 * 46597 * [workaround] for old jQuery 46598 * passing an array of style properties to .css() 46599 * will result in an object of property-value pairs. 46600 * (compability with version < 1.9) 46601 * 46602 * @private 46603 * @param {jQuery} $obj 46604 * @param {Array} propertyNames - An array of one or more CSS properties. 46605 * @return {Object} 46606 */ 46607 Style.prototype.jQueryCSS = function ($obj, propertyNames) { 46608 if (env.jqueryVersion < 1.9) { 46609 var result_1 = {}; 46610 $$1.each(propertyNames, function (idx, propertyName) { 46611 result_1[propertyName] = $obj.css(propertyName); 46612 }); 46613 return result_1; 46614 } 46615 return $obj.css(propertyNames); 46616 }; 46617 /** 46618 * returns style object from node 46619 * 46620 * @param {jQuery} $node 46621 * @return {Object} 46622 */ 46623 Style.prototype.fromNode = function ($node) { 46624 var properties = ['font-family', 'font-size', 'text-align', 'list-style-type', 'line-height']; 46625 var styleInfo = this.jQueryCSS($node, properties) || {}; 46626 styleInfo['font-size'] = parseInt(styleInfo['font-size'], 10); 46627 return styleInfo; 46628 }; 46629 /** 46630 * paragraph level style 46631 * 46632 * @param {WrappedRange} rng 46633 * @param {Object} styleInfo 46634 */ 46635 Style.prototype.stylePara = function (rng, styleInfo) {
vendor: 4,147 bytes, lines 46636-46728
46636 $$1.each(rng.nodes(dom.isPara, { 46637 includeAncestor: true 46638 }), function (idx, para) { 46639 $$1(para).css(styleInfo); 46640 }); 46641 }; 46642 /** 46643 * insert and returns styleNodes on range. 46644 * 46645 * @param {WrappedRange} rng 46646 * @param {Object} [options] - options for styleNodes 46647 * @param {String} [options.nodeName] - default: `SPAN` 46648 * @param {Boolean} [options.expandClosestSibling] - default: `false` 46649 * @param {Boolean} [options.onlyPartialContains] - default: `false` 46650 * @return {Node[]} 46651 */ 46652 Style.prototype.styleNodes = function (rng, options) { 46653 rng = rng.splitText(); 46654 var nodeName = (options && options.nodeName) || 'SPAN'; 46655 var expandClosestSibling = !!(options && options.expandClosestSibling); 46656 var onlyPartialContains = !!(options && options.onlyPartialContains); 46657 if (rng.isCollapsed()) { 46658 return [rng.insertNode(dom.create(nodeName))]; 46659 } 46660 var pred = dom.makePredByNodeName(nodeName); 46661 var nodes = rng.nodes(dom.isText, { 46662 fullyContains: true 46663 }).map(function (text) { 46664 return dom.singleChildAncestor(text, pred) || dom.wrap(text, nodeName); 46665 }); 46666 if (expandClosestSibling) { 46667 if (onlyPartialContains) { 46668 var nodesInRange_1 = rng.nodes(); 46669 // compose with partial contains predication 46670 pred = func.and(pred, function (node) { 46671 return lists.contains(nodesInRange_1, node); 46672 }); 46673 } 46674 return nodes.map(function (node) { 46675 var siblings = dom.withClosestSiblings(node, pred); 46676 var head = lists.head(siblings); 46677 var tails = lists.tail(siblings); 46678 $$1.each(tails, function (idx, elem) { 46679 dom.appendChildNodes(head, elem.childNodes); 46680 dom.remove(elem); 46681 }); 46682 return lists.head(siblings); 46683 }); 46684 } 46685 else { 46686 return nodes; 46687 } 46688 }; 46689 /** 46690 * get current style on cursor 46691 * 46692 * @param {WrappedRange} rng 46693 * @return {Object} - object contains style properties. 46694 */ 46695 Style.prototype.current = function (rng) { 46696 var $cont = $$1(!dom.isElement(rng.sc) ? rng.sc.parentNode : rng.sc); 46697 var styleInfo = this.fromNode($cont); 46698 // document.queryCommandState for toggle state 46699 // [workaround] prevent Firefox nsresult: "0x80004005 (NS_ERROR_FAILURE)" 46700 try { 46701 styleInfo = $$1.extend(styleInfo, { 46702 'font-bold': document.queryCommandState('bold') ? 'bold' : 'normal', 46703 'font-italic': document.queryCommandState('italic') ? 'italic' : 'normal', 46704 'font-underline': document.queryCommandState('underline') ? 'underline' : 'normal', 46705 'font-subscript': document.queryCommandState('subscript') ? 'subscript' : 'normal', 46706 'font-superscript': document.queryCommandState('superscript') ? 'superscript' : 'normal', 46707 'font-strikethrough': document.queryCommandState('strikethrough') ? 'strikethrough' : 'normal', 46708 'font-family': document.queryCommandValue('fontname') || styleInfo['font-family'] 46709 }); 46710 } 46711 catch (e) { } 46712 // list-style-type to list-style(unordered, ordered) 46713 if (!rng.isOnList()) { 46714 styleInfo['list-style'] = 'none'; 46715 } 46716 else { 46717 var orderedTypes = ['circle', 'disc', 'disc-leading-zero', 'square']; 46718 var isUnordered = $$1.inArray(styleInfo['list-style-type'], orderedTypes) > -1; 46719 styleInfo['list-style'] = isUnordered ? 'unordered' : 'ordered'; 46720 } 46721 var para = dom.ancestor(rng.sc, dom.isPara); 46722 if (para && para.style['line-height']) { 46723 styleInfo['line-height'] = para.style.lineHeight; 46724 } 46725 else { 46726 var lineHeight = parseInt(styleInfo['line-height'], 10) / parseInt(styleInfo['font-size'], 10); 46727 styleInfo['line-height'] = lineHeight.toFixed(1); 46728 }
46729 styleInfo.anchor = rng.isOnAnchor() && dom.ancestor(rng.sc, dom.isAnchor); 46730 styleInfo.ancestors = dom.listAncestor(rng.sc, dom.isEditable); 46731 styleInfo.range = rng; 46732 return styleInfo; 46733 }; 46734 return Style; 46735}()); 46736 46737var Bullet = /** @class */ (function () { 46738 function Bullet() { 46739 } 46740 /** 46741 * toggle ordered list 46742 */ 46743 Bullet.prototype.insertOrderedList = function (editable) { 46744 this.toggleList('OL', editable); 46745 }; 46746 /** 46747 * toggle unordered list 46748 */ 46749 Bullet.prototype.insertUnorderedList = function (editable) { 46750 this.toggleList('UL', editable); 46751 }; 46752 /** 46753 * indent 46754 */ 46755 Bullet.prototype.indent = function (editable) { 46756 var _this = this; 46757 var rng = range.create(editable).wrapBodyInlineWithPara(); 46758 var paras = rng.nodes(dom.isPara, { includeAncestor: true }); 46759 var clustereds = lists.clusterBy(paras, func.peq2('parentNode')); 46760 $$1.each(clustereds, function (idx, paras) { 46761 var head = lists.head(paras); 46762 if (dom.isLi(head)) { 46763 _this.wrapList(paras, head.parentNode.nodeName); 46764 } 46765 else { 46766 $$1.each(paras, function (idx, para) { 46767 $$1(para).css('marginLeft', function (idx, val) { 46768 return (parseInt(val, 10) || 0) + 25; 46769 }); 46770 }); 46771 } 46772 }); 46773 rng.select(); 46774 }; 46775 /** 46776 * outdent 46777 */ 46778 Bullet.prototype.outdent = function (editable) { 46779 var _this = this; 46780 var rng = range.create(editable).wrapBodyInlineWithPara(); 46781 var paras = rng.nodes(dom.isPara, { includeAncestor: true }); 46782 var clustereds = lists.clusterBy(paras, func.peq2('parentNode')); 46783 $$1.each(clustereds, function (idx, paras) { 46784 var head = lists.head(paras); 46785 if (dom.isLi(head)) { 46786 _this.releaseList([paras]); 46787 } 46788 else { 46789 $$1.each(paras, function (idx, para) { 46790 $$1(para).css('marginLeft', function (idx, val) { 46791 val = (parseInt(val, 10) || 0); 46792 return val > 25 ? val - 25 : ''; 46793 }); 46794 }); 46795 } 46796 }); 46797 rng.select(); 46798 }; 46799 /** 46800 * toggle list 46801 * 46802 * @param {String} listName - OL or UL 46803 */ 46804 Bullet.prototype.toggleList = function (listName, editable) { 46805 var _this = this; 46806 var rng = range.create(editable).wrapBodyInlineWithPara(); 46807 var paras = rng.nodes(dom.isPara, { includeAncestor: true }); 46808 var bookmark = rng.paraBookmark(paras); 46809 var clustereds = lists.clusterBy(paras, func.peq2('parentNode')); 46810 // paragraph to list 46811 if (lists.find(paras, dom.isPurePara)) { 46812 var wrappedParas_1 = []; 46813 $$1.each(clustereds, function (idx, paras) { 46814 wrappedParas_1 = wrappedParas_1.concat(_this.wrapList(paras, listName)); 46815 }); 46816 paras = wrappedParas_1; 46817 // list to paragraph or change list style 46818 } 46819 else { 46820 var diffLists = rng.nodes(dom.isList, { 46821 includeAncestor: true 46822 }).filter(function (listNode) { 46823 return !$$1.nodeName(listNode, listName); 46824 }); 46825 if (diffLists.length) { 46826 $$1.each(diffLists, function (idx, listNode) { 46827 dom.replace(listNode, listName); 46828 }); 46829 } 46830 else { 46831 paras = this.releaseList(clustereds, true); 46832 } 46833 } 46834 range.createFromParaBookmark(bookmark, paras).select(); 46835 }; 46836 /** 46837 * @param {Node[]} paras 46838 * @param {String} listName 46839 * @return {Node[]} 46840 */ 46841 Bullet.prototype.wrapList = function (paras, listName) { 46842 var head = lists.head(paras); 46843 var last = lists.last(paras); 46844 var prevList = dom.isList(head.previousSibling) && head.previousSibling; 46845 var nextList = dom.isList(last.nextSibling) && last.nextSibling;
46846 var listNode = prevList || dom.insertAfter(dom.create(listName || 'UL'), last); 46847 // P to LI 46848 paras = paras.map(function (para) { 46849 return dom.isPurePara(para) ? dom.replace(para, 'LI') : para; 46850 }); 46851 // append to list(<ul>, <ol>) 46852 dom.appendChildNodes(listNode, paras); 46853 if (nextList) { 46854 dom.appendChildNodes(listNode, lists.from(nextList.childNodes)); 46855 dom.remove(nextList); 46856 } 46857 return paras; 46858 }; 46859 /** 46860 * @method releaseList 46861 * 46862 * @param {Array[]} clustereds 46863 * @param {Boolean} isEscapseToBody 46864 * @return {Node[]} 46865 */ 46866 Bullet.prototype.releaseList = function (clustereds, isEscapseToBody) { 46867 var releasedParas = []; 46868 $$1.each(clustereds, function (idx, paras) { 46869 var head = lists.head(paras); 46870 var last = lists.last(paras); 46871 var headList = isEscapseToBody ? dom.lastAncestor(head, dom.isList) : head.parentNode; 46872 var lastList = headList.childNodes.length > 1 ? dom.splitTree(headList, { 46873 node: last.parentNode, 46874 offset: dom.position(last) + 1 46875 }, { 46876 isSkipPaddingBlankHTML: true 46877 }) : null; 46878 var middleList = dom.splitTree(headList, { 46879 node: head.parentNode, 46880 offset: dom.position(head) 46881 }, { 46882 isSkipPaddingBlankHTML: true 46883 }); 46884 paras = isEscapseToBody ? dom.listDescendant(middleList, dom.isLi) 46885 : lists.from(middleList.childNodes).filter(dom.isLi); 46886 // LI to P 46887 if (isEscapseToBody || !dom.isList(headList.parentNode)) { 46888 paras = paras.map(function (para) { 46889 return dom.replace(para, 'P'); 46890 }); 46891 } 46892 $$1.each(lists.from(paras).reverse(), function (idx, para) { 46893 dom.insertAfter(para, headList); 46894 }); 46895 // remove empty lists 46896 var rootLists = lists.compact([headList, middleList, lastList]); 46897 $$1.each(rootLists, function (idx, rootList) { 46898 var listNodes = [rootList].concat(dom.listDescendant(rootList, dom.isList)); 46899 $$1.each(listNodes.reverse(), function (idx, listNode) { 46900 if (!dom.nodeLength(listNode)) { 46901 dom.remove(listNode, true); 46902 } 46903 }); 46904 }); 46905 releasedParas = releasedParas.concat(paras); 46906 }); 46907 return releasedParas; 46908 }; 46909 return Bullet; 46910}()); 46911 46912/** 46913 * @class editing.Typing 46914 * 46915 * Typing 46916 * 46917 */ 46918var Typing = /** @class */ (function () { 46919 function Typing() { 46920 // a Bullet instance to toggle lists off 46921 this.bullet = new Bullet(); 46922 } 46923 /** 46924 * insert tab 46925 * 46926 * @param {WrappedRange} rng 46927 * @param {Number} tabsize 46928 */ 46929 Typing.prototype.insertTab = function (rng, tabsize) { 46930 var tab = dom.createText(new Array(tabsize + 1).join(dom.NBSP_CHAR)); 46931 rng = rng.deleteContents(); 46932 rng.insertNode(tab, true); 46933 rng = range.create(tab, tabsize); 46934 rng.select(); 46935 }; 46936 /** 46937 * insert paragraph 46938 */ 46939 Typing.prototype.insertParagraph = function (editable) { 46940 var rng = range.create(editable); 46941 // deleteContents on range. 46942 rng = rng.deleteContents(); 46943 // Wrap range if it needs to be wrapped by paragraph 46944 rng = rng.wrapBodyInlineWithPara(); 46945 // finding paragraph 46946 var splitRoot = dom.ancestor(rng.sc, dom.isPara); 46947 var nextPara; 46948 // on paragraph: split paragraph 46949 if (splitRoot) { 46950 // if it is an empty line with li 46951 if (dom.isEmpty(splitRoot) && dom.isLi(splitRoot)) { 46952 // toogle UL/OL and escape 46953 this.bullet.toggleList(splitRoot.parentNode.nodeName); 46954 return; 46955 // if it is an empty line with para on blockquote 46956 } 46957 else if (dom.isEmpty(splitRoot) && dom.isPara(splitRoot) && dom.isBlockquote(splitRoot.parentNode)) { 46958 // escape blockquote 46959 dom.insertAfter(splitRoot, splitRoot.parentNode); 46960 nextPara = splitRoot; 46961 // if new line has content (not a line break) 46962 } 46963 else { 46964 nextPara = dom.splitTree(splitRoot, rng.getStartPoint()); 46965 var emptyAnchors = dom.listDescendant(splitRoot, dom.isEmptyAnchor); 46966 emptyAnchors = emptyAnchors.concat(dom.listDescendant(nextPara, dom.isEmptyAnchor)); 46967 $$1.each(emptyAnchors, function (idx, anchor) { 46968 dom.remove(anchor); 46969 }); 46970 // replace empty heading, pre or custom-made styleTag with P tag 46971 if ((dom.isHeading(nextPara) || dom.isPre(nextPara) || dom.isCustomStyleTag(nextPara)) && dom.isEmpty(nextPara)) { 46972 nextPara = dom.replace(nextPara, 'p'); 46973 } 46974 }
46975 // no paragraph: insert empty paragraph 46976 } 46977 else { 46978 var next = rng.sc.childNodes[rng.so]; 46979 nextPara = $$1(dom.emptyPara)[0]; 46980 if (next) { 46981 rng.sc.insertBefore(nextPara, next); 46982 } 46983 else { 46984 rng.sc.appendChild(nextPara); 46985 } 46986 } 46987 range.create(nextPara, 0).normalize().select().scrollIntoView(editable); 46988 }; 46989 return Typing; 46990}()); 46991 46992/** 46993 * @class Create a virtual table to create what actions to do in change. 46994 * @param {object} startPoint Cell selected to apply change. 46995 * @param {enum} where Where change will be applied Row or Col. Use enum: TableResultAction.where 46996 * @param {enum} action Action to be applied. Use enum: TableResultAction.requestAction 46997 * @param {object} domTable Dom element of table to make changes. 46998 */ 46999var TableResultAction = function (startPoint, where, action, domTable) { 47000 var _startPoint = { 'colPos': 0, 'rowPos': 0 }; 47001 var _virtualTable = []; 47002 var _actionCellList = []; 47003 /// /////////////////////////////////////////// 47004 // Private functions 47005 /// /////////////////////////////////////////// 47006 /** 47007 * Set the startPoint of action. 47008 */ 47009 function setStartPoint() { 47010 if (!startPoint || !startPoint.tagName || (startPoint.tagName.toLowerCase() !== 'td' && startPoint.tagName.toLowerCase() !== 'th')) { 47011 console.error('Impossible to identify start Cell point.', startPoint); 47012 return; 47013 } 47014 _startPoint.colPos = startPoint.cellIndex; 47015 if (!startPoint.parentElement || !startPoint.parentElement.tagName || startPoint.parentElement.tagName.toLowerCase() !== 'tr') { 47016 console.error('Impossible to identify start Row point.', startPoint); 47017 return; 47018 } 47019 _startPoint.rowPos = startPoint.parentElement.rowIndex; 47020 } 47021 /** 47022 * Define virtual table position info object. 47023 * 47024 * @param {int} rowIndex Index position in line of virtual table. 47025 * @param {int} cellIndex Index position in column of virtual table. 47026 * @param {object} baseRow Row affected by this position. 47027 * @param {object} baseCell Cell affected by this position. 47028 * @param {bool} isSpan Inform if it is an span cell/row. 47029 */ 47030 function setVirtualTablePosition(rowIndex, cellIndex, baseRow, baseCell, isRowSpan, isColSpan, isVirtualCell) { 47031 var objPosition = { 47032 'baseRow': baseRow, 47033 'baseCell': baseCell, 47034 'isRowSpan': isRowSpan, 47035 'isColSpan': isColSpan, 47036 'isVirtual': isVirtualCell 47037 }; 47038 if (!_virtualTable[rowIndex]) { 47039 _virtualTable[rowIndex] = []; 47040 } 47041 _virtualTable[rowIndex][cellIndex] = objPosition; 47042 } 47043 /** 47044 * Create action cell object. 47045 * 47046 * @param {object} virtualTableCellObj Object of specific position on virtual table. 47047 * @param {enum} resultAction Action to be applied in that item. 47048 */ 47049 function getActionCell(virtualTableCellObj, resultAction, virtualRowPosition, virtualColPosition) { 47050 return { 47051 'baseCell': virtualTableCellObj.baseCell, 47052 'action': resultAction, 47053 'virtualTable': { 47054 'rowIndex': virtualRowPosition, 47055 'cellIndex': virtualColPosition 47056 } 47057 }; 47058 } 47059 /** 47060 * Recover free index of row to append Cell. 47061 * 47062 * @param {int} rowIndex Index of row to find free space. 47063 * @param {int} cellIndex Index of cell to find free space in table. 47064 */ 47065 function recoverCellIndex(rowIndex, cellIndex) { 47066 if (!_virtualTable[rowIndex]) { 47067 return cellIndex; 47068 } 47069 if (!_virtualTable[rowIndex][cellIndex]) { 47070 return cellIndex; 47071 } 47072 var newCellIndex = cellIndex; 47073 while (_virtualTable[rowIndex][newCellIndex]) { 47074 newCellIndex++; 47075 if (!_virtualTable[rowIndex][newCellIndex]) { 47076 return newCellIndex; 47077 } 47078 } 47079 } 47080 /** 47081 * Recover info about row and cell and add information to virtual table. 47082 * 47083 * @param {object} row Row to recover information. 47084 * @param {object}
vendor: 4,253 bytes, lines 47084-47184
47084 cell Cell to recover information. 47085 */ 47086 function addCellInfoToVirtual(row, cell) { 47087 var cellIndex = recoverCellIndex(row.rowIndex, cell.cellIndex); 47088 var cellHasColspan = (cell.colSpan > 1); 47089 var cellHasRowspan = (cell.rowSpan > 1); 47090 var isThisSelectedCell = (row.rowIndex === _startPoint.rowPos && cell.cellIndex === _startPoint.colPos); 47091 setVirtualTablePosition(row.rowIndex, cellIndex, row, cell, cellHasRowspan, cellHasColspan, false); 47092 // Add span rows to virtual Table. 47093 var rowspanNumber = cell.attributes.rowSpan ? parseInt(cell.attributes.rowSpan.value, 10) : 0; 47094 if (rowspanNumber > 1) { 47095 for (var rp = 1; rp < rowspanNumber; rp++) { 47096 var rowspanIndex = row.rowIndex + rp; 47097 adjustStartPoint(rowspanIndex, cellIndex, cell, isThisSelectedCell); 47098 setVirtualTablePosition(rowspanIndex, cellIndex, row, cell, true, cellHasColspan, true); 47099 } 47100 } 47101 // Add span cols to virtual table. 47102 var colspanNumber = cell.attributes.colSpan ? parseInt(cell.attributes.colSpan.value, 10) : 0; 47103 if (colspanNumber > 1) { 47104 for (var cp = 1; cp < colspanNumber; cp++) { 47105 var cellspanIndex = recoverCellIndex(row.rowIndex, (cellIndex + cp)); 47106 adjustStartPoint(row.rowIndex, cellspanIndex, cell, isThisSelectedCell); 47107 setVirtualTablePosition(row.rowIndex, cellspanIndex, row, cell, cellHasRowspan, true, true); 47108 } 47109 } 47110 } 47111 /** 47112 * Process validation and adjust of start point if needed 47113 * 47114 * @param {int} rowIndex 47115 * @param {int} cellIndex 47116 * @param {object} cell 47117 * @param {bool} isSelectedCell 47118 */ 47119 function adjustStartPoint(rowIndex, cellIndex, cell, isSelectedCell) { 47120 if (rowIndex === _startPoint.rowPos && _startPoint.colPos >= cell.cellIndex && cell.cellIndex <= cellIndex && !isSelectedCell) { 47121 _startPoint.colPos++; 47122 } 47123 } 47124 /** 47125 * Create virtual table of cells with all cells, including span cells. 47126 */ 47127 function createVirtualTable() { 47128 var rows = domTable.rows; 47129 for (var rowIndex = 0; rowIndex < rows.length; rowIndex++) { 47130 var cells = rows[rowIndex].cells; 47131 for (var cellIndex = 0; cellIndex < cells.length; cellIndex++) { 47132 addCellInfoToVirtual(rows[rowIndex], cells[cellIndex]); 47133 } 47134 } 47135 } 47136 /** 47137 * Get action to be applied on the cell. 47138 * 47139 * @param {object} cell virtual table cell to apply action 47140 */ 47141 function getDeleteResultActionToCell(cell) { 47142 switch (where) { 47143 case TableResultAction.where.Column: 47144 if (cell.isColSpan) { 47145 return TableResultAction.resultAction.SubtractSpanCount; 47146 } 47147 break; 47148 case TableResultAction.where.Row: 47149 if (!cell.isVirtual && cell.isRowSpan) { 47150 return TableResultAction.resultAction.AddCell; 47151 } 47152 else if (cell.isRowSpan) { 47153 return TableResultAction.resultAction.SubtractSpanCount; 47154 } 47155 break; 47156 } 47157 return TableResultAction.resultAction.RemoveCell; 47158 } 47159 /** 47160 * Get action to be applied on the cell. 47161 * 47162 * @param {object} cell virtual table cell to apply action 47163 */ 47164 function getAddResultActionToCell(cell) { 47165 switch (where) { 47166 case TableResultAction.where.Column: 47167 if (cell.isColSpan) { 47168 return TableResultAction.resultAction.SumSpanCount; 47169 } 47170 else if (cell.isRowSpan && cell.isVirtual) { 47171 return TableResultAction.resultAction.Ignore; 47172 } 47173 break; 47174 case TableResultAction.where.Row: 47175 if (cell.isRowSpan) { 47176 return TableResultAction.resultAction.SumSpanCount; 47177 } 47178 else if (cell.isColSpan && cell.isVirtual) { 47179 return TableResultAction.resultAction.Ignore; 47180 } 47181 break; 47182 } 47183 return TableResultAction.resultAction.AddCell; 47184 }
47185 function init() { 47186 setStartPoint(); 47187 createVirtualTable(); 47188 } 47189 /// /////////////////////////////////////////// 47190 // Public functions 47191 /// /////////////////////////////////////////// 47192 /** 47193 * Recover array os what to do in table. 47194 */ 47195 this.getActionList = function () { 47196 var fixedRow = (where === TableResultAction.where.Row) ? _startPoint.rowPos : -1; 47197 var fixedCol = (where === TableResultAction.where.Column) ? _startPoint.colPos : -1; 47198 var actualPosition = 0; 47199 var canContinue = true; 47200 while (canContinue) { 47201 var rowPosition = (fixedRow >= 0) ? fixedRow : actualPosition; 47202 var colPosition = (fixedCol >= 0) ? fixedCol : actualPosition; 47203 var row = _virtualTable[rowPosition]; 47204 if (!row) { 47205 canContinue = false; 47206 return _actionCellList; 47207 } 47208 var cell = row[colPosition]; 47209 if (!cell) { 47210 canContinue = false; 47211 return _actionCellList; 47212 } 47213 // Define action to be applied in this cell 47214 var resultAction = TableResultAction.resultAction.Ignore; 47215 switch (action) { 47216 case TableResultAction.requestAction.Add: 47217 resultAction = getAddResultActionToCell(cell); 47218 break; 47219 case TableResultAction.requestAction.Delete: 47220 resultAction = getDeleteResultActionToCell(cell); 47221 break; 47222 } 47223 _actionCellList.push(getActionCell(cell, resultAction, rowPosition, colPosition)); 47224 actualPosition++; 47225 } 47226 return _actionCellList; 47227 }; 47228 init(); 47229}; 47230/** 47231* 47232* Where action occours enum. 47233*/ 47234TableResultAction.where = { 'Row': 0, 'Column': 1 }; 47235/** 47236* 47237* Requested action to apply enum. 47238*/ 47239TableResultAction.requestAction = { 'Add': 0, 'Delete': 1 }; 47240/** 47241* 47242* Result action to be executed enum. 47243*/ 47244TableResultAction.resultAction = { 'Ignore': 0, 'SubtractSpanCount': 1, 'RemoveCell': 2, 'AddCell': 3, 'SumSpanCount': 4 }; 47245/** 47246 * 47247 * @class editing.Table 47248 * 47249 * Table 47250 * 47251 */ 47252var Table = /** @class */ (function () { 47253 function Table() { 47254 } 47255 /** 47256 * handle tab key 47257 * 47258 * @param {WrappedRange} rng 47259 * @param {Boolean} isShift 47260 */ 47261 Table.prototype.tab = function (rng, isShift) { 47262 var cell = dom.ancestor(rng.commonAncestor(), dom.isCell); 47263 var table = dom.ancestor(cell, dom.isTable); 47264 var cells = dom.listDescendant(table, dom.isCell); 47265 var nextCell = lists[isShift ? 'prev' : 'next'](cells, cell); 47266 if (nextCell) { 47267 range.create(nextCell, 0).select(); 47268 } 47269 }; 47270 /** 47271 * Add a new row 47272 * 47273 * @param {WrappedRange} rng 47274 * @param {String} position (top/bottom) 47275 * @return {Node} 47276 */ 47277 Table.prototype.addRow = function (rng, position) { 47278 var cell = dom.ancestor(rng.commonAncestor(), dom.isCell); 47279 var currentTr = $$1(cell).closest('tr'); 47280 var trAttributes = this.recoverAttributes(currentTr); 47281 var html = $$1('<tr' + trAttributes + '></tr>'); 47282 var vTable = new TableResultAction(cell, TableResultAction.where.Row, TableResultAction.requestAction.Add, $$1(currentTr).closest('table')[0]); 47283 var actions = vTable.getActionList(); 47284 for (var idCell = 0; idCell < actions.length; idCell++) { 47285 var currentCell = actions[idCell]; 47286 var tdAttributes = this.recoverAttributes(currentCell.baseCell); 47287 switch (currentCell.action) { 47288 case TableResultAction.resultAction.AddCell: 47289 html.append('<td' + tdAttributes + '>' + dom.blank + '</td>'); 47290 break; 47291 case TableResultAction.resultAction.SumSpanCount: 47292 if (position === 'top') { 47293 var baseCellTr = currentCell.baseCell.parent; 47294 var isTopFromRowSpan = (!baseCellTr ? 0 : currentCell.baseCell.closest('tr').rowIndex) <= currentTr[0].rowIndex; 47295 if (isTopFromRowSpan) { 47296 var newTd = $$1('<div></div>').append($$1('<td' + tdAttributes + '>' + dom.blank + '</td>').removeAttr('rowspan')).html(); 47297 html.append(newTd); 47298 break; 47299 } 47300 } 47301 var rowspanNumber = parseInt(currentCell.baseCell.rowSpan, 10); 47302 rowspanNumber++; 47303 currentCell.baseCell.setAttribute('rowSpan', rowspanNumber); 47304 break; 47305 } 47306 } 47307 if (position === 'top') { 47308 currentTr.before(html); 47309 } 47310 else { 47311 var cellHasRowspan = (cell.rowSpan > 1); 47312 if (cellHasRowspan) { 47313 var lastTrIndex = currentTr[0].rowIndex + (cell.rowSpan - 2); 47314 $$1($$1(currentTr).parent().find('tr')[lastTrIndex]).after($$1(html)); 47315 return; 47316 } 47317 currentTr.after(html); 47318 } 47319 }; 47320 /** 47321 * Add a new col 47322 * 47323 * @param {WrappedRange} rng 47324 * @param {String} position (left/right) 47325 * @return {Node} 47326 */ 47327 Table.prototype.addCol = function (rng, position) { 47328 var cell = dom.ancestor(rng.commonAncestor(), dom.isCell); 47329 var row = $$1(cell).closest('tr'); 47330 var rowsGroup = $$1(row).siblings(); 47331 rowsGroup.push(row); 47332 var vTable = new TableResultAction(cell, TableResultAction.where.Column, TableResultAction.requestAction.Add, $$1(row).closest('table')[0]); 47333 var actions = vTable.getActionList(); 47334 for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) { 47335 var currentCell = actions[actionIndex]; 47336 var tdAttributes = this.recoverAttributes(currentCell.baseCell); 47337 switch (currentCell.action) { 47338 case TableResultAction.resultAction.AddCell: 47339 if (position === 'right') { 47340 $$1(currentCell.baseCell).after('<td' + tdAttributes + '>' + dom.blank + '</td>'); 47341 } 47342 else { 47343 $$1(currentCell.baseCell).before('<td' + tdAttributes + '>' + dom.blank + '</td>'); 47344 } 47345 break; 47346 case TableResultAction.resultAction.SumSpanCount: 47347 if (position === 'right') { 47348 var colspanNumber = parseInt(currentCell.baseCell.colSpan, 10); 47349 colspanNumber++; 47350 currentCell.baseCell.setAttribute('colSpan', colspanNumber); 47351 } 47352 else { 47353 $$1(currentCell.baseCell).before('<td' + tdAttributes + '>' + dom.blank + '</td>'); 47354 } 47355 break; 47356 } 47357 } 47358 }; 47359 /* 47360 * Copy attributes from element. 47361 * 47362 * @param {object} Element to recover attributes. 47363 * @return {string} Copied string elements. 47364 */ 47365 Table.prototype.recoverAttributes = function (el) { 47366 var resultStr = ''; 47367 if (!el) { 47368 return resultStr; 47369 } 47370 var attrList = el.attributes || []; 47371 for (var i = 0; i < attrList.length; i++) { 47372 if (attrList[i].name.toLowerCase() === 'id') { 47373 continue; 47374 } 47375 if (attrList[i].specified) { 47376 resultStr += ' ' + attrList[i].name + '=\'' + attrList[i].value + '\''; 47377 } 47378 } 47379 return resultStr; 47380 }; 47381 /** 47382 * Delete current row 47383 * 47384 * @param {WrappedRange} rng 47385 * @return {Node} 47386 */ 47387 Table.prototype.deleteRow = function (rng) { 47388 var cell = dom.ancestor(rng.commonAncestor(), dom.isCell); 47389 var row = $$1(cell).closest('tr');
47390 var cellPos = row.children('td, th').index($$1(cell)); 47391 var rowPos = row[0].rowIndex; 47392 var vTable = new TableResultAction(cell, TableResultAction.where.Row, TableResultAction.requestAction.Delete, $$1(row).closest('table')[0]); 47393 var actions = vTable.getActionList(); 47394 for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) { 47395 if (!actions[actionIndex]) { 47396 continue; 47397 } 47398 var baseCell = actions[actionIndex].baseCell; 47399 var virtualPosition = actions[actionIndex].virtualTable; 47400 var hasRowspan = (baseCell.rowSpan && baseCell.rowSpan > 1); 47401 var rowspanNumber = (hasRowspan) ? parseInt(baseCell.rowSpan, 10) : 0; 47402 switch (actions[actionIndex].action) { 47403 case TableResultAction.resultAction.Ignore: 47404 continue; 47405 case TableResultAction.resultAction.AddCell: 47406 var nextRow = row.next('tr')[0]; 47407 if (!nextRow) { 47408 continue; 47409 } 47410 var cloneRow = row[0].cells[cellPos]; 47411 if (hasRowspan) { 47412 if (rowspanNumber > 2) { 47413 rowspanNumber--; 47414 nextRow.insertBefore(cloneRow, nextRow.cells[cellPos]); 47415 nextRow.cells[cellPos].setAttribute('rowSpan', rowspanNumber); 47416 nextRow.cells[cellPos].innerHTML = ''; 47417 } 47418 else if (rowspanNumber === 2) { 47419 nextRow.insertBefore(cloneRow, nextRow.cells[cellPos]); 47420 nextRow.cells[cellPos].removeAttribute('rowSpan'); 47421 nextRow.cells[cellPos].innerHTML = ''; 47422 } 47423 } 47424 continue; 47425 case TableResultAction.resultAction.SubtractSpanCount: 47426 if (hasRowspan) { 47427 if (rowspanNumber > 2) { 47428 rowspanNumber--; 47429 baseCell.setAttribute('rowSpan', rowspanNumber); 47430 if (virtualPosition.rowIndex !== rowPos && baseCell.cellIndex === cellPos) { 47431 baseCell.innerHTML = ''; 47432 } 47433 } 47434 else if (rowspanNumber === 2) { 47435 baseCell.removeAttribute('rowSpan'); 47436 if (virtualPosition.rowIndex !== rowPos && baseCell.cellIndex === cellPos) { 47437 baseCell.innerHTML = ''; 47438 } 47439 } 47440 } 47441 continue; 47442 case TableResultAction.resultAction.RemoveCell: 47443 // Do not need remove cell because row will be deleted. 47444 continue; 47445 } 47446 } 47447 row.remove(); 47448 }; 47449 /** 47450 * Delete current col 47451 * 47452 * @param {WrappedRange} rng 47453 * @return {Node} 47454 */ 47455 Table.prototype.deleteCol = function (rng) { 47456 var cell = dom.ancestor(rng.commonAncestor(), dom.isCell); 47457 var row = $$1(cell).closest('tr'); 47458 var cellPos = row.children('td, th').index($$1(cell)); 47459 var vTable = new TableResultAction(cell, TableResultAction.where.Column, TableResultAction.requestAction.Delete, $$1(row).closest('table')[0]); 47460 var actions = vTable.getActionList(); 47461 for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) { 47462 if (!actions[actionIndex]) { 47463 continue; 47464 } 47465 switch (actions[actionIndex].action) { 47466 case TableResultAction.resultAction.Ignore: 47467 continue; 47468 case TableResultAction.resultAction.SubtractSpanCount: 47469 var baseCell = actions[actionIndex].baseCell; 47470 var hasColspan = (baseCell.colSpan && baseCell.colSpan > 1); 47471 if (hasColspan) { 47472 var colspanNumber = (baseCell.colSpan) ? parseInt(baseCell.colSpan, 10) : 0; 47473 if (colspanNumber > 2) { 47474 colspanNumber--; 47475 baseCell.setAttribute('colSpan', colspanNumber); 47476 if (baseCell.cellIndex === cellPos) { 47477 baseCell.innerHTML = ''; 47478 } 47479 } 47480 else if (colspanNumber === 2) { 47481 baseCell.removeAttribute('colSpan'); 47482 if (baseCell.cellIndex === cellPos) { 47483 baseCell.innerHTML = ''; 47484 } 47485 } 47486 } 47487 continue; 47488 case TableResultAction.resultAction.RemoveCell: 47489 dom.remove(actions[actionIndex].baseCell, true); 47490 continue; 47491 } 47492 } 47493 }; 47494 /** 47495 * create empty table element 47496 * 47497 * @param {Number} rowCount 47498 * @param {Number} colCount 47499 * @return {Node} 47500 */ 47501 Table.prototype.createTable = function (colCount, rowCount, options) { 47502 var tds = []; 47503 var tdHTML; 47504 for (var idxCol = 0; idxCol < colCount; idxCol++) { 47505 tds.push('<td>' + dom.blank + '</td>'); 47506 } 47507 tdHTML = tds.join(''); 47508 var trs = []; 47509 var trHTML; 47510 for (var idxRow = 0; idxRow < rowCount; idxRow++) { 47511 trs.push('<tr>' + tdHTML + '</tr>'); 47512 } 47513 trHTML = trs.join(''); 47514 var $table = $$1('<table>' + trHTML + '</table>'); 47515 if (options && options.tableClassName) { 47516 $table.addClass(options.tableClassName); 47517 } 47518 return $table[0]; 47519 }; 47520 /** 47521 * Delete current table 47522 * 47523 * @param {WrappedRange} rng 47524 * @return {Node} 47525 */ 47526 Table.prototype.deleteTable = function (rng) { 47527 var cell = dom.ancestor(rng.commonAncestor(), dom.isCell); 47528 $$1(cell).closest('table').remove(); 47529 }; 47530 return Table; 47531}()); 47532 47533var KEY_BOGUS = 'bogus'; 47534/** 47535 * @class Editor 47536 */ 47537var Editor = /** @class */ (function () { 47538 function Editor(context) { 47539 var _this = this; 47540 this.context = context; 47541 this.$note = context.layoutInfo.note; 47542 this.$editor = context.layoutInfo.editor; 47543 this.$editable = context.layoutInfo.editable; 47544 this.options = context.options; 47545 this.lang = this.options.langInfo; 47546 this.editable = this.$editable[0]; 47547 this.lastRange = null; 47548 this.style = new Style(); 47549 this.table = new Table(); 47550 this.typing = new Typing(); 47551 this.bullet = new Bullet(); 47552 this.history = new History(this.$editable); 47553 this.context.memo('help.undo', this.lang.help.undo); 47554 this.context.memo('help.redo', this.lang.help.redo); 47555 this.context.memo('help.tab', this.lang.help.tab); 47556 this.context.memo('help.untab', this.lang.help.untab); 47557 this.context.memo('help.insertParagraph', this.lang.help.insertParagraph); 47558 this.context.memo('help.insertOrderedList', this.lang.help.insertOrderedList); 47559 this.context.memo('help.insertUnorderedList', this.lang.help.insertUnorderedList); 47560 this.context.memo('help.indent', this.lang.help.indent); 47561 this.context.memo('help.outdent', this.lang.help.outdent); 47562 this.context.memo('help.formatPara', this.lang.help.formatPara); 47563 this.context.memo('help.insertHorizontalRule', this.lang.help.insertHorizontalRule); 47564 this.context.memo('help.fontName', this.lang.help.fontName); 47565 // native commands(with execCommand), generate function for execCommand 47566 var commands = [ 47567 'bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 47568 'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', 47569 'formatBlock', 'removeFormat', 'backColor' 47570 ]; 47571 for (var idx = 0, len = commands.length; idx < len; idx++) { 47572 this[commands[idx]] = (function (sCmd) { 47573 return function (value) { 47574 _this.beforeCommand(); 47575 document.execCommand(sCmd, false, value); 47576 _this.afterCommand(true); 47577 }; 47578 })(commands[idx]); 47579 this.context.memo('help.' + commands[idx], this.lang.help[commands[idx]]); 47580 } 47581 this.fontName = this.wrapCommand(function (value) { 47582 return _this.fontStyling('font-family', "\'" + value + "\'"); 47583 }); 47584 this.fontSize = this.wrapCommand(function (value) { 47585 return _this.fontStyling('font-size', value + 'px'); 47586 }); 47587 for (var idx = 1; idx <= 6; idx++) { 47588 this['formatH' + idx] = (function (idx) { 47589 return function () { 47590 _this.formatBlock('H' + idx); 47591 }; 47592 })(idx); 47593 this.context.memo('help.formatH' + idx, this.lang.help['formatH' + idx]); 47594 } 47595 47596 this.insertParagraph = this.wrapCommand(function () { 47597 _this.typing.insertParagraph(_this.editable); 47598 }); 47599 this.insertOrderedList = this.wrapCommand(function () { 47600 _this.bullet.insertOrderedList(_this.editable); 47601 }); 47602 this.insertUnorderedList = this.wrapCommand(function () { 47603 _this.bullet.insertUnorderedList(_this.editable); 47604 }); 47605 this.indent = this.wrapCommand(function () { 47606 _this.bullet.indent(_this.editable); 47607 }); 47608 this.outdent = this.wrapCommand(function () { 47609 _this.bullet.outdent(_this.editable); 47610 }); 47611 /**
47612 * insertNode 47613 * insert node 47614 * @param {Node} node 47615 */ 47616 this.insertNode = this.wrapCommand(function (node) { 47617 if (_this.isLimited($$1(node).text().length)) { 47618 return; 47619 } 47620 var rng = _this.createRange(); 47621 rng.insertNode(node); 47622 range.createFromNodeAfter(node).select(); 47623 }); 47624 /** 47625 * insert text 47626 * @param {String} text 47627 */ 47628 this.insertText = this.wrapCommand(function (text) { 47629 if (_this.isLimited(text.length)) { 47630 return; 47631 } 47632 var rng = _this.createRange(); 47633 var textNode = rng.insertNode(dom.createText(text)); 47634 range.create(textNode, dom.nodeLength(textNode)).select(); 47635 }); 47636 /** 47637 * paste HTML 47638 * @param {String} markup 47639 */ 47640 this.pasteHTML = this.wrapCommand(function (markup) { 47641 if (_this.isLimited(markup.length)) { 47642 return; 47643 } 47644 var contents = _this.createRange().pasteHTML(markup); 47645 range.createFromNodeAfter(lists.last(contents)).select(); 47646 }); 47647 /** 47648 * formatBlock 47649 * 47650 * @param {String} tagName 47651 */ 47652 this.formatBlock = this.wrapCommand(function (tagName, $target) { 47653 var onApplyCustomStyle = _this.options.callbacks.onApplyCustomStyle; 47654 if (onApplyCustomStyle) { 47655 onApplyCustomStyle.call(_this, $target, _this.context, _this.onFormatBlock); 47656 } 47657 else { 47658 _this.onFormatBlock(tagName, $target); 47659 } 47660 }); 47661 /** 47662 * insert horizontal rule 47663 */ 47664 this.insertHorizontalRule = this.wrapCommand(function () { 47665 var hrNode = _this.createRange().insertNode(dom.create('HR')); 47666 if (hrNode.nextSibling) { 47667 range.create(hrNode.nextSibling, 0).normalize().select(); 47668 } 47669 }); 47670 /** 47671 * lineHeight 47672 * @param {String} value 47673 */ 47674 this.lineHeight = this.wrapCommand(function (value) { 47675 _this.style.stylePara(_this.createRange(), { 47676 lineHeight: value 47677 }); 47678 }); 47679 /** 47680 * create link (command) 47681 * 47682 * @param {Object} linkInfo 47683 */ 47684 this.createLink = this.wrapCommand(function (linkInfo) { 47685 var linkUrl = linkInfo.url; 47686 var linkText = linkInfo.text; 47687 var isNewWindow = linkInfo.isNewWindow; 47688 var rng = linkInfo.range || _this.createRange(); 47689 var isTextChanged = rng.toString() !== linkText; 47690 // handle spaced urls from input 47691 if (typeof linkUrl === 'string') { 47692 linkUrl = linkUrl.trim(); 47693 } 47694 if (_this.options.onCreateLink) { 47695 linkUrl = _this.options.onCreateLink(linkUrl); 47696 } 47697 else { 47698 // if url doesn't match an URL schema, set http:// as default 47699 linkUrl = /^[A-Za-z][A-Za-z0-9+-.]*\:[\/\/]?/.test(linkUrl) 47700 ? linkUrl : 'http://' + linkUrl; 47701 } 47702 var anchors = []; 47703 if (isTextChanged) { 47704 rng = rng.deleteContents(); 47705 var anchor = rng.insertNode($$1('<A>' + linkText + '</A>')[0]); 47706 anchors.push(anchor); 47707 } 47708 else { 47709 anchors = _this.style.styleNodes(rng, { 47710 nodeName: 'A', 47711 expandClosestSibling: true, 47712 onlyPartialContains: true 47713 }); 47714 } 47715 $$1.each(anchors, function (idx, anchor) { 47716 $$1(anchor).attr('href', linkUrl); 47717 if (isNewWindow) { 47718 $$1(anchor).attr('target', '_blank'); 47719 } 47720 else { 47721 $$1(anchor).removeAttr('target'); 47722 } 47723 }); 47724 var startRange = range.createFromNodeBefore(lists.head(anchors)); 47725 var startPoint = startRange.getStartPoint(); 47726 var endRange = range.createFromNodeAfter(lists.last(anchors)); 47727 var endPoint = endRange.getEndPoint(); 47728 range.create(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset).select(); 47729 }); 47730 /** 47731 * setting color 47732 * 47733 * @param {Object} sObjColor color code 47734 * @param {String} sObjColor.foreColor foreground color 47735 * @param {String} sObjColor.backColor background color 47736 */ 47737 this.color = this.wrapCommand(function (colorInfo) { 47738 var foreColor = colorInfo.foreColor; 47739 var backColor = colorInfo.backColor; 47740 if (foreColor) { 47741 document.execCommand('foreColor', false, foreColor); 47742 } 47743 if (backColor) { 47744 document.execCommand('backColor', false, backColor); 47745 } 47746 }); 47747 /** 47748 * Set foreground color 47749 * 47750 * @param {String} colorCode foreground color code 47751 */ 47752 this.foreColor = this.wrapCommand(function (colorInfo) { 47753 document.execCommand('styleWithCSS', false, true); 47754 document.execCommand('foreColor', false, colorInfo); 47755 }); 47756 /** 47757 * insert Table 47758 * 47759 * @param {String} dimension of table (ex : "5x5") 47760 */ 47761 this.insertTable = this.wrapCommand(function (dim) { 47762 var dimension = dim.split('x'); 47763 var rng = _this.createRange().deleteContents();
47764 rng.insertNode(_this.table.createTable(dimension[0], dimension[1], _this.options)); 47765 }); 47766 /** 47767 * remove media object and Figure Elements if media object is img with Figure. 47768 */ 47769 this.removeMedia = this.wrapCommand(function () { 47770 var $target = $$1(_this.restoreTarget()).parent(); 47771 if ($target.parent('figure').length) { 47772 $target.parent('figure').remove(); 47773 } 47774 else { 47775 $target = $$1(_this.restoreTarget()).detach(); 47776 } 47777 _this.context.triggerEvent('media.delete', $target, _this.$editable); 47778 }); 47779 /** 47780 * float me 47781 * 47782 * @param {String} value 47783 */ 47784 this.floatMe = this.wrapCommand(function (value) { 47785 var $target = $$1(_this.restoreTarget()); 47786 $target.toggleClass('note-float-left', value === 'left'); 47787 $target.toggleClass('note-float-right', value === 'right'); 47788 $target.css('float', value); 47789 }); 47790 /** 47791 * resize overlay element 47792 * @param {String} value 47793 */ 47794 this.resize = this.wrapCommand(function (value) { 47795 var $target = $$1(_this.restoreTarget()); 47796 $target.css({ 47797 width: value * 100 + '%', 47798 height: '' 47799 }); 47800 }); 47801 } 47802 Editor.prototype.initialize = function () { 47803 var _this = this; 47804 // bind custom events 47805 this.$editable.on('keydown', function (event) { 47806 if (event.keyCode === key.code.ENTER) { 47807 _this.context.triggerEvent('enter', event); 47808 } 47809 _this.context.triggerEvent('keydown', event); 47810 if (!event.isDefaultPrevented()) { 47811 if (_this.options.shortcuts) { 47812 _this.handleKeyMap(event); 47813 } 47814 else { 47815 _this.preventDefaultEditableShortCuts(event); 47816 } 47817 } 47818 if (_this.isLimited(1, event)) { 47819 return false; 47820 } 47821 }).on('keyup', function (event) { 47822 _this.context.triggerEvent('keyup', event); 47823 }).on('focus', function (event) { 47824 _this.context.triggerEvent('focus', event); 47825 }).on('blur', function (event) { 47826 _this.context.triggerEvent('blur', event); 47827 }).on('mousedown', function (event) { 47828 _this.context.triggerEvent('mousedown', event); 47829 }).on('mouseup', function (event) { 47830 _this.context.triggerEvent('mouseup', event); 47831 }).on('scroll', function (event) { 47832 _this.context.triggerEvent('scroll', event); 47833 }).on('paste', function (event) { 47834 _this.context.triggerEvent('paste', event); 47835 }); 47836 // init content before set event 47837 this.$editable.html(dom.html(this.$note) || dom.emptyPara); 47838 this.$editable.on(env.inputEventName, func.debounce(function () { 47839 _this.context.triggerEvent('change', _this.$editable.html()); 47840 }, 100)); 47841 this.$editor.on('focusin', function (event) { 47842 _this.context.triggerEvent('focusin', event); 47843 }).on('focusout', function (event) { 47844 _this.context.triggerEvent('focusout', event); 47845 }); 47846 if (!this.options.airMode) { 47847 if (this.options.width) { 47848 this.$editor.outerWidth(this.options.width); 47849 } 47850 if (this.options.height) { 47851 this.$editable.outerHeight(this.options.height); 47852 } 47853 if (this.options.maxHeight) { 47854 this.$editable.css('max-height', this.options.maxHeight); 47855 } 47856 if (this.options.minHeight) { 47857 this.$editable.css('min-height', this.options.minHeight); 47858 } 47859 } 47860 this.history.recordUndo(); 47861 }; 47862 Editor.prototype.destroy = function () { 47863 this.$editable.off(); 47864 }; 47865 Editor.prototype.handleKeyMap = function (event) { 47866 var keyMap = this.options.keyMap[env.isMac ? 'mac' : 'pc']; 47867 var keys = []; 47868 if (event.metaKey) { 47869 keys.push('CMD'); 47870 } 47871 if (event.ctrlKey && !event.altKey) { 47872 keys.push('CTRL'); 47873 } 47874 if (event.shiftKey) { 47875 keys.push('SHIFT'); 47876 } 47877 var keyName = key.nameFromCode[event.keyCode]; 47878 if (keyName) { 47879 keys.push(keyName); 47880 } 47881 var eventName = keyMap[keys.join('+')]; 47882 if (eventName) {
47883 if (this.context.invoke(eventName) !== false) { 47884 event.preventDefault(); 47885 } 47886 } 47887 else if (key.isEdit(event.keyCode)) { 47888 this.afterCommand(); 47889 } 47890 }; 47891 Editor.prototype.preventDefaultEditableShortCuts = function (event) { 47892 // B(Bold, 66) / I(Italic, 73) / U(Underline, 85) 47893 if ((event.ctrlKey || event.metaKey) && 47894 lists.contains([66, 73, 85], event.keyCode)) { 47895 event.preventDefault(); 47896 } 47897 }; 47898 Editor.prototype.isLimited = function (pad, event) { 47899 pad = pad || 0; 47900 if (typeof event !== 'undefined') { 47901 if (key.isMove(event.keyCode) || 47902 (event.ctrlKey || event.metaKey) || 47903 lists.contains([key.code.BACKSPACE, key.code.DELETE], event.keyCode)) { 47904 return false; 47905 } 47906 } 47907 if (this.options.maxTextLength > 0) { 47908 if ((this.$editable.text().length + pad) >= this.options.maxTextLength) { 47909 return true; 47910 } 47911 } 47912 return false; 47913 }; 47914 /** 47915 * create range 47916 * @return {WrappedRange} 47917 */ 47918 Editor.prototype.createRange = function () { 47919 this.focus(); 47920 return range.create(this.editable); 47921 }; 47922 /** 47923 * saveRange 47924 * 47925 * save current range 47926 * 47927 * @param {Boolean} [thenCollapse=false] 47928 */ 47929 Editor.prototype.saveRange = function (thenCollapse) { 47930 this.lastRange = this.createRange(); 47931 if (thenCollapse) { 47932 this.lastRange.collapse().select(); 47933 } 47934 }; 47935 /** 47936 * restoreRange 47937 * 47938 * restore lately range 47939 */ 47940 Editor.prototype.restoreRange = function () { 47941 if (this.lastRange) { 47942 this.lastRange.select(); 47943 this.focus(); 47944 } 47945 }; 47946 Editor.prototype.saveTarget = function (node) { 47947 this.$editable.data('target', node); 47948 }; 47949 Editor.prototype.clearTarget = function () { 47950 this.$editable.removeData('target'); 47951 }; 47952 Editor.prototype.restoreTarget = function () { 47953 return this.$editable.data('target'); 47954 }; 47955 /** 47956 * currentStyle 47957 * 47958 * current style 47959 * @return {Object|Boolean} unfocus 47960 */ 47961 Editor.prototype.currentStyle = function () { 47962 var rng = range.create(); 47963 if (rng) { 47964 rng = rng.normalize(); 47965 } 47966 return rng ? this.style.current(rng) : this.style.fromNode(this.$editable); 47967 }; 47968 /** 47969 * style from node 47970 * 47971 * @param {jQuery} $node 47972 * @return {Object} 47973 */ 47974 Editor.prototype.styleFromNode = function ($node) { 47975 return this.style.fromNode($node); 47976 }; 47977 /** 47978 * undo 47979 */ 47980 Editor.prototype.undo = function () { 47981 this.context.triggerEvent('before.command', this.$editable.html()); 47982 this.history.undo(); 47983 this.context.triggerEvent('change', this.$editable.html()); 47984 }; 47985 /** 47986 * redo 47987 */ 47988 Editor.prototype.redo = function () { 47989 this.context.triggerEvent('before.command', this.$editable.html()); 47990 this.history.redo(); 47991 this.context.triggerEvent('change', this.$editable.html()); 47992 }; 47993 /** 47994 * before command 47995 */ 47996 Editor.prototype.beforeCommand = function () { 47997 this.context.triggerEvent('before.command', this.$editable.html()); 47998 // keep focus on editable before command execution 47999 this.focus(); 48000 }; 48001 /** 48002 * after command 48003 * @param {Boolean} isPreventTrigger 48004 */ 48005 Editor.prototype.afterCommand = function (isPreventTrigger) { 48006 this.normalizeContent(); 48007 this.history.recordUndo(); 48008 if (!isPreventTrigger) { 48009 this.context.triggerEvent('change', this.$editable.html()); 48010 } 48011 }; 48012 /** 48013 * handle tab key 48014 */ 48015 Editor.prototype.tab = function () { 48016 var rng = this.createRange(); 48017 if (rng.isCollapsed() && rng.isOnCell()) { 48018 this.table.tab(rng); 48019 } 48020 else { 48021 if (this.options.tabSize === 0) { 48022 return false; 48023 } 48024 if (!this.isLimited(this.options.tabSize)) { 48025 this.beforeCommand(); 48026 this.typing.insertTab(rng, this.options.tabSize); 48027 this.afterCommand(); 48028 } 48029 } 48030 }; 48031 /** 48032 * handle shift+tab key 48033 */ 48034 Editor.prototype.untab = function () { 48035 var rng = this.createRange(); 48036 if (rng.isCollapsed() && rng.isOnCell()) { 48037 this.table.tab(rng, true); 48038 } 48039 else { 48040 if (this.options.tabSize === 0) { 48041 return false;
48042 } 48043 } 48044 }; 48045 /** 48046 * run given function between beforeCommand and afterCommand 48047 */ 48048 Editor.prototype.wrapCommand = function (fn) { 48049 var _this = this; 48050 return function () { 48051 _this.beforeCommand(); 48052 fn.apply(_this, arguments); 48053 _this.afterCommand(); 48054 }; 48055 }; 48056 /** 48057 * insert image 48058 * 48059 * @param {String} src 48060 * @param {String|Function} param 48061 * @return {Promise} 48062 */ 48063 Editor.prototype.insertImage = function (src, param) { 48064 var _this = this; 48065 return createImage(src, param).then(function ($image) { 48066 _this.beforeCommand(); 48067 if (typeof param === 'function') { 48068 param($image); 48069 } 48070 else { 48071 if (typeof param === 'string') { 48072 $image.attr('data-filename', param); 48073 } 48074 $image.css('width', Math.min(_this.$editable.width(), $image.width())); 48075 } 48076 $image.show(); 48077 range.create(_this.editable).insertNode($image[0]); 48078 range.createFromNodeAfter($image[0]).select(); 48079 _this.afterCommand(); 48080 }).fail(function (e) { 48081 _this.context.triggerEvent('image.upload.error', e); 48082 }); 48083 }; 48084 /** 48085 * insertImages 48086 * @param {File[]} files 48087 */ 48088 Editor.prototype.insertImages = function (files) { 48089 var _this = this; 48090 $$1.each(files, function (idx, file) { 48091 var filename = file.name; 48092 if (_this.options.maximumImageFileSize && _this.options.maximumImageFileSize < file.size) { 48093 _this.context.triggerEvent('image.upload.error', _this.lang.image.maximumFileSizeError); 48094 } 48095 else { 48096 readFileAsDataURL(file).then(function (dataURL) { 48097 return _this.insertImage(dataURL, filename); 48098 }).fail(function () { 48099 _this.context.triggerEvent('image.upload.error'); 48100 }); 48101 } 48102 }); 48103 }; 48104 /** 48105 * insertImagesOrCallback 48106 * @param {File[]} files 48107 */ 48108 Editor.prototype.insertImagesOrCallback = function (files) { 48109 var callbacks = this.options.callbacks; 48110 // If onImageUpload this.options setted 48111 if (callbacks.onImageUpload) { 48112 this.context.triggerEvent('image.upload', files); 48113 // else insert Image as dataURL 48114 } 48115 else { 48116 this.insertImages(files); 48117 } 48118 }; 48119 /** 48120 * return selected plain text 48121 * @return {String} text 48122 */ 48123 Editor.prototype.getSelectedText = function () { 48124 var rng = this.createRange(); 48125 // if range on anchor, expand range with anchor 48126 if (rng.isOnAnchor()) { 48127 rng = range.createFromNode(dom.ancestor(rng.sc, dom.isAnchor)); 48128 } 48129 return rng.toString(); 48130 }; 48131 Editor.prototype.onFormatBlock = function (tagName, $target) { 48132 // [workaround] for MSIE, IE need `<` 48133 tagName = env.isMSIE ? '<' + tagName + '>' : tagName; 48134 document.execCommand('FormatBlock', false, tagName); 48135 // support custom class 48136 if ($target && $target.length) { 48137 var className = $target[0].className || ''; 48138 if (className) { 48139 var currentRange = this.createRange(); 48140 var $parent = $$1([currentRange.sc, currentRange.ec]).closest(tagName); 48141 $parent.addClass(className); 48142 } 48143 } 48144 }; 48145 Editor.prototype.formatPara = function () { 48146 this.formatBlock('P'); 48147 }; 48148 Editor.prototype.fontStyling = function (target, value) { 48149 var rng = this.createRange(); 48150 if (rng) { 48151 var spans = this.style.styleNodes(rng); 48152 $$1(spans).css(target, value); 48153 // [workaround] added styled bogus span for style 48154 // - also bogus character needed for cursor position 48155 if (rng.isCollapsed()) { 48156 var firstSpan = lists.head(spans); 48157 if (firstSpan && !dom.nodeLength(firstSpan)) { 48158 firstSpan.innerHTML = dom.ZERO_WIDTH_NBSP_CHAR; 48159 range.createFromNodeAfter(firstSpan.firstChild).select(); 48160 this.$editable.data(KEY_BOGUS, firstSpan); 48161 } 48162 } 48163 } 48164 }; 48165 /** 48166 * unlink 48167 * 48168 * @type command 48169 */ 48170 Editor.prototype.unlink = function () { 48171 var rng = this.createRange(); 48172 if (rng.isOnAnchor()) { 48173 var anchor = dom.ancestor(rng.sc, dom.isAnchor); 48174 rng = range.createFromNode(anchor); 48175 rng.select(); 48176 this.beforeCommand(); 48177 document.execCommand('unlink'); 48178 this.afterCommand(); 48179 } 48180 }; 48181 /** 48182 * returns link info 48183 * 48184 * @return {Object} 48185 * @return {WrappedRange} return.range 48186 * @return {String} return.text 48187 * @return {Boolean} [return.isNewWindow=true] 48188 * @return {String} [return.url=""] 48189 */ 48190 Editor.prototype.getLinkInfo = function () { 48191 var rng = this.createRange().expand(dom.isAnchor); 48192 // Get the first anchor on range(for edit).
48193 var $anchor = $$1(lists.head(rng.nodes(dom.isAnchor))); 48194 var linkInfo = { 48195 range: rng, 48196 text: rng.toString(), 48197 url: $anchor.length ? $anchor.attr('href') : '' 48198 }; 48199 // Define isNewWindow when anchor exists. 48200 if ($anchor.length) { 48201 linkInfo.isNewWindow = $anchor.attr('target') === '_blank'; 48202 } 48203 return linkInfo; 48204 }; 48205 Editor.prototype.addRow = function (position) { 48206 var rng = this.createRange(this.$editable); 48207 if (rng.isCollapsed() && rng.isOnCell()) { 48208 this.beforeCommand(); 48209 this.table.addRow(rng, position); 48210 this.afterCommand(); 48211 } 48212 }; 48213 Editor.prototype.addCol = function (position) { 48214 var rng = this.createRange(this.$editable); 48215 if (rng.isCollapsed() && rng.isOnCell()) { 48216 this.beforeCommand(); 48217 this.table.addCol(rng, position); 48218 this.afterCommand(); 48219 } 48220 }; 48221 Editor.prototype.deleteRow = function () { 48222 var rng = this.createRange(this.$editable); 48223 if (rng.isCollapsed() && rng.isOnCell()) { 48224 this.beforeCommand(); 48225 this.table.deleteRow(rng); 48226 this.afterCommand(); 48227 } 48228 }; 48229 Editor.prototype.deleteCol = function () { 48230 var rng = this.createRange(this.$editable); 48231 if (rng.isCollapsed() && rng.isOnCell()) { 48232 this.beforeCommand(); 48233 this.table.deleteCol(rng); 48234 this.afterCommand(); 48235 } 48236 }; 48237 Editor.prototype.deleteTable = function () { 48238 var rng = this.createRange(this.$editable); 48239 if (rng.isCollapsed() && rng.isOnCell()) { 48240 this.beforeCommand(); 48241 this.table.deleteTable(rng); 48242 this.afterCommand(); 48243 } 48244 }; 48245 /** 48246 * @param {Position} pos 48247 * @param {jQuery} $target - target element 48248 * @param {Boolean} [bKeepRatio] - keep ratio 48249 */ 48250 Editor.prototype.resizeTo = function (pos, $target, bKeepRatio) { 48251 var imageSize; 48252 if (bKeepRatio) { 48253 var newRatio = pos.y / pos.x; 48254 var ratio = $target.data('ratio'); 48255 imageSize = { 48256 width: ratio > newRatio ? pos.x : pos.y / ratio, 48257 height: ratio > newRatio ? pos.x * ratio : pos.y 48258 }; 48259 } 48260 else { 48261 imageSize = { 48262 width: pos.x, 48263 height: pos.y 48264 }; 48265 } 48266 $target.css(imageSize); 48267 }; 48268 /** 48269 * returns whether editable area has focus or not. 48270 */ 48271 Editor.prototype.hasFocus = function () { 48272 return this.$editable.is(':focus'); 48273 }; 48274 /** 48275 * set focus 48276 */ 48277 Editor.prototype.focus = function () { 48278 // [workaround] Screen will move when page is scolled in IE. 48279 // - do focus when not focused 48280 if (!this.hasFocus()) { 48281 this.$editable.focus(); 48282 } 48283 }; 48284 /** 48285 * returns whether contents is empty or not. 48286 * @return {Boolean} 48287 */ 48288 Editor.prototype.isEmpty = function () { 48289 return dom.isEmpty(this.$editable[0]) || dom.emptyPara === this.$editable.html(); 48290 }; 48291 /** 48292 * Removes all contents and restores the editable instance to an _emptyPara_. 48293 */ 48294 Editor.prototype.empty = function () { 48295 this.context.invoke('code', dom.emptyPara); 48296 }; 48297 /** 48298 * normalize content 48299 */ 48300 Editor.prototype.normalizeContent = function () { 48301 this.$editable[0].normalize(); 48302 }; 48303 return Editor; 48304}()); 48305 48306var Clipboard = /** @class */ (function () { 48307 function Clipboard(context) { 48308 this.context = context; 48309 this.$editable = context.layoutInfo.editable; 48310 } 48311 Clipboard.prototype.initialize = function () { 48312 this.$editable.on('paste', this.pasteByEvent.bind(this)); 48313 }; 48314 /** 48315 * paste by clipboard event 48316 * 48317 * @param {Event} event 48318 */ 48319 Clipboard.prototype.pasteByEvent = function (event) { 48320 var clipboardData = event.originalEvent.clipboardData; 48321 if (clipboardData && clipboardData.items && clipboardData.items.length) { 48322 var item = lists.head(clipboardData.items); 48323 if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {
48324 this.context.invoke('editor.insertImagesOrCallback', [item.getAsFile()]); 48325 } 48326 this.context.invoke('editor.afterCommand'); 48327 } 48328 }; 48329 return Clipboard; 48330}()); 48331 48332var Dropzone = /** @class */ (function () { 48333 function Dropzone(context) { 48334 this.context = context; 48335 this.$eventListener = $$1(document); 48336 this.$editor = context.layoutInfo.editor; 48337 this.$editable = context.layoutInfo.editable; 48338 this.options = context.options; 48339 this.lang = this.options.langInfo; 48340 this.documentEventHandlers = {}; 48341 this.$dropzone = $$1([ 48342 '<div class="note-dropzone">', 48343 ' <div class="note-dropzone-message"/>', 48344 '</div>' 48345 ].join('')).prependTo(this.$editor); 48346 } 48347 /** 48348 * attach Drag and Drop Events 48349 */ 48350 Dropzone.prototype.initialize = function () { 48351 if (this.options.disableDragAndDrop) { 48352 // prevent default drop event 48353 this.documentEventHandlers.onDrop = function (e) { 48354 e.preventDefault(); 48355 }; 48356 // do not consider outside of dropzone 48357 this.$eventListener = this.$dropzone; 48358 this.$eventListener.on('drop', this.documentEventHandlers.onDrop); 48359 } 48360 else { 48361 this.attachDragAndDropEvent(); 48362 } 48363 }; 48364 /** 48365 * attach Drag and Drop Events 48366 */ 48367 Dropzone.prototype.attachDragAndDropEvent = function () { 48368 var _this = this; 48369 var collection = $$1(); 48370 var $dropzoneMessage = this.$dropzone.find('.note-dropzone-message'); 48371 this.documentEventHandlers.onDragenter = function (e) { 48372 var isCodeview = _this.context.invoke('codeview.isActivated'); 48373 var hasEditorSize = _this.$editor.width() > 0 && _this.$editor.height() > 0; 48374 if (!isCodeview && !collection.length && hasEditorSize) { 48375 _this.$editor.addClass('dragover'); 48376 _this.$dropzone.width(_this.$editor.width()); 48377 _this.$dropzone.height(_this.$editor.height()); 48378 $dropzoneMessage.text(_this.lang.image.dragImageHere); 48379 } 48380 collection = collection.add(e.target); 48381 }; 48382 this.documentEventHandlers.onDragleave = function (e) { 48383 collection = collection.not(e.target); 48384 if (!collection.length) { 48385 _this.$editor.removeClass('dragover'); 48386 } 48387 }; 48388 this.documentEventHandlers.onDrop = function () { 48389 collection = $$1(); 48390 _this.$editor.removeClass('dragover'); 48391 }; 48392 // show dropzone on dragenter when dragging a object to document 48393 // -but only if the editor is visible, i.e. has a positive width and height 48394 this.$eventListener.on('dragenter', this.documentEventHandlers.onDragenter) 48395 .on('dragleave', this.documentEventHandlers.onDragleave) 48396 .on('drop', this.documentEventHandlers.onDrop); 48397 // change dropzone's message on hover. 48398 this.$dropzone.on('dragenter', function () { 48399 _this.$dropzone.addClass('hover'); 48400 $dropzoneMessage.text(_this.lang.image.dropImage); 48401 }).on('dragleave', function () { 48402 _this.$dropzone.removeClass('hover'); 48403 $dropzoneMessage.text(_this.lang.image.dragImageHere); 48404 }); 48405 // attach dropImage 48406 this.$dropzone.on('drop', function (event) { 48407 var dataTransfer = event.originalEvent.dataTransfer; 48408 // stop the browser from opening the dropped content 48409 event.preventDefault(); 48410 if (dataTransfer && dataTransfer.files && dataTransfer.files.length) { 48411 _this.$editable.focus(); 48412 _this.context.invoke('editor.insertImagesOrCallback', dataTransfer.files); 48413 } 48414 else { 48415 $$1.each(dataTransfer.types, function (idx, type) { 48416 var content = dataTransfer.getData(type); 48417 if (type.toLowerCase().indexOf('text') > -1) { 48418 _this.context.invoke('editor.pasteHTML', content); 48419 } 48420 else { 48421 $$1(content).each(function (idx, item) {
48422 _this.context.invoke('editor.insertNode', item); 48423 }); 48424 } 48425 }); 48426 } 48427 }).on('dragover', false); // prevent default dragover event 48428 }; 48429 Dropzone.prototype.destroy = function () { 48430 var _this = this; 48431 Object.keys(this.documentEventHandlers).forEach(function (key) { 48432 _this.$eventListener.off(key.substr(2).toLowerCase(), _this.documentEventHandlers[key]); 48433 }); 48434 this.documentEventHandlers = {}; 48435 }; 48436 return Dropzone; 48437}()); 48438 48439var CodeMirror; 48440if (env.hasCodeMirror) { 48441 if (env.isSupportAmd) { 48442 require(['codemirror'], function (cm) { 48443 CodeMirror = cm; 48444 }); 48445 } 48446 else { 48447 CodeMirror = window.CodeMirror; 48448 } 48449} 48450/** 48451 * @class Codeview 48452 */ 48453var CodeView = /** @class */ (function () { 48454 function CodeView(context) { 48455 this.context = context; 48456 this.$editor = context.layoutInfo.editor; 48457 this.$editable = context.layoutInfo.editable; 48458 this.$codable = context.layoutInfo.codable; 48459 this.options = context.options; 48460 } 48461 CodeView.prototype.sync = function () { 48462 var isCodeview = this.isActivated(); 48463 if (isCodeview && env.hasCodeMirror) { 48464 this.$codable.data('cmEditor').save(); 48465 } 48466 }; 48467 /** 48468 * @return {Boolean} 48469 */ 48470 CodeView.prototype.isActivated = function () { 48471 return this.$editor.hasClass('codeview'); 48472 }; 48473 /** 48474 * toggle codeview 48475 */ 48476 CodeView.prototype.toggle = function () { 48477 if (this.isActivated()) { 48478 this.deactivate(); 48479 } 48480 else { 48481 this.activate(); 48482 } 48483 this.context.triggerEvent('codeview.toggled'); 48484 }; 48485 /** 48486 * activate code view 48487 */ 48488 CodeView.prototype.activate = function () { 48489 var _this = this; 48490 this.$codable.val(dom.html(this.$editable, this.options.prettifyHtml)); 48491 this.$codable.height(this.$editable.height()); 48492 this.context.invoke('toolbar.updateCodeview', true); 48493 this.$editor.addClass('codeview'); 48494 this.$codable.focus(); 48495 // activate CodeMirror as codable 48496 if (env.hasCodeMirror) { 48497 var cmEditor_1 = CodeMirror.fromTextArea(this.$codable[0], this.options.codemirror); 48498 // CodeMirror TernServer 48499 if (this.options.codemirror.tern) { 48500 var server_1 = new CodeMirror.TernServer(this.options.codemirror.tern); 48501 cmEditor_1.ternServer = server_1; 48502 cmEditor_1.on('cursorActivity', function (cm) { 48503 server_1.updateArgHints(cm); 48504 }); 48505 } 48506 cmEditor_1.on('blur', function (event) { 48507 _this.context.triggerEvent('blur.codeview', cmEditor_1.getValue(), event); 48508 }); 48509 // CodeMirror hasn't Padding. 48510 cmEditor_1.setSize(null, this.$editable.outerHeight()); 48511 this.$codable.data('cmEditor', cmEditor_1); 48512 } 48513 else { 48514 this.$codable.on('blur', function (event) { 48515 _this.context.triggerEvent('blur.codeview', _this.$codable.val(), event); 48516 }); 48517 } 48518 }; 48519 /** 48520 * deactivate code view 48521 */ 48522 CodeView.prototype.deactivate = function () { 48523 // deactivate CodeMirror as codable 48524 if (env.hasCodeMirror) { 48525 var cmEditor = this.$codable.data('cmEditor'); 48526 this.$codable.val(cmEditor.getValue()); 48527 cmEditor.toTextArea(); 48528 } 48529 var value = dom.value(this.$codable, this.options.prettifyHtml) || dom.emptyPara; 48530 var isChange = this.$editable.html() !== value; 48531 this.$editable.html(value); 48532 this.$editable.height(this.options.height ? this.$codable.height() : 'auto'); 48533 this.$editor.removeClass('codeview'); 48534 if (isChange) { 48535 this.context.triggerEvent('change', this.$editable.html(), this.$editable); 48536 } 48537 this.$editable.focus(); 48538 this.context.invoke('toolbar.updateCodeview', false); 48539 }; 48540 CodeView.prototype.destroy = function () { 48541 if (this.isActivated()) { 48542 this.deactivate(); 48543 } 48544 }; 48545 return CodeView; 48546}()); 48547 48548var EDITABLE_PADDING = 24; 48549var Statusbar = /** @class */ (function () { 48550 function Statusbar(context) { 48551 this.$document = $$1(document); 48552 this.$statusbar = context.layoutInfo.statusbar; 48553 this.$editable = context.layoutInfo.editable; 48554 this.options = context.options; 48555 } 48556 Statusbar.prototype.initialize = function () { 48557 var _this = this; 48558 if (this.options.airMode || this.options.disableResizeEditor) { 48559 this.destroy(); 48560 return; 48561 } 48562 this.$statusbar.on('mousedown', function (event) { 48563 event.preventDefault(); 48564 event.stopPropagation(); 48565 var editableTop = _this.$editable.offset().top - _this.$document.scrollTop(); 48566 var onMouseMove = function (event) { 48567 var height = event.clientY - (editableTop + EDITABLE_PADDING); 48568 height = (_this.options.minheight > 0) ? Math.max(height, _this.options.minheight) : height; 48569 height = (_this.options.maxHeight > 0) ? Math.min(height, _this.options.maxHeight) : height; 48570 _this.$editable.height(height); 48571 }; 48572 _this.$document.on('mousemove', onMouseMove).one('mouseup', function () { 48573 _this.$document.off('mousemove', onMouseMove); 48574 }); 48575 }); 48576 }; 48577 Statusbar.prototype.destroy = function () { 48578 this.$statusbar.off(); 48579 this.$statusbar.addClass('locked'); 48580 }; 48581 return Statusbar; 48582}()); 48583 48584var Fullscreen = /** @class */ (function () { 48585 function Fullscreen(context) { 48586 var _this = this; 48587 this.context = context; 48588 this.$editor = context.layoutInfo.editor; 48589 this.$toolbar = context.layoutInfo.toolbar; 48590 this.$editable = context.layoutInfo.editable; 48591 this.$codable = context.layoutInfo.codable; 48592 this.$window = $$1(window); 48593 this.$scrollbar = $$1('html, body'); 48594 this.onResize = function () { 48595 _this.resizeTo({ 48596 h: _this.$window.height() - _this.$toolbar.outerHeight() 48597 }); 48598 }; 48599 } 48600 Fullscreen.prototype.resizeTo = function (size) { 48601 this.$editable.css('height', size.h); 48602 this.$codable.css('height', size.h); 48603 if (this.$codable.data('cmeditor')) { 48604 this.$codable.data('cmeditor').setsize(null, size.h); 48605 } 48606 }; 48607 /** 48608 * toggle fullscreen 48609 */ 48610 Fullscreen.prototype.toggle = function () { 48611 this.$editor.toggleClass('fullscreen'); 48612 if (this.isFullscreen()) {
48613 this.$editable.data('orgHeight', this.$editable.css('height')); 48614 this.$window.on('resize', this.onResize).trigger('resize'); 48615 this.$scrollbar.css('overflow', 'hidden'); 48616 } 48617 else { 48618 this.$window.off('resize', this.onResize); 48619 this.resizeTo({ h: this.$editable.data('orgHeight') }); 48620 this.$scrollbar.css('overflow', 'visible'); 48621 } 48622 this.context.invoke('toolbar.updateFullscreen', this.isFullscreen()); 48623 }; 48624 Fullscreen.prototype.isFullscreen = function () { 48625 return this.$editor.hasClass('fullscreen'); 48626 }; 48627 return Fullscreen; 48628}()); 48629 48630var Handle = /** @class */ (function () { 48631 function Handle(context) { 48632 var _this = this; 48633 this.context = context; 48634 this.$document = $$1(document); 48635 this.$editingArea = context.layoutInfo.editingArea; 48636 this.options = context.options; 48637 this.lang = this.options.langInfo; 48638 this.events = { 48639 'summernote.mousedown': function (we, e) { 48640 if (_this.update(e.target)) { 48641 e.preventDefault(); 48642 } 48643 }, 48644 'summernote.keyup summernote.scroll summernote.change summernote.dialog.shown': function () { 48645 _this.update(); 48646 }, 48647 'summernote.disable': function () { 48648 _this.hide(); 48649 }, 48650 'summernote.codeview.toggled': function () { 48651 _this.update(); 48652 } 48653 }; 48654 } 48655 Handle.prototype.initialize = function () { 48656 var _this = this; 48657 this.$handle = $$1([ 48658 '<div class="note-handle">', 48659 '<div class="note-control-selection">', 48660 '<div class="note-control-selection-bg"></div>', 48661 '<div class="note-control-holder note-control-nw"></div>', 48662 '<div class="note-control-holder note-control-ne"></div>', 48663 '<div class="note-control-holder note-control-sw"></div>', 48664 '<div class="', 48665 (this.options.disableResizeImage ? 'note-control-holder' : 'note-control-sizing'), 48666 ' note-control-se"></div>', 48667 (this.options.disableResizeImage ? '' : '<div class="note-control-selection-info"></div>'), 48668 '</div>', 48669 '</div>' 48670 ].join('')).prependTo(this.$editingArea); 48671 this.$handle.on('mousedown', function (event) { 48672 if (dom.isControlSizing(event.target)) { 48673 event.preventDefault(); 48674 event.stopPropagation(); 48675 var $target_1 = _this.$handle.find('.note-control-selection').data('target'); 48676 var posStart_1 = $target_1.offset(); 48677 var scrollTop_1 = _this.$document.scrollTop(); 48678 var onMouseMove_1 = function (event) { 48679 _this.context.invoke('editor.resizeTo', { 48680 x: event.clientX - posStart_1.left, 48681 y: event.clientY - (posStart_1.top - scrollTop_1) 48682 }, $target_1, !event.shiftKey); 48683 _this.update($target_1[0]); 48684 }; 48685 _this.$document 48686 .on('mousemove', onMouseMove_1) 48687 .one('mouseup', function (e) { 48688 e.preventDefault(); 48689 _this.$document.off('mousemove', onMouseMove_1); 48690 _this.context.invoke('editor.afterCommand'); 48691 }); 48692 if (!$target_1.data('ratio')) { 48693 $target_1.data('ratio', $target_1.height() / $target_1.width()); 48694 } 48695 } 48696 }); 48697 // Listen for scrolling on the handle overlay. 48698 this.$handle.on('wheel', function (e) { 48699 e.preventDefault(); 48700 _this.update(); 48701 }); 48702 }; 48703 Handle.prototype.destroy = function () { 48704 this.$handle.remove(); 48705 }; 48706 Handle.prototype.update = function (target) { 48707 if (this.context.isDisabled()) { 48708 return false; 48709 } 48710 var isImage = dom.isImg(target); 48711 var $selection = this.$handle.find('.note-control-selection');
48712 this.context.invoke('imagePopover.update', target); 48713 if (isImage) { 48714 var $image = $$1(target); 48715 var position = $image.position(); 48716 var pos = { 48717 left: position.left + parseInt($image.css('marginLeft'), 10), 48718 top: position.top + parseInt($image.css('marginTop'), 10) 48719 }; 48720 // exclude margin 48721 var imageSize = { 48722 w: $image.outerWidth(false), 48723 h: $image.outerHeight(false) 48724 }; 48725 $selection.css({ 48726 display: 'block', 48727 left: pos.left, 48728 top: pos.top, 48729 width: imageSize.w, 48730 height: imageSize.h 48731 }).data('target', $image); // save current image element. 48732 var origImageObj = new Image(); 48733 origImageObj.src = $image.attr('src'); 48734 var sizingText = imageSize.w + 'x' + imageSize.h + ' (' + this.lang.image.original + ': ' + origImageObj.width + 'x' + origImageObj.height + ')'; 48735 $selection.find('.note-control-selection-info').text(sizingText); 48736 this.context.invoke('editor.saveTarget', target); 48737 } 48738 else { 48739 this.hide(); 48740 } 48741 return isImage; 48742 }; 48743 /** 48744 * hide 48745 * 48746 * @param {jQuery} $handle 48747 */ 48748 Handle.prototype.hide = function () { 48749 this.context.invoke('editor.clearTarget'); 48750 this.$handle.children().hide(); 48751 }; 48752 return Handle; 48753}()); 48754 48755var defaultScheme = 'http://'; 48756var linkPattern = /^([A-Za-z][A-Za-z0-9+-.]*\:[\/\/]?|mailto:[A-Z0-9._%+-]+@)?(www\.)?(.+)$/i; 48757var AutoLink = /** @class */ (function () { 48758 function AutoLink(context) { 48759 var _this = this; 48760 this.context = context; 48761 this.events = { 48762 'summernote.keyup': function (we, e) { 48763 if (!e.isDefaultPrevented()) { 48764 _this.handleKeyup(e); 48765 } 48766 }, 48767 'summernote.keydown': function (we, e) { 48768 _this.handleKeydown(e); 48769 } 48770 }; 48771 } 48772 AutoLink.prototype.initialize = function () { 48773 this.lastWordRange = null; 48774 }; 48775 AutoLink.prototype.destroy = function () { 48776 this.lastWordRange = null; 48777 }; 48778 AutoLink.prototype.replace = function () { 48779 if (!this.lastWordRange) { 48780 return; 48781 } 48782 var keyword = this.lastWordRange.toString(); 48783 var match = keyword.match(linkPattern); 48784 if (match && (match[1] || match[2])) { 48785 var link = match[1] ? keyword : defaultScheme + keyword; 48786 var node = $$1('<a />').html(keyword).attr('href', link)[0]; 48787 this.lastWordRange.insertNode(node); 48788 this.lastWordRange = null; 48789 this.context.invoke('editor.focus'); 48790 } 48791 }; 48792 AutoLink.prototype.handleKeydown = function (e) { 48793 if (lists.contains([key.code.ENTER, key.code.SPACE], e.keyCode)) { 48794 var wordRange = this.context.invoke('editor.createRange').getWordRange(); 48795 this.lastWordRange = wordRange; 48796 } 48797 }; 48798 AutoLink.prototype.handleKeyup = function (e) { 48799 if (lists.contains([key.code.ENTER, key.code.SPACE], e.keyCode)) { 48800 this.replace(); 48801 } 48802 }; 48803 return AutoLink; 48804}()); 48805 48806/** 48807 * textarea auto sync. 48808 */ 48809var AutoSync = /** @class */ (function () { 48810 function AutoSync(context) { 48811 var _this = this; 48812 this.$note = context.layoutInfo.note; 48813 this.events = { 48814 'summernote.change': function () { 48815 _this.$note.val(context.invoke('code')); 48816 } 48817 }; 48818 } 48819 AutoSync.prototype.shouldInitialize = function () { 48820 return dom.isTextarea(this.$note[0]); 48821 }; 48822 return AutoSync; 48823}()); 48824 48825var Placeholder = /** @class */ (function () { 48826 function Placeholder(context) { 48827 var _this = this; 48828 this.context = context; 48829 this.$editingArea = context.layoutInfo.editingArea; 48830 this.options = context.options; 48831 this.events = { 48832 'summernote.init summernote.change': function () { 48833 _this.update(); 48834 }, 48835 'summernote.codeview.toggled': function () { 48836 _this.update(); 48837 } 48838 }; 48839 } 48840 Placeholder.prototype.shouldInitialize = function () { 48841 return !!this.options.placeholder; 48842 }; 48843 Placeholder.prototype.initialize = function () { 48844 var _this = this; 48845 this.$placeholder = $$1('<div class="note-placeholder">'); 48846 this.$placeholder.on('click', function () {
48847 _this.context.invoke('focus'); 48848 }).text(this.options.placeholder).prependTo(this.$editingArea); 48849 this.update(); 48850 }; 48851 Placeholder.prototype.destroy = function () { 48852 this.$placeholder.remove(); 48853 }; 48854 Placeholder.prototype.update = function () { 48855 var isShow = !this.context.invoke('codeview.isActivated') && this.context.invoke('editor.isEmpty'); 48856 this.$placeholder.toggle(isShow); 48857 }; 48858 return Placeholder; 48859}()); 48860 48861var Buttons = /** @class */ (function () { 48862 function Buttons(context) { 48863 this.ui = $$1.summernote.ui; 48864 this.context = context; 48865 this.$toolbar = context.layoutInfo.toolbar; 48866 this.options = context.options; 48867 this.lang = this.options.langInfo; 48868 this.invertedKeyMap = func.invertObject(this.options.keyMap[env.isMac ? 'mac' : 'pc']); 48869 } 48870 Buttons.prototype.representShortcut = function (editorMethod) { 48871 var shortcut = this.invertedKeyMap[editorMethod]; 48872 if (!this.options.shortcuts || !shortcut) { 48873 return ''; 48874 } 48875 if (env.isMac) { 48876 shortcut = shortcut.replace('CMD', '⌘').replace('SHIFT', '⇧'); 48877 } 48878 shortcut = shortcut.replace('BACKSLASH', '\\') 48879 .replace('SLASH', '/') 48880 .replace('LEFTBRACKET', '[') 48881 .replace('RIGHTBRACKET', ']'); 48882 return ' (' + shortcut + ')'; 48883 }; 48884 Buttons.prototype.button = function (o) { 48885 if (!this.options.tooltip && o.tooltip) { 48886 delete o.tooltip; 48887 } 48888 o.container = this.options.container; 48889 return this.ui.button(o); 48890 }; 48891 Buttons.prototype.initialize = function () { 48892 this.addToolbarButtons(); 48893 this.addImagePopoverButtons(); 48894 this.addLinkPopoverButtons(); 48895 this.addTablePopoverButtons(); 48896 this.fontInstalledMap = {}; 48897 }; 48898 Buttons.prototype.destroy = function () { 48899 delete this.fontInstalledMap; 48900 }; 48901 Buttons.prototype.isFontInstalled = function (name) { 48902 if (!this.fontInstalledMap.hasOwnProperty(name)) { 48903 this.fontInstalledMap[name] = env.isFontInstalled(name) || 48904 lists.contains(this.options.fontNamesIgnoreCheck, name); 48905 } 48906 return this.fontInstalledMap[name]; 48907 }; 48908 Buttons.prototype.isFontDeservedToAdd = function (name) { 48909 var genericFamilies = ['sans-serif', 'serif', 'monospace', 'cursive', 'fantasy']; 48910 name = name.toLowerCase(); 48911 return ((name !== '') && this.isFontInstalled(name) && ($$1.inArray(name, genericFamilies) === -1)); 48912 }; 48913 Buttons.prototype.addToolbarButtons = function () { 48914 var _this = this; 48915 this.context.memo('button.style', function () { 48916 return _this.ui.buttonGroup([ 48917 _this.button({ 48918 className: 'dropdown-toggle', 48919 contents: _this.ui.dropdownButtonContents(_this.ui.icon(_this.options.icons.magic), _this.options), 48920 tooltip: _this.lang.style.style, 48921 data: { 48922 toggle: 'dropdown' 48923 } 48924 }), 48925 _this.ui.dropdown({ 48926 className: 'dropdown-style', 48927 items: _this.options.styleTags, 48928 title: _this.lang.style.style, 48929 template: function (item) { 48930 if (typeof item === 'string') { 48931 item = { tag: item, title: (_this.lang.style.hasOwnProperty(item) ? _this.lang.style[item] : item) }; 48932 } 48933 var tag = item.tag; 48934 var title = item.title; 48935 var style = item.style ? ' style="' + item.style + '" ' : ''; 48936 var className = item.className ? ' class="' + item.className + '"' : ''; 48937 return '<' + tag + style + className + '>' + title + '</' + tag + '>'; 48938 }, 48939 click: _this.context.createInvokeHandler('editor.formatBlock') 48940 }) 48941 ]).render(); 48942 }); 48943 var _loop_1 = function (styleIdx, styleLen) { 48944 var item = this_1.options.styleTags[styleIdx]; 48945 this_1.context.memo('button.style.' + item, function () { 48946 return _this.button({ 48947 className: 'note-btn-style-' + item, 48948 contents: '<div data-value="' + item + '">' + item.toUpperCase() + '</div>', 48949 tooltip: _this.lang.style[item], 48950 click: _this.context.createInvokeHandler('editor.formatBlock') 48951 }).render(); 48952 }); 48953 }; 48954 var this_1 = this; 48955 for (var styleIdx = 0, styleLen = this.options.styleTags.length; styleIdx < styleLen; styleIdx++) { 48956 _loop_1(styleIdx, styleLen); 48957 } 48958 this.context.memo('button.bold', function () { 48959 return _this.button({ 48960 className: 'note-btn-bold', 48961 contents: _this.ui.icon(_this.options.icons.bold), 48962 tooltip: _this.lang.font.bold + _this.representShortcut('bold'),
48963 click: _this.context.createInvokeHandlerAndUpdateState('editor.bold') 48964 }).render(); 48965 }); 48966 this.context.memo('button.italic', function () { 48967 return _this.button({ 48968 className: 'note-btn-italic', 48969 contents: _this.ui.icon(_this.options.icons.italic), 48970 tooltip: _this.lang.font.italic + _this.representShortcut('italic'), 48971 click: _this.context.createInvokeHandlerAndUpdateState('editor.italic') 48972 }).render(); 48973 }); 48974 this.context.memo('button.underline', function () { 48975 return _this.button({ 48976 className: 'note-btn-underline', 48977 contents: _this.ui.icon(_this.options.icons.underline), 48978 tooltip: _this.lang.font.underline + _this.representShortcut('underline'), 48979 click: _this.context.createInvokeHandlerAndUpdateState('editor.underline') 48980 }).render(); 48981 }); 48982 this.context.memo('button.clear', function () { 48983 return _this.button({ 48984 contents: _this.ui.icon(_this.options.icons.eraser), 48985 tooltip: _this.lang.font.clear + _this.representShortcut('removeFormat'), 48986 click: _this.context.createInvokeHandler('editor.removeFormat') 48987 }).render(); 48988 }); 48989 this.context.memo('button.strikethrough', function () { 48990 return _this.button({ 48991 className: 'note-btn-strikethrough', 48992 contents: _this.ui.icon(_this.options.icons.strikethrough), 48993 tooltip: _this.lang.font.strikethrough + _this.representShortcut('strikethrough'), 48994 click: _this.context.createInvokeHandlerAndUpdateState('editor.strikethrough') 48995 }).render(); 48996 }); 48997 this.context.memo('button.superscript', function () { 48998 return _this.button({ 48999 className: 'note-btn-superscript', 49000 contents: _this.ui.icon(_this.options.icons.superscript), 49001 tooltip: _this.lang.font.superscript, 49002 click: _this.context.createInvokeHandlerAndUpdateState('editor.superscript') 49003 }).render(); 49004 }); 49005 this.context.memo('button.subscript', function () { 49006 return _this.button({ 49007 className: 'note-btn-subscript', 49008 contents: _this.ui.icon(_this.options.icons.subscript), 49009 tooltip: _this.lang.font.subscript, 49010 click: _this.context.createInvokeHandlerAndUpdateState('editor.subscript') 49011 }).render(); 49012 }); 49013 this.context.memo('button.fontname', function () { 49014 var styleInfo = _this.context.invoke('editor.currentStyle'); 49015 // Add 'default' fonts into the fontnames array if not exist 49016 $$1.each(styleInfo['font-family'].split(','), function (idx, fontname) { 49017 fontname = fontname.trim().replace(/['"]+/g, ''); 49018 if (_this.isFontDeservedToAdd(fontname)) { 49019 if ($$1.inArray(fontname, _this.options.fontNames) === -1) { 49020 _this.options.fontNames.push(fontname); 49021 } 49022 } 49023 }); 49024 return _this.ui.buttonGroup([ 49025 _this.button({ 49026 className: 'dropdown-toggle', 49027 contents: _this.ui.dropdownButtonContents('<span class="note-current-fontname"/>', _this.options), 49028 tooltip: _this.lang.font.name, 49029 data: { 49030 toggle: 'dropdown' 49031 } 49032 }), 49033 _this.ui.dropdownCheck({ 49034 className: 'dropdown-fontname', 49035 checkClassName: _this.options.icons.menuCheck, 49036 items: _this.options.fontNames.filter(_this.isFontInstalled.bind(_this)), 49037 title: _this.lang.font.name, 49038 template: function (item) { 49039 return '<span style="font-family: \'' + item + '\'">' + item + '</span>'; 49040 }, 49041 click: _this.context.createInvokeHandlerAndUpdateState('editor.fontName') 49042 }) 49043 ]).render(); 49044 }); 49045 this.context.memo('button.fontsize', function () { 49046 return _this.ui.buttonGroup([ 49047 _this.button({ 49048 className: 'dropdown-toggle', 49049 contents: _this.ui.dropdownButtonContents('<span class="note-current-fontsize"/>', _this.options), 49050 tooltip: _this.lang.font.size, 49051 data: { 49052 toggle: 'dropdown' 49053 } 49054 }), 49055 _this.ui.dropdownCheck({ 49056 className: 'dropdown-fontsize', 49057 checkClassName: _this.options.icons.menuCheck, 49058 items: _this.options.fontSizes, 49059 title: _this.lang.font.size, 49060 click: _this.context.createInvokeHandlerAndUpdateState('editor.fontSize') 49061 }) 49062 ]).render(); 49063 }); 49064 this.context.memo('button.color', function () { 49065 return _this.ui.buttonGroup({ 49066 className: 'note-color', 49067 children: [ 49068 _this.button({ 49069 className: 'note-current-color-button', 49070 contents: _this.ui.icon(_this.options.icons.font + ' note-recent-color'), 49071 tooltip: _this.lang.color.recent, 49072 click: function (e) { 49073 var $button = $$1(e.currentTarget);
vendor: 16,384 bytes, lines 49074-49395
49074 _this.context.invoke('editor.color', { 49075 backColor: $button.attr('data-backColor'), 49076 foreColor: $button.attr('data-foreColor') 49077 }); 49078 }, 49079 callback: function ($button) { 49080 var $recentColor = $button.find('.note-recent-color'); 49081 $recentColor.css('background-color', '#FFFF00'); 49082 $button.attr('data-backColor', '#FFFF00'); 49083 } 49084 }), 49085 _this.button({ 49086 className: 'dropdown-toggle', 49087 contents: _this.ui.dropdownButtonContents('', _this.options), 49088 tooltip: _this.lang.color.more, 49089 data: { 49090 toggle: 'dropdown' 49091 } 49092 }), 49093 _this.ui.dropdown({ 49094 items: [ 49095 '<div class="note-palette">', 49096 ' <div class="note-palette-title">' + _this.lang.color.background + '</div>', 49097 ' <div>', 49098 ' <button type="button" class="note-color-reset btn btn-light" data-event="backColor" data-value="inherit">', 49099 _this.lang.color.transparent, 49100 ' </button>', 49101 ' </div>', 49102 ' <div class="note-holder" data-event="backColor"/>', 49103 '</div>', 49104 '<div class="note-palette">', 49105 ' <div class="note-palette-title">' + _this.lang.color.foreground + '</div>', 49106 ' <div>', 49107 ' <button type="button" class="note-color-reset btn btn-light" data-event="removeFormat" data-value="foreColor">', 49108 _this.lang.color.resetToDefault, 49109 ' </button>', 49110 ' </div>', 49111 ' <div class="note-holder" data-event="foreColor"/>', 49112 '</div>' 49113 ].join(''), 49114 callback: function ($dropdown) { 49115 $dropdown.find('.note-holder').each(function (idx, item) { 49116 var $holder = $$1(item); 49117 $holder.append(_this.ui.palette({ 49118 colors: _this.options.colors, 49119 colorsName: _this.options.colorsName, 49120 eventName: $holder.data('event'), 49121 container: _this.options.container, 49122 tooltip: _this.options.tooltip 49123 }).render()); 49124 }); 49125 }, 49126 click: function (event) { 49127 var $button = $$1(event.target); 49128 var eventName = $button.data('event'); 49129 var value = $button.data('value'); 49130 if (eventName && value) { 49131 var key = eventName === 'backColor' ? 'background-color' : 'color'; 49132 var $color = $button.closest('.note-color').find('.note-recent-color'); 49133 var $currentButton = $button.closest('.note-color').find('.note-current-color-button'); 49134 $color.css(key, value); 49135 $currentButton.attr('data-' + eventName, value); 49136 _this.context.invoke('editor.' + eventName, value); 49137 } 49138 } 49139 }) 49140 ] 49141 }).render(); 49142 }); 49143 this.context.memo('button.ul', function () { 49144 return _this.button({ 49145 contents: _this.ui.icon(_this.options.icons.unorderedlist), 49146 tooltip: _this.lang.lists.unordered + _this.representShortcut('insertUnorderedList'), 49147 click: _this.context.createInvokeHandler('editor.insertUnorderedList') 49148 }).render(); 49149 }); 49150 this.context.memo('button.ol', function () { 49151 return _this.button({ 49152 contents: _this.ui.icon(_this.options.icons.orderedlist), 49153 tooltip: _this.lang.lists.ordered + _this.representShortcut('insertOrderedList'), 49154 click: _this.context.createInvokeHandler('editor.insertOrderedList') 49155 }).render(); 49156 }); 49157 var justifyLeft = this.button({ 49158 contents: this.ui.icon(this.options.icons.alignLeft), 49159 tooltip: this.lang.paragraph.left + this.representShortcut('justifyLeft'), 49160 click: this.context.createInvokeHandler('editor.justifyLeft') 49161 }); 49162 var justifyCenter = this.button({ 49163 contents: this.ui.icon(this.options.icons.alignCenter), 49164 tooltip: this.lang.paragraph.center + this.representShortcut('justifyCenter'), 49165 click: this.context.createInvokeHandler('editor.justifyCenter') 49166 }); 49167 var justifyRight = this.button({ 49168 contents: this.ui.icon(this.options.icons.alignRight), 49169 tooltip: this.lang.paragraph.right + this.representShortcut('justifyRight'), 49170 click: this.context.createInvokeHandler('editor.justifyRight') 49171 }); 49172 var justifyFull = this.button({ 49173 contents: this.ui.icon(this.options.icons.alignJustify), 49174 tooltip: this.lang.paragraph.justify + this.representShortcut('justifyFull'), 49175 click: this.context.createInvokeHandler('editor.justifyFull') 49176 }); 49177 var outdent = this.button({ 49178 contents: this.ui.icon(this.options.icons.outdent), 49179 tooltip: this.lang.paragraph.outdent + this.representShortcut('outdent'), 49180 click: this.context.createInvokeHandler('editor.outdent') 49181 }); 49182 var indent = this.button({ 49183 contents: this.ui.icon(this.options.icons.indent), 49184 tooltip: this.lang.paragraph.indent + this.representShortcut('indent'), 49185 click: this.context.createInvokeHandler('editor.indent') 49186 }); 49187 this.context.memo('button.justifyLeft', func.invoke(justifyLeft, 'render')); 49188 this.context.memo('button.justifyCenter', func.invoke(justifyCenter, 'render')); 49189 this.context.memo('button.justifyRight', func.invoke(justifyRight, 'render')); 49190 this.context.memo('button.justifyFull', func.invoke(justifyFull, 'render')); 49191 this.context.memo('button.outdent', func.invoke(outdent, 'render')); 49192 this.context.memo('button.indent', func.invoke(indent, 'render')); 49193 this.context.memo('button.paragraph', function () { 49194 return _this.ui.buttonGroup([ 49195 _this.button({ 49196 className: 'dropdown-toggle', 49197 contents: _this.ui.dropdownButtonContents(_this.ui.icon(_this.options.icons.alignLeft), _this.options), 49198 tooltip: _this.lang.paragraph.paragraph, 49199 data: { 49200 toggle: 'dropdown' 49201 } 49202 }), 49203 _this.ui.dropdown([ 49204 _this.ui.buttonGroup({ 49205 className: 'note-align', 49206 children: [justifyLeft, justifyCenter, justifyRight, justifyFull] 49207 }), 49208 _this.ui.buttonGroup({ 49209 className: 'note-list', 49210 children: [outdent, indent] 49211 }) 49212 ]) 49213 ]).render(); 49214 }); 49215 this.context.memo('button.height', function () { 49216 return _this.ui.buttonGroup([ 49217 _this.button({ 49218 className: 'dropdown-toggle', 49219 contents: _this.ui.dropdownButtonContents(_this.ui.icon(_this.options.icons.textHeight), _this.options), 49220 tooltip: _this.lang.font.height, 49221 data: { 49222 toggle: 'dropdown' 49223 } 49224 }), 49225 _this.ui.dropdownCheck({ 49226 items: _this.options.lineHeights, 49227 checkClassName: _this.options.icons.menuCheck, 49228 className: 'dropdown-line-height', 49229 title: _this.lang.font.height, 49230 click: _this.context.createInvokeHandler('editor.lineHeight') 49231 }) 49232 ]).render(); 49233 }); 49234 this.context.memo('button.table', function () { 49235 return _this.ui.buttonGroup([ 49236 _this.button({ 49237 className: 'dropdown-toggle', 49238 contents: _this.ui.dropdownButtonContents(_this.ui.icon(_this.options.icons.table), _this.options), 49239 tooltip: _this.lang.table.table, 49240 data: { 49241 toggle: 'dropdown' 49242 } 49243 }), 49244 _this.ui.dropdown({ 49245 title: _this.lang.table.table, 49246 className: 'note-table', 49247 items: [ 49248 '<div class="note-dimension-picker">', 49249 ' <div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"/>', 49250 ' <div class="note-dimension-picker-highlighted"/>', 49251 ' <div class="note-dimension-picker-unhighlighted"/>', 49252 '</div>', 49253 '<div class="note-dimension-display">1 x 1</div>' 49254 ].join('') 49255 }) 49256 ], { 49257 callback: function ($node) { 49258 var $catcher = $node.find('.note-dimension-picker-mousecatcher'); 49259 $catcher.css({ 49260 width: _this.options.insertTableMaxSize.col + 'em', 49261 height: _this.options.insertTableMaxSize.row + 'em' 49262 }).mousedown(_this.context.createInvokeHandler('editor.insertTable')) 49263 .on('mousemove', _this.tableMoveHandler.bind(_this)); 49264 } 49265 }).render(); 49266 }); 49267 this.context.memo('button.link', function () { 49268 return _this.button({ 49269 contents: _this.ui.icon(_this.options.icons.link), 49270 tooltip: _this.lang.link.link + _this.representShortcut('linkDialog.show'), 49271 click: _this.context.createInvokeHandler('linkDialog.show') 49272 }).render(); 49273 }); 49274 this.context.memo('button.picture', function () { 49275 return _this.button({ 49276 contents: _this.ui.icon(_this.options.icons.picture), 49277 tooltip: _this.lang.image.image, 49278 click: _this.context.createInvokeHandler('imageDialog.show') 49279 }).render(); 49280 }); 49281 this.context.memo('button.video', function () { 49282 return _this.button({ 49283 contents: _this.ui.icon(_this.options.icons.video), 49284 tooltip: _this.lang.video.video, 49285 click: _this.context.createInvokeHandler('videoDialog.show') 49286 }).render(); 49287 }); 49288 this.context.memo('button.hr', function () { 49289 return _this.button({ 49290 contents: _this.ui.icon(_this.options.icons.minus), 49291 tooltip: _this.lang.hr.insert + _this.representShortcut('insertHorizontalRule'), 49292 click: _this.context.createInvokeHandler('editor.insertHorizontalRule') 49293 }).render(); 49294 }); 49295 this.context.memo('button.fullscreen', function () { 49296 return _this.button({ 49297 className: 'btn-fullscreen', 49298 contents: _this.ui.icon(_this.options.icons.arrowsAlt), 49299 tooltip: _this.lang.options.fullscreen, 49300 click: _this.context.createInvokeHandler('fullscreen.toggle') 49301 }).render(); 49302 }); 49303 this.context.memo('button.codeview', function () { 49304 return _this.button({ 49305 className: 'btn-codeview', 49306 contents: _this.ui.icon(_this.options.icons.code), 49307 tooltip: _this.lang.options.codeview, 49308 click: _this.context.createInvokeHandler('codeview.toggle') 49309 }).render(); 49310 }); 49311 this.context.memo('button.redo', function () { 49312 return _this.button({ 49313 contents: _this.ui.icon(_this.options.icons.redo), 49314 tooltip: _this.lang.history.redo + _this.representShortcut('redo'), 49315 click: _this.context.createInvokeHandler('editor.redo') 49316 }).render(); 49317 }); 49318 this.context.memo('button.undo', function () { 49319 return _this.button({ 49320 contents: _this.ui.icon(_this.options.icons.undo), 49321 tooltip: _this.lang.history.undo + _this.representShortcut('undo'), 49322 click: _this.context.createInvokeHandler('editor.undo') 49323 }).render(); 49324 }); 49325 this.context.memo('button.help', function () { 49326 return _this.button({ 49327 contents: _this.ui.icon(_this.options.icons.question), 49328 tooltip: _this.lang.options.help, 49329 click: _this.context.createInvokeHandler('helpDialog.show') 49330 }).render(); 49331 }); 49332 }; 49333 /** 49334 * image : [ 49335 * ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']], 49336 * ['float', ['floatLeft', 'floatRight', 'floatNone' ]], 49337 * ['remove', ['removeMedia']] 49338 * ], 49339 */ 49340 Buttons.prototype.addImagePopoverButtons = function () { 49341 var _this = this; 49342 // Image Size Buttons 49343 this.context.memo('button.imageSize100', function () { 49344 return _this.button({ 49345 contents: '<span class="note-fontsize-10">100%</span>', 49346 tooltip: _this.lang.image.resizeFull, 49347 click: _this.context.createInvokeHandler('editor.resize', '1') 49348 }).render(); 49349 }); 49350 this.context.memo('button.imageSize50', function () { 49351 return _this.button({ 49352 contents: '<span class="note-fontsize-10">50%</span>', 49353 tooltip: _this.lang.image.resizeHalf, 49354 click: _this.context.createInvokeHandler('editor.resize', '0.5') 49355 }).render(); 49356 }); 49357 this.context.memo('button.imageSize25', function () { 49358 return _this.button({ 49359 contents: '<span class="note-fontsize-10">25%</span>', 49360 tooltip: _this.lang.image.resizeQuarter, 49361 click: _this.context.createInvokeHandler('editor.resize', '0.25') 49362 }).render(); 49363 }); 49364 // Float Buttons 49365 this.context.memo('button.floatLeft', function () { 49366 return _this.button({ 49367 contents: _this.ui.icon(_this.options.icons.alignLeft), 49368 tooltip: _this.lang.image.floatLeft, 49369 click: _this.context.createInvokeHandler('editor.floatMe', 'left') 49370 }).render(); 49371 }); 49372 this.context.memo('button.floatRight', function () { 49373 return _this.button({ 49374 contents: _this.ui.icon(_this.options.icons.alignRight), 49375 tooltip: _this.lang.image.floatRight, 49376 click: _this.context.createInvokeHandler('editor.floatMe', 'right') 49377 }).render(); 49378 }); 49379 this.context.memo('button.floatNone', function () { 49380 return _this.button({ 49381 contents: _this.ui.icon(_this.options.icons.alignJustify), 49382 tooltip: _this.lang.image.floatNone, 49383 click: _this.context.createInvokeHandler('editor.floatMe', 'none') 49384 }).render(); 49385 }); 49386 // Remove Buttons 49387 this.context.memo('button.removeMedia', function () { 49388 return _this.button({ 49389 contents: _this.ui.icon(_this.options.icons.trash), 49390 tooltip: _this.lang.image.remove, 49391 click: _this.context.createInvokeHandler('editor.removeMedia') 49392 }).render(); 49393 }); 49394 }; 49395 Buttons.
49395prototype.addLinkPopoverButtons = function () { 49396 var _this = this; 49397 this.context.memo('button.linkDialogShow', function () { 49398 return _this.button({ 49399 contents: _this.ui.icon(_this.options.icons.link), 49400 tooltip: _this.lang.link.edit, 49401 click: _this.context.createInvokeHandler('linkDialog.show') 49402 }).render(); 49403 }); 49404 this.context.memo('button.unlink', function () { 49405 return _this.button({ 49406 contents: _this.ui.icon(_this.options.icons.unlink), 49407 tooltip: _this.lang.link.unlink, 49408 click: _this.context.createInvokeHandler('editor.unlink') 49409 }).render(); 49410 }); 49411 }; 49412 /** 49413 * table : [ 49414 * ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']], 49415 * ['delete', ['deleteRow', 'deleteCol', 'deleteTable']] 49416 * ], 49417 */ 49418 Buttons.prototype.addTablePopoverButtons = function () { 49419 var _this = this; 49420 this.context.memo('button.addRowUp', function () { 49421 return _this.button({ 49422 className: 'btn-md', 49423 contents: _this.ui.icon(_this.options.icons.rowAbove), 49424 tooltip: _this.lang.table.addRowAbove, 49425 click: _this.context.createInvokeHandler('editor.addRow', 'top') 49426 }).render(); 49427 }); 49428 this.context.memo('button.addRowDown', function () { 49429 return _this.button({ 49430 className: 'btn-md', 49431 contents: _this.ui.icon(_this.options.icons.rowBelow), 49432 tooltip: _this.lang.table.addRowBelow, 49433 click: _this.context.createInvokeHandler('editor.addRow', 'bottom') 49434 }).render(); 49435 }); 49436 this.context.memo('button.addColLeft', function () { 49437 return _this.button({ 49438 className: 'btn-md', 49439 contents: _this.ui.icon(_this.options.icons.colBefore), 49440 tooltip: _this.lang.table.addColLeft, 49441 click: _this.context.createInvokeHandler('editor.addCol', 'left') 49442 }).render(); 49443 }); 49444 this.context.memo('button.addColRight', function () { 49445 return _this.button({ 49446 className: 'btn-md', 49447 contents: _this.ui.icon(_this.options.icons.colAfter), 49448 tooltip: _this.lang.table.addColRight, 49449 click: _this.context.createInvokeHandler('editor.addCol', 'right') 49450 }).render(); 49451 }); 49452 this.context.memo('button.deleteRow', function () { 49453 return _this.button({ 49454 className: 'btn-md', 49455 contents: _this.ui.icon(_this.options.icons.rowRemove), 49456 tooltip: _this.lang.table.delRow, 49457 click: _this.context.createInvokeHandler('editor.deleteRow') 49458 }).render(); 49459 }); 49460 this.context.memo('button.deleteCol', function () { 49461 return _this.button({ 49462 className: 'btn-md', 49463 contents: _this.ui.icon(_this.options.icons.colRemove), 49464 tooltip: _this.lang.table.delCol, 49465 click: _this.context.createInvokeHandler('editor.deleteCol') 49466 }).render(); 49467 }); 49468 this.context.memo('button.deleteTable', function () { 49469 return _this.button({ 49470 className: 'btn-md', 49471 contents: _this.ui.icon(_this.options.icons.trash), 49472 tooltip: _this.lang.table.delTable, 49473 click: _this.context.createInvokeHandler('editor.deleteTable') 49474 }).render(); 49475 }); 49476 }; 49477 Buttons.prototype.build = function ($container, groups) { 49478 for (var groupIdx = 0, groupLen = groups.length; groupIdx < groupLen; groupIdx++) { 49479 var group = groups[groupIdx]; 49480 var groupName = $$1.isArray(group) ? group[0] : group; 49481 var buttons = $$1.isArray(group) ? ((group.length === 1) ? [group[0]] : group[1]) : [group]; 49482 var $group = this.ui.buttonGroup({ 49483 className: 'note-' + groupName 49484 }).render(); 49485 for (var idx = 0, len = buttons.length; idx < len; idx++) { 49486 var btn = this.context.memo('button.' + buttons[idx]); 49487 if (btn) { 49488 $group.append(typeof btn === 'function' ? btn(this.context) : btn); 49489 } 49490 } 49491 $group.appendTo($container); 49492 } 49493 }; 49494 /** 49495 * @param {jQuery} [$container] 49496 */ 49497 Buttons.prototype.updateCurrentStyle = function ($container) { 49498 var _this = this; 49499 var $cont = $container || this.$toolbar;
49500 var styleInfo = this.context.invoke('editor.currentStyle'); 49501 this.updateBtnStates($cont, { 49502 '.note-btn-bold': function () { 49503 return styleInfo['font-bold'] === 'bold'; 49504 }, 49505 '.note-btn-italic': function () { 49506 return styleInfo['font-italic'] === 'italic'; 49507 }, 49508 '.note-btn-underline': function () { 49509 return styleInfo['font-underline'] === 'underline'; 49510 }, 49511 '.note-btn-subscript': function () { 49512 return styleInfo['font-subscript'] === 'subscript'; 49513 }, 49514 '.note-btn-superscript': function () { 49515 return styleInfo['font-superscript'] === 'superscript'; 49516 }, 49517 '.note-btn-strikethrough': function () { 49518 return styleInfo['font-strikethrough'] === 'strikethrough'; 49519 } 49520 }); 49521 if (styleInfo['font-family']) { 49522 var fontNames = styleInfo['font-family'].split(',').map(function (name) { 49523 return name.replace(/[\'\"]/g, '') 49524 .replace(/\s+$/, '') 49525 .replace(/^\s+/, ''); 49526 }); 49527 var fontName_1 = lists.find(fontNames, this.isFontInstalled.bind(this)); 49528 $cont.find('.dropdown-fontname a').each(function (idx, item) { 49529 var $item = $$1(item); 49530 // always compare string to avoid creating another func. 49531 var isChecked = ($item.data('value') + '') === (fontName_1 + ''); 49532 $item.toggleClass('checked', isChecked); 49533 }); 49534 $cont.find('.note-current-fontname').text(fontName_1).css('font-family', fontName_1); 49535 } 49536 if (styleInfo['font-size']) { 49537 var fontSize_1 = styleInfo['font-size']; 49538 $cont.find('.dropdown-fontsize a').each(function (idx, item) { 49539 var $item = $$1(item); 49540 // always compare with string to avoid creating another func. 49541 var isChecked = ($item.data('value') + '') === (fontSize_1 + ''); 49542 $item.toggleClass('checked', isChecked); 49543 }); 49544 $cont.find('.note-current-fontsize').text(fontSize_1); 49545 } 49546 if (styleInfo['line-height']) { 49547 var lineHeight_1 = styleInfo['line-height']; 49548 $cont.find('.dropdown-line-height li a').each(function (idx, item) { 49549 // always compare with string to avoid creating another func. 49550 var isChecked = ($$1(item).data('value') + '') === (lineHeight_1 + ''); 49551 _this.className = isChecked ? 'checked' : ''; 49552 }); 49553 } 49554 }; 49555 Buttons.prototype.updateBtnStates = function ($container, infos) { 49556 var _this = this; 49557 $$1.each(infos, function (selector, pred) { 49558 _this.ui.toggleBtnActive($container.find(selector), pred()); 49559 }); 49560 }; 49561 Buttons.prototype.tableMoveHandler = function (event) { 49562 var PX_PER_EM = 18; 49563 var $picker = $$1(event.target.parentNode); // target is mousecatcher 49564 var $dimensionDisplay = $picker.next(); 49565 var $catcher = $picker.find('.note-dimension-picker-mousecatcher'); 49566 var $highlighted = $picker.find('.note-dimension-picker-highlighted'); 49567 var $unhighlighted = $picker.find('.note-dimension-picker-unhighlighted'); 49568 var posOffset; 49569 // HTML5 with jQuery - e.offsetX is undefined in Firefox 49570 if (event.offsetX === undefined) { 49571 var posCatcher = $$1(event.target).offset(); 49572 posOffset = { 49573 x: event.pageX - posCatcher.left, 49574 y: event.pageY - posCatcher.top 49575 }; 49576 } 49577 else { 49578 posOffset = { 49579 x: event.offsetX, 49580 y: event.offsetY 49581 }; 49582 } 49583 var dim = { 49584 c: Math.ceil(posOffset.x / PX_PER_EM) || 1, 49585 r: Math.ceil(posOffset.y / PX_PER_EM) || 1 49586 }; 49587 $highlighted.css({ width: dim.c + 'em', height: dim.r + 'em' }); 49588 $catcher.data('value', dim.c + 'x' + dim.r); 49589 if (dim.c > 3 && dim.c < this.options.insertTableMaxSize.col) { 49590 $unhighlighted.css({ width: dim.c + 1 + 'em' }); 49591 } 49592 if (dim.r > 3 && dim.r < this.options.insertTableMaxSize.row) { 49593 $unhighlighted.css({ height: dim.r + 1 + 'em' }); 49594 } 49595 $dimensionDisplay.html(dim.c + ' x ' + dim.r); 49596 }; 49597 return Buttons; 49598}()); 49599 49600var Toolbar = /** @class */ (function () { 49601 function Toolbar(context) { 49602 this.context = context; 49603 this.$window = $$1(window); 49604 this.$document = $$1(document); 49605 this.ui = $$1.summernote.ui; 49606 this.$note = context.layoutInfo.note; 49607 this.$editor = context.layoutInfo.editor; 49608 this.$toolbar = context.layoutInfo.toolbar; 49609 this.options = context.options; 49610 this.followScroll = this.followScroll.bind(this); 49611 } 49612 Toolbar.prototype.shouldInitialize = function () { 49613 return !this.options.airMode; 49614 }; 49615 Toolbar.prototype.initialize = function () { 49616 var _this = this; 49617 this.options.toolbar = this.options.toolbar || []; 49618 if (!this.options.toolbar.length) { 49619 this.$toolbar.hide(); 49620 } 49621 else {
49622 this.context.invoke('buttons.build', this.$toolbar, this.options.toolbar); 49623 } 49624 if (this.options.toolbarContainer) { 49625 this.$toolbar.appendTo(this.options.toolbarContainer); 49626 } 49627 this.changeContainer(false); 49628 this.$note.on('summernote.keyup summernote.mouseup summernote.change', function () { 49629 _this.context.invoke('buttons.updateCurrentStyle'); 49630 }); 49631 this.context.invoke('buttons.updateCurrentStyle'); 49632 if (this.options.followingToolbar) { 49633 this.$window.on('scroll resize', this.followScroll); 49634 } 49635 }; 49636 Toolbar.prototype.destroy = function () { 49637 this.$toolbar.children().remove(); 49638 if (this.options.followingToolbar) { 49639 this.$window.off('scroll resize', this.followScroll); 49640 } 49641 }; 49642 Toolbar.prototype.followScroll = function () { 49643 if (this.$editor.hasClass('fullscreen')) { 49644 return false; 49645 } 49646 var $toolbarWrapper = this.$toolbar.parent('.note-toolbar-wrapper'); 49647 var editorHeight = this.$editor.outerHeight(); 49648 var editorWidth = this.$editor.width(); 49649 var toolbarHeight = this.$toolbar.height(); 49650 $toolbarWrapper.css({ 49651 height: toolbarHeight 49652 }); 49653 // check if the web app is currently using another static bar 49654 var otherBarHeight = 0; 49655 if (this.options.otherStaticBar) { 49656 otherBarHeight = $$1(this.options.otherStaticBar).outerHeight(); 49657 } 49658 var currentOffset = this.$document.scrollTop(); 49659 var editorOffsetTop = this.$editor.offset().top; 49660 var editorOffsetBottom = editorOffsetTop + editorHeight; 49661 var activateOffset = editorOffsetTop - otherBarHeight; 49662 var deactivateOffsetBottom = editorOffsetBottom - otherBarHeight - toolbarHeight; 49663 if ((currentOffset > activateOffset) && (currentOffset < deactivateOffsetBottom)) { 49664 this.$toolbar.css({ 49665 position: 'fixed', 49666 top: otherBarHeight, 49667 width: editorWidth 49668 }); 49669 } 49670 else { 49671 this.$toolbar.css({ 49672 position: 'relative', 49673 top: 0, 49674 width: '100%' 49675 }); 49676 } 49677 }; 49678 Toolbar.prototype.changeContainer = function (isFullscreen) { 49679 if (isFullscreen) { 49680 this.$toolbar.prependTo(this.$editor); 49681 } 49682 else { 49683 if (this.options.toolbarContainer) { 49684 this.$toolbar.appendTo(this.options.toolbarContainer); 49685 } 49686 } 49687 }; 49688 Toolbar.prototype.updateFullscreen = function (isFullscreen) { 49689 this.ui.toggleBtnActive(this.$toolbar.find('.btn-fullscreen'), isFullscreen); 49690 this.changeContainer(isFullscreen); 49691 }; 49692 Toolbar.prototype.updateCodeview = function (isCodeview) { 49693 this.ui.toggleBtnActive(this.$toolbar.find('.btn-codeview'), isCodeview); 49694 if (isCodeview) { 49695 this.deactivate(); 49696 } 49697 else { 49698 this.activate(); 49699 } 49700 }; 49701 Toolbar.prototype.activate = function (isIncludeCodeview) { 49702 var $btn = this.$toolbar.find('button'); 49703 if (!isIncludeCodeview) { 49704 $btn = $btn.not('.btn-codeview'); 49705 } 49706 this.ui.toggleBtn($btn, true); 49707 }; 49708 Toolbar.prototype.deactivate = function (isIncludeCodeview) { 49709 var $btn = this.$toolbar.find('button'); 49710 if (!isIncludeCodeview) { 49711 $btn = $btn.not('.btn-codeview'); 49712 } 49713 this.ui.toggleBtn($btn, false); 49714 }; 49715 return Toolbar; 49716}()); 49717 49718var LinkDialog = /** @class */ (function () { 49719 function LinkDialog(context) { 49720 this.context = context; 49721 this.ui = $$1.summernote.ui; 49722 this.$body = $$1(document.body); 49723 this.$editor = context.layoutInfo.editor; 49724 this.options = context.options; 49725 this.lang = this.options.langInfo; 49726 context.memo('help.linkDialog.show', this.options.langInfo.help['linkDialog.show']); 49727 } 49728 LinkDialog.prototype.initialize = function () { 49729 var $container = this.options.dialogsInBody ? this.$body : this.$editor; 49730 var body = [ 49731 '<div class="form-group note-form-group">', 49732 "<label class=\"note-form-label\">" + this.lang.link.textToDisplay + "</label>", 49733 '<input class="note-link-text form-control note-form-control note-input" type="text" />', 49734 '</div>', 49735 '<div class="form-group note-form-group">', 49736 "<label class=\"note-form-label\">" + this.lang.link.url + "</label>", 49737 '<input class="note-link-url form-control note-form-control note-input" type="text" value="http://" />', 49738 '</div>', 49739 !this.options.disableLinkTarget 49740 ? $$1('<div/>').append(this.ui.checkbox({ 49741 id: 'sn-checkbox-open-in-new-window', 49742 text: this.lang.link.openInNewWindow, 49743 checked: true 49744 }).render()).html() 49745 : '' 49746 ].join(''); 49747 var buttonClass = 'btn btn-primary note-btn note-btn-primary note-link-btn'; 49748 var footer = "<button type=\"submit\" href=\"#\" class=\"" + buttonClass + "\" disabled>" + this.lang.link.insert + "</button>"; 49749 this.$dialog = this.ui.dialog({ 49750 className: 'link-dialog', 49751 title: this.lang.link.insert, 49752 fade: this.options.dialogsFade, 49753 body: body, 49754 footer: footer 49755 }).render().appendTo($container); 49756 }; 49757 LinkDialog.prototype.destroy = function () { 49758 this.ui.hideDialog(this.$dialog); 49759 this.$dialog.remove(); 49760 }; 49761 LinkDialog.prototype.bindEnterKey = function ($input, $btn) { 49762 $input.on('keypress', function (event) { 49763 if (event.keyCode === key.code.ENTER) { 49764 event.preventDefault(); 49765 $btn.trigger('click'); 49766 } 49767 }); 49768 }; 49769 /** 49770 * toggle update button 49771 */ 49772 LinkDialog.prototype.toggleLinkBtn = function ($linkBtn, $linkText, $linkUrl) { 49773 this.ui.toggleBtn($linkBtn, $linkText.val() && $linkUrl.val()); 49774 }; 49775 /** 49776 * Show link dialog and set event handlers on dialog controls. 49777 * 49778 * @param {Object} linkInfo 49779 * @return {Promise} 49780 */ 49781 LinkDialog.prototype.showLinkDialog = function (linkInfo) { 49782 var _this = this; 49783 return $$1.Deferred(function (deferred) { 49784 var $linkText = _this.$dialog.find('.note-link-text'); 49785 var $linkUrl = _this.$dialog.find('.note-link-url'); 49786 var $linkBtn = _this.$dialog.find('.note-link-btn'); 49787 var $openInNewWindow = _this.$dialog.find('input[type=checkbox]'); 49788 _this.ui.onDialogShown(_this.$dialog, function () { 49789 _this.context.triggerEvent('dialog.shown'); 49790 // if no url was given, copy text to url 49791 if (!linkInfo.url) { 49792 linkInfo.url = linkInfo.text; 49793 } 49794 $linkText.val(linkInfo.text); 49795 var handleLinkTextUpdate = function () { 49796 _this.toggleLinkBtn($linkBtn, $linkText, $linkUrl); 49797 // if linktext was modified by keyup,
49798 // stop cloning text from linkUrl 49799 linkInfo.text = $linkText.val(); 49800 }; 49801 $linkText.on('input', handleLinkTextUpdate).on('paste', function () { 49802 setTimeout(handleLinkTextUpdate, 0); 49803 }); 49804 var handleLinkUrlUpdate = function () { 49805 _this.toggleLinkBtn($linkBtn, $linkText, $linkUrl); 49806 // display same link on `Text to display` input 49807 // when create a new link 49808 if (!linkInfo.text) { 49809 $linkText.val($linkUrl.val()); 49810 } 49811 }; 49812 $linkUrl.on('input', handleLinkUrlUpdate).on('paste', function () { 49813 setTimeout(handleLinkUrlUpdate, 0); 49814 }).val(linkInfo.url); 49815 if (!env.isSupportTouch) { 49816 $linkUrl.trigger('focus'); 49817 } 49818 _this.toggleLinkBtn($linkBtn, $linkText, $linkUrl); 49819 _this.bindEnterKey($linkUrl, $linkBtn); 49820 _this.bindEnterKey($linkText, $linkBtn); 49821 var isChecked = linkInfo.isNewWindow !== undefined 49822 ? linkInfo.isNewWindow : _this.context.options.linkTargetBlank; 49823 $openInNewWindow.prop('checked', isChecked); 49824 $linkBtn.one('click', function (event) { 49825 event.preventDefault(); 49826 deferred.resolve({ 49827 range: linkInfo.range, 49828 url: $linkUrl.val(), 49829 text: $linkText.val(), 49830 isNewWindow: $openInNewWindow.is(':checked') 49831 }); 49832 _this.ui.hideDialog(_this.$dialog); 49833 }); 49834 }); 49835 _this.ui.onDialogHidden(_this.$dialog, function () { 49836 // detach events 49837 $linkText.off('input paste keypress'); 49838 $linkUrl.off('input paste keypress'); 49839 $linkBtn.off('click'); 49840 if (deferred.state() === 'pending') { 49841 deferred.reject(); 49842 } 49843 }); 49844 _this.ui.showDialog(_this.$dialog); 49845 }).promise(); 49846 }; 49847 /** 49848 * @param {Object} layoutInfo 49849 */ 49850 LinkDialog.prototype.show = function () { 49851 var _this = this; 49852 var linkInfo = this.context.invoke('editor.getLinkInfo'); 49853 this.context.invoke('editor.saveRange'); 49854 this.showLinkDialog(linkInfo).then(function (linkInfo) { 49855 _this.context.invoke('editor.restoreRange'); 49856 _this.context.invoke('editor.createLink', linkInfo); 49857 }).fail(function () { 49858 _this.context.invoke('editor.restoreRange'); 49859 }); 49860 }; 49861 return LinkDialog; 49862}()); 49863 49864var LinkPopover = /** @class */ (function () { 49865 function LinkPopover(context) { 49866 var _this = this; 49867 this.context = context; 49868 this.ui = $$1.summernote.ui; 49869 this.options = context.options; 49870 this.events = { 49871 'summernote.keyup summernote.mouseup summernote.change summernote.scroll': function () { 49872 _this.update(); 49873 }, 49874 'summernote.disable summernote.dialog.shown': function () { 49875 _this.hide(); 49876 } 49877 }; 49878 } 49879 LinkPopover.prototype.shouldInitialize = function () { 49880 return !lists.isEmpty(this.options.popover.link); 49881 }; 49882 LinkPopover.prototype.initialize = function () { 49883 this.$popover = this.ui.popover({ 49884 className: 'note-link-popover', 49885 callback: function ($node) { 49886 var $content = $node.find('.popover-content,.note-popover-content'); 49887 $content.prepend('<span><a target="_blank"></a> </span>'); 49888 } 49889 }).render().appendTo(this.options.container); 49890 var $content = this.$popover.find('.popover-content,.note-popover-content'); 49891 this.context.invoke('buttons.build', $content, this.options.popover.link); 49892 }; 49893 LinkPopover.prototype.destroy = function () { 49894 this.$popover.remove(); 49895 }; 49896 LinkPopover.prototype.update = function () { 49897 // Prevent focusing on editable when invoke('code') is executed
49898 if (!this.context.invoke('editor.hasFocus')) { 49899 this.hide(); 49900 return; 49901 } 49902 var rng = this.context.invoke('editor.createRange'); 49903 if (rng.isCollapsed() && rng.isOnAnchor()) { 49904 var anchor = dom.ancestor(rng.sc, dom.isAnchor); 49905 var href = $$1(anchor).attr('href'); 49906 this.$popover.find('a').attr('href', href).html(href); 49907 var pos = dom.posFromPlaceholder(anchor); 49908 this.$popover.css({ 49909 display: 'block', 49910 left: pos.left, 49911 top: pos.top 49912 }); 49913 } 49914 else { 49915 this.hide(); 49916 } 49917 }; 49918 LinkPopover.prototype.hide = function () { 49919 this.$popover.hide(); 49920 }; 49921 return LinkPopover; 49922}()); 49923 49924var ImageDialog = /** @class */ (function () { 49925 function ImageDialog(context) { 49926 this.context = context; 49927 this.ui = $$1.summernote.ui; 49928 this.$body = $$1(document.body); 49929 this.$editor = context.layoutInfo.editor; 49930 this.options = context.options; 49931 this.lang = this.options.langInfo; 49932 } 49933 ImageDialog.prototype.initialize = function () { 49934 var $container = this.options.dialogsInBody ? this.$body : this.$editor; 49935 var imageLimitation = ''; 49936 if (this.options.maximumImageFileSize) { 49937 var unit = Math.floor(Math.log(this.options.maximumImageFileSize) / Math.log(1024)); 49938 var readableSize = (this.options.maximumImageFileSize / Math.pow(1024, unit)).toFixed(2) * 1 + 49939 ' ' + ' KMGTP'[unit] + 'B'; 49940 imageLimitation = "<small>" + (this.lang.image.maximumFileSize + ' : ' + readableSize) + "</small>"; 49941 } 49942 var body = [ 49943 '<div class="form-group note-form-group note-group-select-from-files">', 49944 '<label class="note-form-label">' + this.lang.image.selectFromFiles + '</label>', 49945 '<input class="note-image-input note-form-control note-input" ', 49946 ' type="file" name="files" accept="image/*" multiple="multiple" />', 49947 imageLimitation, 49948 '</div>', 49949 '<div class="form-group note-group-image-url" style="overflow:auto;">', 49950 '<label class="note-form-label">' + this.lang.image.url + '</label>', 49951 '<input class="note-image-url form-control note-form-control note-input ', 49952 ' col-md-12" type="text" />', 49953 '</div>' 49954 ].join(''); 49955 var buttonClass = 'btn btn-primary note-btn note-btn-primary note-image-btn'; 49956 var footer = "<button type=\"submit\" href=\"#\" class=\"" + buttonClass + "\" disabled>" + this.lang.image.insert + "</button>"; 49957 this.$dialog = this.ui.dialog({ 49958 title: this.lang.image.insert, 49959 fade: this.options.dialogsFade, 49960 body: body, 49961 footer: footer 49962 }).render().appendTo($container); 49963 }; 49964 ImageDialog.prototype.destroy = function () { 49965 this.ui.hideDialog(this.$dialog); 49966 this.$dialog.remove(); 49967 }; 49968 ImageDialog.prototype.bindEnterKey = function ($input, $btn) { 49969 $input.on('keypress', function (event) { 49970 if (event.keyCode === key.code.ENTER) { 49971 event.preventDefault(); 49972 $btn.trigger('click'); 49973 } 49974 }); 49975 }; 49976 ImageDialog.prototype.show = function () { 49977 var _this = this; 49978 this.context.invoke('editor.saveRange'); 49979 this.showImageDialog().then(function (data) { 49980 // [workaround] hide dialog before restore range for IE range focus 49981 _this.ui.hideDialog(_this.$dialog); 49982 _this.context.invoke('editor.restoreRange'); 49983 if (typeof data === 'string') { 49984 _this.context.invoke('editor.insertImage', data); 49985 } 49986 else { 49987 _this.context.invoke('editor.insertImagesOrCallback', data); 49988 } 49989 }).fail(function () { 49990 _this.context.invoke('editor.restoreRange'); 49991 }); 49992 }; 49993 /** 49994 * show image dialog 49995 * 49996 * @param {jQuery} $dialog 49997 * @return {Promise} 49998 */ 49999 ImageDialog.prototype.showImageDialog = function () { 50000 var _this = this; 50001 return $$1.Deferred(function (deferred) { 50002 var $imageInput = _this.$dialog.find('.note-image-input'); 50003 var $imageUrl = _this.$dialog.find('.note-image-url'); 50004 var $imageBtn = _this.$dialog.find('.note-image-btn'); 50005 _this.ui.onDialogShown(_this.$dialog, function () { 50006 _this.context.triggerEvent('dialog.shown'); 50007 // Cloning imageInput to clear element. 50008 $imageInput.replaceWith($imageInput.clone().on('change', function (event) { 50009 deferred.resolve(event.target.files || event.target.value); 50010 }).val('')); 50011 $imageBtn.click(function (event) { 50012 event.preventDefault(); 50013 deferred.resolve($imageUrl.val()); 50014 }); 50015 $imageUrl.on('keyup paste', function () { 50016 var url = $imageUrl.val(); 50017 _this.ui.toggleBtn($imageBtn, url); 50018 }).val(''); 50019 if (!env.isSupportTouch) { 50020 $imageUrl.trigger('focus'); 50021 } 50022 _this.bindEnterKey($imageUrl, $imageBtn); 50023 }); 50024 _this.ui.onDialogHidden(_this.$dialog, function () { 50025 $imageInput.off('change'); 50026 $imageUrl.off('keyup paste keypress'); 50027 $imageBtn.off('click'); 50028 if (deferred.state() === 'pending') { 50029 deferred.reject(); 50030 } 50031 }); 50032 _this.ui.showDialog(_this.$dialog); 50033 }); 50034 }; 50035 return ImageDialog; 50036}()); 50037 50038/** 50039 * Image popover module 50040 * mouse events that show/hide popover will be handled by Handle.js. 50041 * Handle.js will receive the events and invoke 'imagePopover.update'. 50042 */ 50043var ImagePopover = /** @class */ (function () { 50044 function ImagePopover(context) { 50045 var _this = this; 50046 this.context = context; 50047 this.ui = $$1.summernote.ui; 50048 this.editable = context.layoutInfo.editable[0]; 50049 this.options = context.options; 50050 this.events = { 50051 'summernote.disable': function () { 50052 _this.hide(); 50053 } 50054 }; 50055 } 50056 ImagePopover.prototype.shouldInitialize = function () { 50057 return !lists.isEmpty(this.options.popover.image); 50058 }; 50059 ImagePopover.prototype.initialize = function () { 50060 this.$popover = this.ui.popover({ 50061 className: 'note-image-popover' 50062 }).render().appendTo(this.options.container); 50063 var $content = this.$popover.find('.popover-content,.note-popover-content');
50064 this.context.invoke('buttons.build', $content, this.options.popover.image); 50065 }; 50066 ImagePopover.prototype.destroy = function () { 50067 this.$popover.remove(); 50068 }; 50069 ImagePopover.prototype.update = function (target) { 50070 if (dom.isImg(target)) { 50071 var pos = dom.posFromPlaceholder(target); 50072 var posEditor = dom.posFromPlaceholder(this.editable); 50073 this.$popover.css({ 50074 display: 'block', 50075 left: this.options.popatmouse ? event.pageX - 20 : pos.left, 50076 top: this.options.popatmouse ? event.pageY : Math.min(pos.top, posEditor.top) 50077 }); 50078 } 50079 else { 50080 this.hide(); 50081 } 50082 }; 50083 ImagePopover.prototype.hide = function () { 50084 this.$popover.hide(); 50085 }; 50086 return ImagePopover; 50087}()); 50088 50089var TablePopover = /** @class */ (function () { 50090 function TablePopover(context) { 50091 var _this = this; 50092 this.context = context; 50093 this.ui = $$1.summernote.ui; 50094 this.options = context.options; 50095 this.events = { 50096 'summernote.mousedown': function (we, e) { 50097 _this.update(e.target); 50098 }, 50099 'summernote.keyup summernote.scroll summernote.change': function () { 50100 _this.update(); 50101 }, 50102 'summernote.disable': function () { 50103 _this.hide(); 50104 } 50105 }; 50106 } 50107 TablePopover.prototype.shouldInitialize = function () { 50108 return !lists.isEmpty(this.options.popover.table); 50109 }; 50110 TablePopover.prototype.initialize = function () { 50111 this.$popover = this.ui.popover({ 50112 className: 'note-table-popover' 50113 }).render().appendTo(this.options.container); 50114 var $content = this.$popover.find('.popover-content,.note-popover-content'); 50115 this.context.invoke('buttons.build', $content, this.options.popover.table); 50116 // [workaround] Disable Firefox's default table editor 50117 if (env.isFF) { 50118 document.execCommand('enableInlineTableEditing', false, false); 50119 } 50120 }; 50121 TablePopover.prototype.destroy = function () { 50122 this.$popover.remove(); 50123 }; 50124 TablePopover.prototype.update = function (target) { 50125 if (this.context.isDisabled()) { 50126 return false; 50127 } 50128 var isCell = dom.isCell(target); 50129 if (isCell) { 50130 var pos = dom.posFromPlaceholder(target); 50131 this.$popover.css({ 50132 display: 'block', 50133 left: pos.left, 50134 top: pos.top 50135 }); 50136 } 50137 else { 50138 this.hide(); 50139 } 50140 return isCell; 50141 }; 50142 TablePopover.prototype.hide = function () { 50143 this.$popover.hide(); 50144 }; 50145 return TablePopover; 50146}()); 50147 50148var VideoDialog = /** @class */ (function () { 50149 function VideoDialog(context) { 50150 this.context = context; 50151 this.ui = $$1.summernote.ui; 50152 this.$body = $$1(document.body); 50153 this.$editor = context.layoutInfo.editor; 50154 this.options = context.options; 50155 this.lang = this.options.langInfo; 50156 } 50157 VideoDialog.prototype.initialize = function () { 50158 var $container = this.options.dialogsInBody ? this.$body : this.$editor; 50159 var body = [ 50160 '<div class="form-group note-form-group row-fluid">', 50161 "<label class=\"note-form-label\">" + this.lang.video.url + " <small class=\"text-muted\">" + this.lang.video.providers + "</small></label>", 50162 '<input class="note-video-url form-control note-form-control note-input" type="text" />', 50163 '</div>' 50164 ].join(''); 50165 var buttonClass = 'btn btn-primary note-btn note-btn-primary note-video-btn'; 50166 var footer = "<button type=\"submit\" href=\"#\" class=\"" + buttonClass + "\" disabled>" + this.lang.video.insert + "</button>"; 50167 this.$dialog = this.ui.dialog({ 50168 title: this.lang.video.insert, 50169 fade: this.options.dialogsFade, 50170 body: body, 50171 footer: footer 50172 }).render().appendTo($container); 50173 }; 50174 VideoDialog.prototype.destroy = function () { 50175 this.ui.hideDialog(this.$dialog); 50176 this.$dialog.remove(); 50177 }; 50178 VideoDialog.prototype.bindEnterKey = function ($input, $btn) { 50179 $input.on('keypress', function (event) { 50180 if (event.keyCode === key.code.ENTER) { 50181 event.preventDefault(); 50182 $btn.trigger('click'); 50183 } 50184 }); 50185 }; 50186 VideoDialog.prototype.createVideoNode = function (url) { 50187 // video url patterns(youtube, instagram, vimeo, dailymotion, youku, mp4, ogg, webm) 50188 var ytRegExp = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11}
50188)(?:\S+)?$/; 50189 var ytMatch = url.match(ytRegExp); 50190 var igRegExp = /(?:www\.|\/\/)instagram\.com\/p\/(.[a-zA-Z0-9_-]*)/; 50191 var igMatch = url.match(igRegExp); 50192 var vRegExp = /\/\/vine\.co\/v\/([a-zA-Z0-9]+)/; 50193 var vMatch = url.match(vRegExp); 50194 var vimRegExp = /\/\/(player\.)?vimeo\.com\/([a-z]*\/)*(\d+)[?]?.*/; 50195 var vimMatch = url.match(vimRegExp); 50196 var dmRegExp = /.+dailymotion.com\/(video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/; 50197 var dmMatch = url.match(dmRegExp); 50198 var youkuRegExp = /\/\/v\.youku\.com\/v_show\/id_(\w+)=*\.html/; 50199 var youkuMatch = url.match(youkuRegExp); 50200 var qqRegExp = /\/\/v\.qq\.com.*?vid=(.+)/; 50201 var qqMatch = url.match(qqRegExp); 50202 var qqRegExp2 = /\/\/v\.qq\.com\/x?\/?(page|cover).*?\/([^\/]+)\.html\??.*/; 50203 var qqMatch2 = url.match(qqRegExp2); 50204 var mp4RegExp = /^.+.(mp4|m4v)$/; 50205 var mp4Match = url.match(mp4RegExp); 50206 var oggRegExp = /^.+.(ogg|ogv)$/; 50207 var oggMatch = url.match(oggRegExp); 50208 var webmRegExp = /^.+.(webm)$/; 50209 var webmMatch = url.match(webmRegExp); 50210 var $video; 50211 if (ytMatch && ytMatch[1].length === 11) { 50212 var youtubeId = ytMatch[1]; 50213 $video = $$1('<iframe>') 50214 .attr('frameborder', 0) 50215 .attr('src', '//www.youtube.com/embed/' + youtubeId) 50216 .attr('width', '640').attr('height', '360'); 50217 } 50218 else if (igMatch && igMatch[0].length) { 50219 $video = $$1('<iframe>') 50220 .attr('frameborder', 0) 50221 .attr('src', 'https://instagram.com/p/' + igMatch[1] + '/embed/') 50222 .attr('width', '612').attr('height', '710') 50223 .attr('scrolling', 'no') 50224 .attr('allowtransparency', 'true'); 50225 } 50226 else if (vMatch && vMatch[0].length) { 50227 $video = $$1('<iframe>') 50228 .attr('frameborder', 0) 50229 .attr('src', vMatch[0] + '/embed/simple') 50230 .attr('width', '600').attr('height', '600') 50231 .attr('class', 'vine-embed'); 50232 } 50233 else if (vimMatch && vimMatch[3].length) { 50234 $video = $$1('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>') 50235 .attr('frameborder', 0) 50236 .attr('src', '//player.vimeo.com/video/' + vimMatch[3]) 50237 .attr('width', '640').attr('height', '360'); 50238 } 50239 else if (dmMatch && dmMatch[2].length) { 50240 $video = $$1('<iframe>') 50241 .attr('frameborder', 0) 50242 .attr('src', '//www.dailymotion.com/embed/video/' + dmMatch[2]) 50243 .attr('width', '640').attr('height', '360'); 50244 } 50245 else if (youkuMatch && youkuMatch[1].length) { 50246 $video = $$1('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>') 50247 .attr('frameborder', 0) 50248 .attr('height', '498') 50249 .attr('width', '510') 50250 .attr('src', '//player.youku.com/embed/' + youkuMatch[1]); 50251 } 50252 else if ((qqMatch && qqMatch[1].length) || (qqMatch2 && qqMatch2[2].length)) { 50253 var vid = ((qqMatch && qqMatch[1].length) ? qqMatch[1] : qqMatch2[2]); 50254 $video = $$1('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>') 50255 .attr('frameborder', 0) 50256 .attr('height', '310') 50257 .attr('width', '500') 50258 .attr('src', 'http://v.qq.com/iframe/player.html?vid=' + vid + '&auto=0'); 50259 } 50260 else if (mp4Match || oggMatch || webmMatch) { 50261 $video = $$1('<video controls>') 50262 .attr('src', url) 50263 .attr('width', '640').attr('height', '360'); 50264 } 50265 else { 50266 // this is not a known video link. Now what, Cat? Now what? 50267 return false; 50268 } 50269 $video.addClass('note-video-clip'); 50270 return $video[0]; 50271 }; 50272 VideoDialog.prototype.show = function () { 50273 var _this = this; 50274 var text = this.context.invoke('editor.getSelectedText');
50275 this.context.invoke('editor.saveRange'); 50276 this.showVideoDialog(text).then(function (url) { 50277 // [workaround] hide dialog before restore range for IE range focus 50278 _this.ui.hideDialog(_this.$dialog); 50279 _this.context.invoke('editor.restoreRange'); 50280 // build node 50281 var $node = _this.createVideoNode(url); 50282 if ($node) { 50283 // insert video node 50284 _this.context.invoke('editor.insertNode', $node); 50285 } 50286 }).fail(function () { 50287 _this.context.invoke('editor.restoreRange'); 50288 }); 50289 }; 50290 /** 50291 * show image dialog 50292 * 50293 * @param {jQuery} $dialog 50294 * @return {Promise} 50295 */ 50296 VideoDialog.prototype.showVideoDialog = function (text) { 50297 var _this = this; 50298 return $$1.Deferred(function (deferred) { 50299 var $videoUrl = _this.$dialog.find('.note-video-url'); 50300 var $videoBtn = _this.$dialog.find('.note-video-btn'); 50301 _this.ui.onDialogShown(_this.$dialog, function () { 50302 _this.context.triggerEvent('dialog.shown'); 50303 $videoUrl.val(text).on('input', function () { 50304 _this.ui.toggleBtn($videoBtn, $videoUrl.val()); 50305 }); 50306 if (!env.isSupportTouch) { 50307 $videoUrl.trigger('focus'); 50308 } 50309 $videoBtn.click(function (event) { 50310 event.preventDefault(); 50311 deferred.resolve($videoUrl.val()); 50312 }); 50313 _this.bindEnterKey($videoUrl, $videoBtn); 50314 }); 50315 _this.ui.onDialogHidden(_this.$dialog, function () { 50316 $videoUrl.off('input'); 50317 $videoBtn.off('click'); 50318 if (deferred.state() === 'pending') { 50319 deferred.reject(); 50320 } 50321 }); 50322 _this.ui.showDialog(_this.$dialog); 50323 }); 50324 }; 50325 return VideoDialog; 50326}()); 50327 50328var HelpDialog = /** @class */ (function () { 50329 function HelpDialog(context) { 50330 this.context = context; 50331 this.ui = $$1.summernote.ui; 50332 this.$body = $$1(document.body); 50333 this.$editor = context.layoutInfo.editor; 50334 this.options = context.options; 50335 this.lang = this.options.langInfo; 50336 } 50337 HelpDialog.prototype.initialize = function () { 50338 var $container = this.options.dialogsInBody ? this.$body : this.$editor; 50339 var body = [ 50340 '<p class="text-center">', 50341 '<a href="http://summernote.org/" target="_blank">Summernote 0.8.10</a> · ', 50342 '<a href="https://github.com/summernote/summernote" target="_blank">Project</a> · ', 50343 '<a href="https://github.com/summernote/summernote/issues" target="_blank">Issues</a>', 50344 '</p>' 50345 ].join(''); 50346 this.$dialog = this.ui.dialog({ 50347 title: this.lang.options.help, 50348 fade: this.options.dialogsFade, 50349 body: this.createShortcutList(), 50350 footer: body, 50351 callback: function ($node) { 50352 $node.find('.modal-body,.note-modal-body').css({ 50353 'max-height': 300, 50354 'overflow': 'scroll' 50355 }); 50356 } 50357 }).render().appendTo($container); 50358 }; 50359 HelpDialog.prototype.destroy = function () { 50360 this.ui.hideDialog(this.$dialog); 50361 this.$dialog.remove(); 50362 }; 50363 HelpDialog.prototype.createShortcutList = function () { 50364 var _this = this; 50365 var keyMap = this.options.keyMap[env.isMac ? 'mac' : 'pc']; 50366 return Object.keys(keyMap).map(function (key) { 50367 var command = keyMap[key]; 50368 var $row = $$1('<div><div class="help-list-item"/></div>'); 50369 $row.append($$1('<label><kbd>' + key + '</kdb></label>').css({ 50370 'width': 180, 50371 'margin-right': 10 50372 })).append($$1('<span/>').html(_this.context.memo('help.' + command) || command)); 50373 return $row.html(); 50374 }).join(''); 50375 }; 50376 /** 50377 * show help dialog 50378 * 50379 * @return {Promise} 50380 */ 50381 HelpDialog.prototype.showHelpDialog = function () { 50382 var _this = this; 50383 return $$1.Deferred(function (deferred) { 50384 _this.ui.onDialogShown(_this.$dialog, function () { 50385 _this.context.triggerEvent('dialog.shown'); 50386 deferred.resolve(); 50387 }); 50388 _this.ui.showDialog(_this.$dialog); 50389 }).promise(); 50390 }; 50391 HelpDialog.prototype.show = function () { 50392 var _this = this;
50393 this.context.invoke('editor.saveRange'); 50394 this.showHelpDialog().then(function () { 50395 _this.context.invoke('editor.restoreRange'); 50396 }); 50397 }; 50398 return HelpDialog; 50399}()); 50400 50401var AIR_MODE_POPOVER_X_OFFSET = 20; 50402var AirPopover = /** @class */ (function () { 50403 function AirPopover(context) { 50404 var _this = this; 50405 this.context = context; 50406 this.ui = $$1.summernote.ui; 50407 this.options = context.options; 50408 this.events = { 50409 'summernote.keyup summernote.mouseup summernote.scroll': function () { 50410 _this.update(); 50411 }, 50412 'summernote.disable summernote.change summernote.dialog.shown': function () { 50413 _this.hide(); 50414 }, 50415 'summernote.focusout': function (we, e) { 50416 // [workaround] Firefox doesn't support relatedTarget on focusout 50417 // - Ignore hide action on focus out in FF. 50418 if (env.isFF) { 50419 return; 50420 } 50421 if (!e.relatedTarget || !dom.ancestor(e.relatedTarget, func.eq(_this.$popover[0]))) { 50422 _this.hide(); 50423 } 50424 } 50425 }; 50426 } 50427 AirPopover.prototype.shouldInitialize = function () { 50428 return this.options.airMode && !lists.isEmpty(this.options.popover.air); 50429 }; 50430 AirPopover.prototype.initialize = function () { 50431 this.$popover = this.ui.popover({ 50432 className: 'note-air-popover' 50433 }).render().appendTo(this.options.container); 50434 var $content = this.$popover.find('.popover-content'); 50435 this.context.invoke('buttons.build', $content, this.options.popover.air); 50436 }; 50437 AirPopover.prototype.destroy = function () { 50438 this.$popover.remove(); 50439 }; 50440 AirPopover.prototype.update = function () { 50441 var styleInfo = this.context.invoke('editor.currentStyle'); 50442 if (styleInfo.range && !styleInfo.range.isCollapsed()) { 50443 var rect = lists.last(styleInfo.range.getClientRects()); 50444 if (rect) { 50445 var bnd = func.rect2bnd(rect); 50446 this.$popover.css({ 50447 display: 'block', 50448 left: Math.max(bnd.left + bnd.width / 2, 0) - AIR_MODE_POPOVER_X_OFFSET, 50449 top: bnd.top + bnd.height 50450 }); 50451 this.context.invoke('buttons.updateCurrentStyle', this.$popover); 50452 } 50453 } 50454 else { 50455 this.hide(); 50456 } 50457 }; 50458 AirPopover.prototype.hide = function () { 50459 this.$popover.hide(); 50460 }; 50461 return AirPopover; 50462}()); 50463 50464var POPOVER_DIST = 5; 50465var HintPopover = /** @class */ (function () { 50466 function HintPopover(context) { 50467 var _this = this; 50468 this.context = context; 50469 this.ui = $$1.summernote.ui; 50470 this.$editable = context.layoutInfo.editable; 50471 this.options = context.options; 50472 this.hint = this.options.hint || []; 50473 this.direction = this.options.hintDirection || 'bottom'; 50474 this.hints = $$1.isArray(this.hint) ? this.hint : [this.hint]; 50475 this.events = { 50476 'summernote.keyup': function (we, e) { 50477 if (!e.isDefaultPrevented()) { 50478 _this.handleKeyup(e); 50479 } 50480 }, 50481 'summernote.keydown': function (we, e) { 50482 _this.handleKeydown(e); 50483 }, 50484 'summernote.disable summernote.dialog.shown': function () { 50485 _this.hide(); 50486 } 50487 }; 50488 } 50489 HintPopover.prototype.shouldInitialize = function () { 50490 return this.hints.length > 0; 50491 }; 50492 HintPopover.prototype.initialize = function () { 50493 var _this = this; 50494 this.lastWordRange = null; 50495 this.$popover = this.ui.popover({ 50496 className: 'note-hint-popover', 50497 hideArrow: true, 50498 direction: '' 50499 }).render().appendTo(this.options.container); 50500 this.$popover.hide(); 50501 this.$content = this.$popover.find('.popover-content,.note-popover-content'); 50502 this.$content.on('click', '.note-hint-item', function () { 50503 _this.$content.find('.active').removeClass('active'); 50504 $$1(_this).addClass('active'); 50505 _this.replace(); 50506 }); 50507 }; 50508 HintPopover.prototype.destroy = function () { 50509 this.$popover.remove(); 50510 }; 50511 HintPopover.prototype.selectItem = function ($item) { 50512 this.$content.find('.active').removeClass('active'); 50513 $item.addClass('active'); 50514 this.$content[0].scrollTop = $item[0].offsetTop - (this.$content.innerHe
50514ight() / 2); 50515 }; 50516 HintPopover.prototype.moveDown = function () { 50517 var $current = this.$content.find('.note-hint-item.active'); 50518 var $next = $current.next(); 50519 if ($next.length) { 50520 this.selectItem($next); 50521 } 50522 else { 50523 var $nextGroup = $current.parent().next(); 50524 if (!$nextGroup.length) { 50525 $nextGroup = this.$content.find('.note-hint-group').first(); 50526 } 50527 this.selectItem($nextGroup.find('.note-hint-item').first()); 50528 } 50529 }; 50530 HintPopover.prototype.moveUp = function () { 50531 var $current = this.$content.find('.note-hint-item.active'); 50532 var $prev = $current.prev(); 50533 if ($prev.length) { 50534 this.selectItem($prev); 50535 } 50536 else { 50537 var $prevGroup = $current.parent().prev(); 50538 if (!$prevGroup.length) { 50539 $prevGroup = this.$content.find('.note-hint-group').last(); 50540 } 50541 this.selectItem($prevGroup.find('.note-hint-item').last()); 50542 } 50543 }; 50544 HintPopover.prototype.replace = function () { 50545 var $item = this.$content.find('.note-hint-item.active'); 50546 if ($item.length) { 50547 var node = this.nodeFromItem($item);
50548 // XXX: consider to move codes to editor for recording redo/undo. 50549 this.lastWordRange.insertNode(node); 50550 range.createFromNode(node).collapse().select(); 50551 this.lastWordRange = null; 50552 this.hide(); 50553 this.context.triggerEvent('change', this.$editable.html(), this.$editable[0]); 50554 this.context.invoke('editor.focus'); 50555 } 50556 }; 50557 HintPopover.prototype.nodeFromItem = function ($item) { 50558 var hint = this.hints[$item.data('index')]; 50559 var item = $item.data('item'); 50560 var node = hint.content ? hint.content(item) : item; 50561 if (typeof node === 'string') { 50562 node = dom.createText(node); 50563 } 50564 return node; 50565 }; 50566 HintPopover.prototype.createItemTemplates = function (hintIdx, items) { 50567 var hint = this.hints[hintIdx]; 50568 return items.map(function (item, idx) { 50569 var $item = $$1('<div class="note-hint-item"/>'); 50570 $item.append(hint.template ? hint.template(item) : item + ''); 50571 $item.data({ 50572 'index': hintIdx, 50573 'item': item 50574 }); 50575 return $item; 50576 }); 50577 }; 50578 HintPopover.prototype.handleKeydown = function (e) { 50579 if (!this.$popover.is(':visible')) { 50580 return; 50581 } 50582 if (e.keyCode === key.code.ENTER) { 50583 e.preventDefault(); 50584 this.replace(); 50585 } 50586 else if (e.keyCode === key.code.UP) { 50587 e.preventDefault(); 50588 this.moveUp(); 50589 } 50590 else if (e.keyCode === key.code.DOWN) { 50591 e.preventDefault(); 50592 this.moveDown(); 50593 } 50594 }; 50595 HintPopover.prototype.searchKeyword = function (index, keyword, callback) { 50596 var hint = this.hints[index]; 50597 if (hint && hint.match.test(keyword) && hint.search) { 50598 var matches = hint.match.exec(keyword); 50599 hint.search(matches[1], callback); 50600 } 50601 else { 50602 callback(); 50603 } 50604 }; 50605 HintPopover.prototype.createGroup = function (idx, keyword) { 50606 var _this = this; 50607 var $group = $$1('<div class="note-hint-group note-hint-group-' + idx + '"/>'); 50608 this.searchKeyword(idx, keyword, function (items) { 50609 items = items || []; 50610 if (items.length) { 50611 $group.html(_this.createItemTemplates(idx, items)); 50612 _this.show(); 50613 } 50614 }); 50615 return $group; 50616 }; 50617 HintPopover.prototype.handleKeyup = function (e) { 50618 var _this = this; 50619 if (!lists.contains([key.code.ENTER, key.code.UP, key.code.DOWN], e.keyCode)) { 50620 var wordRange = this.context.invoke('editor.createRange').getWordRange(); 50621 var keyword_1 = wordRange.toString(); 50622 if (this.hints.length && keyword_1) { 50623 this.$content.empty(); 50624 var bnd = func.rect2bnd(lists.last(wordRange.getClientRects())); 50625 if (bnd) { 50626 this.$popover.hide(); 50627 this.lastWordRange = wordRange; 50628 this.hints.forEach(function (hint, idx) { 50629 if (hint.match.test(keyword_1)) { 50630 _this.createGroup(idx, keyword_1).appendTo(_this.$content); 50631 } 50632 }); 50633 // select first .note-hint-item 50634 this.$content.find('.note-hint-item:first').addClass('active'); 50635 // set position for popover after group is created 50636 if (this.direction === 'top') { 50637 this.$popover.css({ 50638 left: bnd.left, 50639 top: bnd.top - this.$popover.outerHeight() - POPOVER_DIST 50640 }); 50641 } 50642 else { 50643 this.$popover.css({ 50644 left: bnd.left, 50645 top: bnd.top + bnd.height + POPOVER_DIST 50646 }); 50647 } 50648 } 50649 } 50650 else { 50651 this.hide(); 50652 } 50653 } 50654 }; 50655 HintPopover.prototype.show = function () { 50656 this.$popover.show(); 50657 }; 50658 HintPopover.prototype.hide = function () { 50659 this.$popover.hide(); 50660 }; 50661 return HintPopover; 50662}()); 50663 50664var Context = /** @class */ (function () { 50665 /** 50666 * @param {jQuery} $note 50667 * @param {Object} options 50668 */ 50669 function Context($note, options) { 50670 this.ui = $$1.summernote.ui; 50671 this.$note = $note; 50672 this.memos = {}; 50673 this.modules = {}; 50674 this.layoutInfo = {}; 50675 this.options = options; 50676 this.initialize(); 50677 } 50678 /** 50679 * create layout and initialize modules and other resources 50680 */ 50681 Context.prototype.initialize = function () { 50682 this.layoutInfo = this.ui.createLayout(this.$note, this.options); 50683 this._initialize(); 50684 this.$note.hide(); 50685 return this; 50686 }; 50687 /** 50688 * destroy modules and other resources and remove layout 50689 */ 50690 Context.prototype.destroy = function () { 50691 this._destroy(); 50692 this.$note.removeData('summernote'); 50693 this.ui.removeLayout(this.$note, this.layoutInfo); 50694 }; 50695 /** 50696 * destory modules and other resources and initialize it again 50697 */ 50698 Context.prototype.reset = function () { 50699 var disabled = this.isDisabled(); 50700 this.code(dom.emptyPara); 50701 this._destroy(); 50702 this._initialize(); 50703 if (disabled) { 50704 this.disable(); 50705 } 50706 }; 50707 Context.prototype._initialize = function () { 50708 var _this = this; 50709 // add optional buttons 50710 var buttons = $$1.extend({}, this.options.buttons);
50711 Object.keys(buttons).forEach(function (key) { 50712 _this.memo('button.' + key, buttons[key]); 50713 }); 50714 var modules = $$1.extend({}, this.options.modules, $$1.summernote.plugins || {}); 50715 // add and initialize modules 50716 Object.keys(modules).forEach(function (key) { 50717 _this.module(key, modules[key], true); 50718 }); 50719 Object.keys(this.modules).forEach(function (key) { 50720 _this.initializeModule(key); 50721 }); 50722 }; 50723 Context.prototype._destroy = function () { 50724 var _this = this; 50725 // destroy modules with reversed order 50726 Object.keys(this.modules).reverse().forEach(function (key) { 50727 _this.removeModule(key); 50728 }); 50729 Object.keys(this.memos).forEach(function (key) { 50730 _this.removeMemo(key); 50731 }); 50732 // trigger custom onDestroy callback 50733 this.triggerEvent('destroy', this); 50734 }; 50735 Context.prototype.code = function (html) { 50736 var isActivated = this.invoke('codeview.isActivated'); 50737 if (html === undefined) { 50738 this.invoke('codeview.sync'); 50739 return isActivated ? this.layoutInfo.codable.val() : this.layoutInfo.editable.html(); 50740 } 50741 else { 50742 if (isActivated) { 50743 this.layoutInfo.codable.val(html); 50744 } 50745 else { 50746 this.layoutInfo.editable.html(html); 50747 } 50748 this.$note.val(html); 50749 this.triggerEvent('change', html); 50750 } 50751 }; 50752 Context.prototype.isDisabled = function () { 50753 return this.layoutInfo.editable.attr('contenteditable') === 'false'; 50754 }; 50755 Context.prototype.enable = function () { 50756 this.layoutInfo.editable.attr('contenteditable', true); 50757 this.invoke('toolbar.activate', true); 50758 this.triggerEvent('disable', false); 50759 }; 50760 Context.prototype.disable = function () { 50761 // close codeview if codeview is opend 50762 if (this.invoke('codeview.isActivated')) { 50763 this.invoke('codeview.deactivate'); 50764 } 50765 this.layoutInfo.editable.attr('contenteditable', false); 50766 this.invoke('toolbar.deactivate', true); 50767 this.triggerEvent('disable', true); 50768 }; 50769 Context.prototype.triggerEvent = function () { 50770 var namespace = lists.head(arguments); 50771 var args = lists.tail(lists.from(arguments)); 50772 var callback = this.options.callbacks[func.namespaceToCamel(namespace, 'on')]; 50773 if (callback) { 50774 callback.apply(this.$note[0], args); 50775 }
50776 this.$note.trigger('summernote.' + namespace, args); 50777 }; 50778 Context.prototype.initializeModule = function (key) { 50779 var module = this.modules[key]; 50780 module.shouldInitialize = module.shouldInitialize || func.ok; 50781 if (!module.shouldInitialize()) { 50782 return; 50783 } 50784 // initialize module 50785 if (module.initialize) { 50786 module.initialize(); 50787 } 50788 // attach events 50789 if (module.events) { 50790 dom.attachEvents(this.$note, module.events); 50791 } 50792 }; 50793 Context.prototype.module = function (key, ModuleClass, withoutIntialize) { 50794 if (arguments.length === 1) { 50795 return this.modules[key]; 50796 } 50797 this.modules[key] = new ModuleClass(this); 50798 if (!withoutIntialize) { 50799 this.initializeModule(key); 50800 } 50801 }; 50802 Context.prototype.removeModule = function (key) { 50803 var module = this.modules[key]; 50804 if (module.shouldInitialize()) { 50805 if (module.events) { 50806 dom.detachEvents(this.$note, module.events); 50807 } 50808 if (module.destroy) { 50809 module.destroy(); 50810 } 50811 } 50812 delete this.modules[key]; 50813 }; 50814 Context.prototype.memo = function (key, obj) { 50815 if (arguments.length === 1) { 50816 return this.memos[key]; 50817 } 50818 this.memos[key] = obj; 50819 }; 50820 Context.prototype.removeMemo = function (key) { 50821 if (this.memos[key] && this.memos[key].destroy) { 50822 this.memos[key].destroy(); 50823 } 50824 delete this.memos[key]; 50825 }; 50826 /** 50827 * Some buttons need to change their visual style immediately once they get pressed 50828 */ 50829 Context.prototype.createInvokeHandlerAndUpdateState = function (namespace, value) { 50830 var _this = this; 50831 return function (event) { 50832 _this.createInvokeHandler(namespace, value)(event); 50833 _this.invoke('buttons.updateCurrentStyle'); 50834 }; 50835 }; 50836 Context.prototype.createInvokeHandler = function (namespace, value) { 50837 var _this = this; 50838 return function (event) { 50839 event.preventDefault(); 50840 var $target = $$1(event.target); 50841 _this.invoke(namespace, value || $target.closest('[data-value]').data('value'), $target); 50842 }; 50843 }; 50844 Context.prototype.invoke = function () { 50845 var namespace = lists.head(arguments); 50846 var args = lists.tail(lists.from(arguments)); 50847 var splits = namespace.split('.'); 50848 var hasSeparator = splits.length > 1; 50849 var moduleName = hasSeparator && lists.head(splits); 50850 var methodName = hasSeparator ? lists.last(splits) : lists.head(splits); 50851 var module = this.modules[moduleName || 'editor']; 50852 if (!moduleName && this[methodName]) { 50853 return this[methodName].apply(this, args); 50854 } 50855 else if (module && module[methodName] && module.shouldInitialize()) { 50856 return module[methodName].apply(module, args); 50857 } 50858 }; 50859 return Context; 50860}()); 50861 50862$$1.fn.extend({ 50863 /** 50864 * Summernote API 50865 * 50866 * @param {Object|String} 50867 * @return {this} 50868 */ 50869 summernote: function () { 50870 var type = $$1.type(lists.head(arguments)); 50871 var isExternalAPICalled = type === 'string'; 50872 var hasInitOptions = type === 'object'; 50873 var options = $$1.extend({}, $$1.summernote.options, hasInitOptions ? lists.head(arguments) : {}); 50874 // Update options 50875 options.langInfo = $$1.extend(true, {}, $$1.summernote.lang['en-US'], $$1.summernote.lang[options.lang]); 50876 options.icons = $$1.extend(true, {}, $$1.summernote.options.icons, options.icons); 50877 options.tooltip = options.tooltip === 'auto' ? !env.isSupportTouch : options.tooltip; 50878 this.each(function (idx, note) { 50879 var $note = $$1(note); 50880 if (!$note.data('summernote')) { 50881 var context = new Context($note, options); 50882 $note.data('summernote', context); 50883 $note.data('summernote').triggerEvent('init', context.layoutInfo); 50884 } 50885 }); 50886 var $note = this.first(); 50887 if ($note.length) { 50888 var context = $note.data('summernote'); 50889 if (isExternalAPICalled) {
50890 return context.invoke.apply(context, lists.from(arguments)); 50891 } 50892 else if (options.focus) { 50893 context.invoke('editor.focus'); 50894 } 50895 } 50896 return this; 50897 } 50898}); 50899 50900$$1.summernote = $$1.extend($$1.summernote, { 50901 version: '0.8.10', 50902 ui: ui, 50903 dom: dom, 50904 plugins: {}, 50905 options: { 50906 modules: { 50907 'editor': Editor, 50908 'clipboard': Clipboard, 50909 'dropzone': Dropzone, 50910 'codeview': CodeView, 50911 'statusbar': Statusbar, 50912 'fullscreen': Fullscreen, 50913 'handle': Handle, 50914 // FIXME: HintPopover must be front of autolink 50915 // - Script error about range when Enter key is pressed on hint popover 50916 'hintPopover': HintPopover, 50917 'autoLink': AutoLink, 50918 'autoSync': AutoSync, 50919 'placeholder': Placeholder, 50920 'buttons': Buttons, 50921 'toolbar': Toolbar, 50922 'linkDialog': LinkDialog, 50923 'linkPopover': LinkPopover, 50924 'imageDialog': ImageDialog, 50925 'imagePopover': ImagePopover, 50926 'tablePopover': TablePopover, 50927 'videoDialog': VideoDialog, 50928 'helpDialog': HelpDialog, 50929 'airPopover': AirPopover 50930 }, 50931 buttons: {}, 50932 lang: 'en-US', 50933 followingToolbar: true, 50934 otherStaticBar: '', 50935 // toolbar 50936 toolbar: [ 50937 ['style', ['style']], 50938 ['font', ['bold', 'underline', 'clear']], 50939 ['fontname', ['fontname']], 50940 ['color', ['color']], 50941 ['para', ['ul', 'ol', 'paragraph']], 50942 ['table', ['table']], 50943 ['insert', ['link', 'picture', 'video']], 50944 ['view', ['fullscreen', 'codeview', 'help']] 50945 ], 50946 // popover 50947 popatmouse: true, 50948 popover: { 50949 image: [ 50950 ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']], 50951 ['float', ['floatLeft', 'floatRight', 'floatNone']], 50952 ['remove', ['removeMedia']] 50953 ], 50954 link: [ 50955 ['link', ['linkDialogShow', 'unlink']] 50956 ], 50957 table: [ 50958 ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']], 50959 ['delete', ['deleteRow', 'deleteCol', 'deleteTable']] 50960 ], 50961 air: [ 50962 ['color', ['color']], 50963 ['font', ['bold', 'underline', 'clear']], 50964 ['para', ['ul', 'paragraph']], 50965 ['table', ['table']], 50966 ['insert', ['link', 'picture']] 50967 ] 50968 }, 50969 // air mode: inline editor 50970 airMode: false, 50971 width: null, 50972 height: null, 50973 linkTargetBlank: true, 50974 focus: false, 50975 tabSize: 4, 50976 styleWithSpan: true, 50977 shortcuts: true, 50978 textareaAutoSync: true, 50979 hintDirection: 'bottom', 50980 tooltip: 'auto', 50981 container: 'body', 50982 maxTextLength: 0, 50983 styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], 50984 fontNames: [ 50985 'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 50986 'Helvetica Neue', 'Helvetica', 'Impact', 'Lucida Grande', 50987 'Tahoma', 'Times New Roman', 'Verdana' 50988 ], 50989 fontSizes: ['8', '9', '10', '11', '12', '14', '18', '24', '36'], 50990 // pallete colors(n x n) 50991 colors: [ 50992 ['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'], 50993 ['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'], 50994 ['#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE'], 50995 ['#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD'], 50996 ['#E76363', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5'], 50997 ['#CE0000', '#E79439', '#EFC631', '#6BA54A', '#4A7B8C', '#3984C6', '#634AA5', '#A54A7B'], 50998 ['#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842'], 50999 ['#630000', '#7B3900', '#846300', '#295218', '#083139', '#003163', '#21104A', '#4A1031'] 51000 ], 51001 // http://chir.ag/projects/name-that-color/ 51002 colorsName: [ 51003 ['Black', 'Tundora', 'Dove Gray', 'Star Dust', 'Pale Slate', 'Gallery', 'Alabaster', 'White'], 51004 ['Red', 'Orange Peel', 'Yellow', 'Green', 'Cyan', 'Blue', 'Electric Violet', 'Magenta'], 51005 ['Azalea', 'Karry', 'Egg White', 'Zanah', 'Botticelli', 'Tropical Blue', 'Mischka', 'Twilight'], 51006 ['Tonys Pink', 'Peach Orange', 'Cream Brulee', 'Sprout', 'Casper', 'Perano', 'Cold Purple', 'Careys Pink'], 51007 ['Mandy', 'Rajah', 'Dandelion', 'Olivine', 'Gulf Stream', 'Viking', 'Blue Marguerite', 'Puce'], 51008 ['Guardsman Red', 'Fire Bush', 'Golden Dream', 'Chelsea Cucumber', 'Smalt Blue', 'Boston Blue', 'Butterfly Bush', 'Cadillac'], 51009 ['Sangria', 'Mai Tai', 'Buddha Gold', 'Forest Green', 'Eden', 'Venice Blue', 'Meteorite', 'Claret'], 51010 ['Rosewood', 'Cinnamon', 'Olive', 'Parsley', 'Tiber', 'Midnight Blue', 'Valentino', 'Loulou'] 51011 ], 51012 lineHeights: ['1.0', '1.2', '1.4', '1.5', '1.6', '1.8', '2.0', '3.0'], 51013 tableClassName: 'table table-bordered', 51014 insertTableMaxSize: { 51015 col: 10, 51016 row: 10 51017 }, 51018 dialogsInBody: false, 51019 dialogsFade: false, 51020 maximumImageFileSize: null, 51021 callbacks: { 51022 onInit: null, 51023 onFocus: null, 51024 onBlur: null, 51025 onBlurCodeview: null, 51026 onEnter: null, 51027 onKeyup: null, 51028 onKeydown: null, 51029 onImageUpload: null, 51030 onImageUploadError: null 51031 }, 51032 codemirror: { 51033 mode: 'text/html', 51034 htmlMode: true, 51035 lineNumbers: true 51036 }, 51037 keyMap: { 51038 pc: { 51039 'ENTER': 'insertParagraph', 51040 'CTRL+Z': 'undo', 51041 'CTRL+Y': 'redo', 51042 'TAB': 'tab', 51043 'SHIFT+TAB': 'untab', 51044 'CTRL+B': 'bold', 51045 'CTRL+I': 'italic', 51046 'CTRL+U': 'underline', 51047 'CTRL+SHIFT+S': 'strikethrough', 51048 'CTRL+BACKSLASH': 'removeFormat', 51049 'CTRL+SHIFT+L': 'justifyLeft', 51050 'CTRL+SHIFT+E': 'justifyCenter', 51051 'CTRL+SHIFT+R': 'justifyRight', 51052 'CTRL+SHIFT+J': 'justifyFull', 51053 'CTRL+SHIFT+NUM7': 'insertUnorderedList', 51054 'CTRL+SHIFT+NUM8': 'insertOrderedList', 51055 'CTRL+LEFTBRACKET': 'outdent', 51056 'CTRL+RIGHTBRACKET': 'indent', 51057 'CTRL+NUM0': 'formatPara', 51058 'CTRL+NUM1': 'formatH1', 51059 'CTRL+NUM2': 'formatH2', 51060 'CTRL+NUM3': 'formatH3', 51061 'CTRL+NUM4': 'formatH4', 51062 'CTRL+NUM5': 'formatH5', 51063 'CTRL+NUM6': 'formatH6', 51064 'CTRL+ENTER': 'insertHorizontalRule', 51065 'CTRL+K': 'linkDialog.show' 51066 }, 51067 mac: { 51068 'ENTER': 'insertParagraph', 51069 'CMD+Z': 'undo', 51070 'CMD+SHIFT+Z': 'redo', 51071 'TAB': 'tab', 51072 'SHIFT+TAB': 'untab', 51073 'CMD+B': 'bold', 51074 'CMD+I': 'italic', 51075 'CMD+U': 'underline', 51076 'CMD+SHIFT+S': 'strikethrough', 51077 'CMD+BACKSLASH': 'removeFormat', 51078 'CMD+SHIFT+L': 'justifyLeft', 51079 'CMD+SHIFT+E': 'justifyCenter', 51080 'CMD+SHIFT+R': 'justifyRight', 51081 'CMD+SHIFT+J': 'justifyFull', 51082 'CMD+SHIFT+NUM7': 'insertUnorderedList', 51083 'CMD+SHIFT+NUM8': 'insertOrderedList', 51084 'CMD+LEFTBRACKET': 'outdent', 51085 'CMD+RIGHTBRACKET': 'indent', 51086 'CMD+NUM0': 'formatPara', 51087 'CMD+NUM1': 'formatH1', 51088 'CMD+NUM2': 'formatH2', 51089 'CMD+NUM3': 'formatH3', 51090 'CMD+NUM4': 'formatH4', 51091 'CMD+NUM5': 'formatH5', 51092 'CMD+NUM6': 'formatH6', 51093 'CMD+ENTER': 'insertHorizontalRule', 51094 'CMD+K': 'linkDialog.show' 51095 } 51096 }, 51097 icons: { 51098 'align': 'note-icon-align', 51099 'alignCenter': 'note-icon-align-center', 51100 'alignJustify': 'note-icon-align-justify', 51101 'alignLeft': 'note-icon-align-left', 51102 'alignRight': 'note-icon-align-right', 51103 'rowBelow': 'note-icon-row-below', 51104 'colBefore': 'note-icon-col-before',
vendor: 9,396 bytes, lines 51105-51149
51105 'colAfter': 'note-icon-col-after', 51106 'rowAbove': 'note-icon-row-above', 51107 'rowRemove': 'note-icon-row-remove', 51108 'colRemove': 'note-icon-col-remove', 51109 'indent': 'note-icon-align-indent', 51110 'outdent': 'note-icon-align-outdent', 51111 'arrowsAlt': 'note-icon-arrows-alt', 51112 'bold': 'note-icon-bold', 51113 'caret': 'note-icon-caret', 51114 'circle': 'note-icon-circle', 51115 'close': 'note-icon-close', 51116 'code': 'note-icon-code', 51117 'eraser': 'note-icon-eraser', 51118 'font': 'note-icon-font', 51119 'frame': 'note-icon-frame', 51120 'italic': 'note-icon-italic', 51121 'link': 'note-icon-link', 51122 'unlink': 'note-icon-chain-broken', 51123 'magic': 'note-icon-magic', 51124 'menuCheck': 'note-icon-menu-check', 51125 'minus': 'note-icon-minus', 51126 'orderedlist': 'note-icon-orderedlist', 51127 'pencil': 'note-icon-pencil', 51128 'picture': 'note-icon-picture', 51129 'question': 'note-icon-question', 51130 'redo': 'note-icon-redo', 51131 'square': 'note-icon-square', 51132 'strikethrough': 'note-icon-strikethrough', 51133 'subscript': 'note-icon-subscript', 51134 'superscript': 'note-icon-superscript', 51135 'table': 'note-icon-table', 51136 'textHeight': 'note-icon-text-height', 51137 'trash': 'note-icon-trash', 51138 'underline': 'note-icon-underline', 51139 'undo': 'note-icon-undo', 51140 'unorderedlist': 'note-icon-unorderedlist', 51141 'video': 'note-icon-video' 51142 } 51143 } 51144}); 51145 51146}))); 51147//# sourceMappingURL=summernote.js.map 51148 51149;!function(e,a){"object"==typeof exports&&"undefined"!=typeof module?module.exports=a():"function"==typeof define&&define.amd?define(a):e.moment=a()}(this,function(){"use strict";var e,n;function l(){return e.apply(null,arguments)}function _(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function i(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function o(e){return void 0===e}function m(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function u(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function M(e,a){var t,s=[];for(t=0;t<e.length;++t)s.push(a(e[t],t));return s}function h(e,a){return Object.prototype.hasOwnProperty.call(e,a)}function L(e,a){for(var t in a)h(a,t)&&(e[t]=a[t]);return h(a,"toString")&&(e.toString=a.toString),h(a,"valueOf")&&(e.valueOf=a.valueOf),e}function c(e,a,t,s){return va(e,a,t,s,!0).utc()}function Y(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function y(e){if(null==e._isValid){var a=Y(e),t=n.call(a.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&a.overflow<0&&!a.empty&&!a.invalidMonth&&!a.invalidWeekday&&!a.weekdayMismatch&&!a.nullInput&&!a.invalidFormat&&!a.userInvalidated&&(!a.meridiem||a.meridiem&&t);if(e._strict&&(s=s&&0===a.charsLeftOver&&0===a.unusedTokens.length&&void 0===a.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function f(e){var a=c(NaN);return null!=e?L(Y(a),e):Y(a).userInvalidated=!0,a}n=Array.prototype.some?Array.prototype.some:function(e){for(var a=Object(this),t=a.length>>>0,s=0;s<t;s++)if(s in a&&e.call(this,a[s],s,a))return!0;return!1};var d=l.momentProperties=[];function k(e,a){var t,s,n;if(o(a._isAMomentObject)||(e._isAMomentObject=a._isAMomentObject),o(a._i)||(e._i=a._i),o(a._f)||(e._f=a._f),o(a._l)||(e._l=a._l),o(a._strict)||(e._strict=a._strict),o(a._tzm)||(e._tzm=a._tzm),o(a._isUTC)||(e._isUTC=a._isUTC),o(a._offset)||(e._offset=a._offset),o(a._pf)||(e._pf=Y(a)),o(a._locale)||(e._locale=a._locale),0<d.length)for(t=0;t<d.length;t++)o(n=a[s=d[t]])||(e[s]=n);return e}var a=!1;function p(e){k(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===a&&(a=!0,l.updateOffset(this),a=!1)}function D(e){return e instanceof p||null!=e&&null!=e._isAMomentObject}function T(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function g(e){var a=+e,t=0;return 0!==a&&isFinite(a)&&(t=T(a)),t}function r(e,a,t){var s,n=Math.min(e.length,a.length),d=Math.abs(e.length-a.length),r=0;for(s=0;s<n;s++)(t&&e[s]!==a[s]||!t&&g(e[s])!==g(a[s]))&&r++;return r+d}function w(e){!1===l.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function t(n,d){var r=!0;return L(function(){if(null!=l.deprecationHandler&&l.deprecationHandler(null,n),r){for(var e,a=[],t=0;t<arguments.length;t++){if(e="","object"==typeof arguments[t]){for(var s in e+="\n["+t+"] ",arguments[0])e+=s+": "+arguments[0][s]+", ";e=e.slice(0,-2)}else e=arguments[t];a.push(e)}w(n+"\nArguments: "+Array.prototype.slice.call(a).join("")+"\n"+(new Error).stack),r=!1}return d.apply(this,arguments)},d)}var s,v={};function S(e,a){null!=l.deprecationHandler&&l.deprecationHandler(e,a),v[e]||(w(a),v[e]=!0)}function H(e){return e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function b(e,a){var t,s=L({},e);for(t in a)h(a,t)&&(i(e[t])&&i(a[t])?(s[t]={},L(s[t],e[t]),L(s[t],a[t])):null!=a[t]?s[t]=a[t]:delete s[t]);for(t in e)h(e,t)&&!h(a,t)&&i(e[t])&&(s[t]=L({},s[t]));return s}function j(e){null!=e&&this.set(e)}l.suppressDeprecationWarnings=!1,l.deprecationHandler=null,s=Object.keys?Object.keys:function(e){var a,t=[];for(a in e)h(e,a)&&t.push(a);return t};var x={};function P(e,a){var t=e.toLowerCase();x[t]=x[t+"s"]=x[a]=e}function O(e){return"string"==typeof e?x[e]||x[e.toLowerCase()]:void 0}function W(e){var a,t,s={};for(t in e)h(e,t)&&(a=O(t))&&(s[a]=e[t]);return s}var E={};function A(e,a){E[e]=a}function F(e,a,t){var s=""+Math.abs(e),n=a-s.length;return(0<=e?t?"+":"":"-")+Math.pow(10,Math.max(0,n)).toString().substr(1)+s}var z=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,J=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,N={},R={};function I(e,a,t,s){var n=s;"string"==typeof s&&(n=function(){return this[s]()}),e&&(R[e]=n),a&&(R[a[0]]=function(){return F(n.apply(this,arguments),a[1],a[2])}),t&&(R[t]=function(){return this.localeData().ordinal(n.apply(this,arguments),e)})}function C(e,a){return e.isValid()?(a=G(a,e.localeData()),N[a]=N[a]||function(s){var e,n,a,d=s.match(z);for(e=0,n=d.length;e<n;e++)R[d[e]]?d[e]=R[d[e]]:d[e]=(a=d[e]).match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"");return function(e){var a,t="";for(a=0;a<n;a++)t+=H(d[a])?d[a].call(e,s):d[a];return t}}(a),N[a](e)):e.localeData().invalidDate()}function G(e,a){var t=5;function s(e){return a.longDateFormat(e)||e}for(J.lastIndex=0;0<=t&&J.test(e);)e=e.replace(J,s),J.lastIndex=0,t-=1;return e}var U=/\d/,V=/\d\d/,K=/\d{3}/,Z=/\d{4}/,$=/[+-]?\d{6}/,B=/\d\d?/,q=/\d\d\d\d?/,Q=/\d\d\d\d\d\d?/,X=/\d{1,3}/,ee=/\d{1,4}/,ae=/[+-]?\d{1,6}/,te=/\d+/,se=/[+-]?\d+/,ne=/Z|[+-]\d\d:?\d\d/gi,de=/Z|[+-]\d\d(?::?\d\d)?/gi,re=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,_e={};function ie(e,t,s){_e[e]=H(t)?t:function(e,a){return e&&s?s:t}}function oe(e,a){return h(_e,e)?_e[e](a._strict,a._locale):new RegExp(me(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,a,t,s,n){return a||t||s||n})))}function me(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ue={};function le(e,t){var a,s=t;for("string"==typeof e&&(e=[e]),m(t)&&(s=function(e,a){a[t]=g(e)}),a=0;a<e.length;a++)ue[e[a]]=s}function Me(e,n){le(e,function(e,a,t,s){t._w=t._w||{},n(e,t._w,t,s)})}var he=0,Le=1,ce=2,Ye=3,ye=4,fe=5,ke=6,pe=7,De=8;function Te(e){return ge(e)?366:365}function ge(e){return e%4==0&&e%100!=0||e%400==0}I("Y",0,0,function(){var e=this.year();return e<=9999?""+e:"+"+e}),I(0,["YY",2],0,function(){return this.year()%100}),I(0,["YYYY",4],0,"year"),I(0,["YYYYY",5],0,"year"),I(0,["YYYYYY",6,!0],0,"year"),P("year","y"),A("year",1),ie("Y",se),ie("YY",B,V),ie("YYYY",ee,Z),ie("YYYYY",ae,$),ie("YYYYYY",ae,$),le(["YYYYY","YYYYYY"],he),le("YYYY",function(e,a){a[he]=2===e.length?l.parseTwoDigitYear(e):g(e)}),le("YY",function(e,a){a[he]=l.parseTwoDigitYear(e)}),le("Y",function(e,a){a[he]=parseInt(e,10)}),l.parseTwoDigitYear=function(e){return g(e)+(68<g(e)?1900:2e3)};var we,ve=Se("FullYear",!0);function Se(a,t){return function(e){return null!=e?(be(this,a,e),l.updateOffset(this,t),this):He(this,a)}}function He(e,a){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+a]():NaN}function be(e,a,t){e.isValid()&&!isNaN(t)&&("FullYear"===a&&ge(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+a](t,e.month(),je(t,e.month())):e._d["set"+(e._isUTC?"UTC":"")+a](t))}function je(e,a){if(isNaN(e)||isNaN(a))return NaN;var t,s=(a%(t=12)+t)%t;return e+=(a-s)/12,1===s?ge(e)?29:28:31-s%7%2}we=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var a;for(a=0;a<this.length;++a)if(this[a]===e)return a;return-1},I("M",["MM",2],"Mo",function(){return this.month()+1}
vendor: 4,405 bytes, line 51149
51149),I("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),I("MMMM",0,0,function(e){return this.localeData().months(this,e)}),P("month","M"),A("month",8),ie("M",B),ie("MM",B,V),ie("MMM",function(e,a){return a.monthsShortRegex(e)}),ie("MMMM",function(e,a){return a.monthsRegex(e)}),le(["M","MM"],function(e,a){a[Le]=g(e)-1}),le(["MMM","MMMM"],function(e,a,t,s){var n=t._locale.monthsParse(e,s,t._strict);null!=n?a[Le]=n:Y(t).invalidMonth=e});var xe=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,Pe="January_February_March_April_May_June_July_August_September_October_November_December".split("_");var Oe="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function We(e,a){var t;if(!e.isValid())return e;if("string"==typeof a)if(/^\d+$/.test(a))a=g(a);else if(!m(a=e.localeData().monthsParse(a)))return e;return t=Math.min(e.date(),je(e.year(),a)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](a,t),e}function Ee(e){return null!=e?(We(this,e),l.updateOffset(this,!0),this):He(this,"Month")}var Ae=re;var Fe=re;function ze(){function e(e,a){return a.length-e.length}var a,t,s=[],n=[],d=[];for(a=0;a<12;a++)t=c([2e3,a]),s.push(this.monthsShort(t,"")),n.push(this.months(t,"")),d.push(this.months(t,"")),d.push(this.monthsShort(t,""));for(s.sort(e),n.sort(e),d.sort(e),a=0;a<12;a++)s[a]=me(s[a]),n[a]=me(n[a]);for(a=0;a<24;a++)d[a]=me(d[a]);this._monthsRegex=new RegExp("^("+d.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+n.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+s.join("|")+")","i")}function Je(e){var a=new Date(Date.UTC.apply(null,arguments));return e<100&&0<=e&&isFinite(a.getUTCFullYear())&&a.setUTCFullYear(e),a}function Ne(e,a,t){var s=7+a-t;return-((7+Je(e,0,s).getUTCDay()-a)%7)+s-1}function Re(e,a,t,s,n){var d,r,_=1+7*(a-1)+(7+t-s)%7+Ne(e,s,n);return _<=0?r=Te(d=e-1)+_:_>Te(e)?(d=e+1,r=_-Te(e)):(d=e,r=_),{year:d,dayOfYear:r}}function Ie(e,a,t){var s,n,d=Ne(e.year(),a,t),r=Math.floor((e.dayOfYear()-d-1)/7)+1;return r<1?s=r+Ce(n=e.year()-1,a,t):r>Ce(e.year(),a,t)?(s=r-Ce(e.year(),a,t),n=e.year()+1):(n=e.year(),s=r),{week:s,year:n}}function Ce(e,a,t){var s=Ne(e,a,t),n=Ne(e+1,a,t);return(Te(e)-s+n)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),P("week","w"),P("isoWeek","W"),A("week",5),A("isoWeek",5),ie("w",B),ie("ww",B,V),ie("W",B),ie("WW",B,V),Me(["w","ww","W","WW"],function(e,a,t,s){a[s.substr(0,1)]=g(e)});I("d",0,"do","day"),I("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),I("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),I("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),P("day","d"),P("weekday","e"),P("isoWeekday","E"),A("day",11),A("weekday",11),A("isoWeekday",11),ie("d",B),ie("e",B),ie("E",B),ie("dd",function(e,a){return a.weekdaysMinRegex(e)}),ie("ddd",function(e,a){return a.weekdaysShortRegex(e)}),ie("dddd",function(e,a){return a.weekdaysRegex(e)}),Me(["dd","ddd","dddd"],function(e,a,t,s){var n=t._locale.weekdaysParse(e,s,t._strict);null!=n?a.d=n:Y(t).invalidWeekday=e}),Me(["d","e","E"],function(e,a,t,s){a[s]=g(e)});var Ge="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var Ue="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var Ve="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var Ke=re;var Ze=re;var $e=re;function Be(){function e(e,a){return a.length-e.length}var a,t,s,n,d,r=[],_=[],i=[],o=[];for(a=0;a<7;a++)t=c([2e3,1]).day(a),s=this.weekdaysMin(t,""),n=this.weekdaysShort(t,""),d=this.weekdays(t,""),r.push(s),_.push(n),i.push(d),o.push(s),o.push(n),o.push(d);for(r.sort(e),_.sort(e),i.sort(e),o.sort(e),a=0;a<7;a++)_[a]=me(_[a]),i[a]=me(i[a]),o[a]=me(o[a]);this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+_.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function qe(){return this.hours()%12||12}function Qe(e,a){I(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),a)})}function Xe(e,a){return a._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,qe),I("k",["kk",2],0,function(){return this.hours()||24}),I("hmm",0,0,function(){return""+qe.apply(this)+F(this.minutes(),2)}
vendor: 4,687 bytes, line 51149
51149),I("hmmss",0,0,function(){return""+qe.apply(this)+F(this.minutes(),2)+F(this.seconds(),2)}),I("Hmm",0,0,function(){return""+this.hours()+F(this.minutes(),2)}),I("Hmmss",0,0,function(){return""+this.hours()+F(this.minutes(),2)+F(this.seconds(),2)}),Qe("a",!0),Qe("A",!1),P("hour","h"),A("hour",13),ie("a",Xe),ie("A",Xe),ie("H",B),ie("h",B),ie("k",B),ie("HH",B,V),ie("hh",B,V),ie("kk",B,V),ie("hmm",q),ie("hmmss",Q),ie("Hmm",q),ie("Hmmss",Q),le(["H","HH"],Ye),le(["k","kk"],function(e,a,t){var s=g(e);a[Ye]=24===s?0:s}),le(["a","A"],function(e,a,t){t._isPm=t._locale.isPM(e),t._meridiem=e}),le(["h","hh"],function(e,a,t){a[Ye]=g(e),Y(t).bigHour=!0}),le("hmm",function(e,a,t){var s=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s)),Y(t).bigHour=!0}),le("hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s,2)),a[fe]=g(e.substr(n)),Y(t).bigHour=!0}),le("Hmm",function(e,a,t){var s=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s))}),le("Hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s,2)),a[fe]=g(e.substr(n))});var ea,aa=Se("Hours",!0),ta={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Pe,monthsShort:Oe,week:{dow:0,doy:6},weekdays:Ge,weekdaysMin:Ve,weekdaysShort:Ue,meridiemParse:/[ap]\.?m?\.?/i},sa={},na={};function da(e){return e?e.toLowerCase().replace("_","-"):e}function ra(e){var a=null;if(!sa[e]&&"undefined"!=typeof module&&module&&module.exports)try{a=ea._abbr,require("./locale/"+e),_a(a)}catch(e){}return sa[e]}function _a(e,a){var t;return e&&((t=o(a)?oa(e):ia(e,a))?ea=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),ea._abbr}function ia(e,a){if(null!==a){var t,s=ta;if(a.abbr=e,null!=sa[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=sa[e]._config;else if(null!=a.parentLocale)if(null!=sa[a.parentLocale])s=sa[a.parentLocale]._config;else{if(null==(t=ra(a.parentLocale)))return na[a.parentLocale]||(na[a.parentLocale]=[]),na[a.parentLocale].push({name:e,config:a}),null;s=t._config}return sa[e]=new j(b(s,a)),na[e]&&na[e].forEach(function(e){ia(e.name,e.config)}),_a(e),sa[e]}return delete sa[e],null}function oa(e){var a;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return ea;if(!_(e)){if(a=ra(e))return a;e=[e]}return function(e){for(var a,t,s,n,d=0;d<e.length;){for(a=(n=da(e[d]).split("-")).length,t=(t=da(e[d+1]))?t.split("-"):null;0<a;){if(s=ra(n.slice(0,a).join("-")))return s;if(t&&t.length>=a&&r(n,t,!0)>=a-1)break;a--}d++}return ea}(e)}function ma(e){var a,t=e._a;return t&&-2===Y(e).overflow&&(a=t[Le]<0||11<t[Le]?Le:t[ce]<1||t[ce]>je(t[he],t[Le])?ce:t[Ye]<0||24<t[Ye]||24===t[Ye]&&(0!==t[ye]||0!==t[fe]||0!==t[ke])?Ye:t[ye]<0||59<t[ye]?ye:t[fe]<0||59<t[fe]?fe:t[ke]<0||999<t[ke]?ke:-1,Y(e)._overflowDayOfYear&&(a<he||ce<a)&&(a=ce),Y(e)._overflowWeeks&&-1===a&&(a=pe),Y(e)._overflowWeekday&&-1===a&&(a=De),Y(e).overflow=a),e}function ua(e,a,t){return null!=e?e:null!=a?a:t}function la(e){var a,t,s,n,d,r=[];if(!e._d){var _,i;for(_=e,i=new Date(l.now()),s=_._useUTC?[i.getUTCFullYear(),i.getUTCMonth(),i.getUTCDate()]:[i.getFullYear(),i.getMonth(),i.getDate()],e._w&&null==e._a[ce]&&null==e._a[Le]&&function(e){var a,t,s,n,d,r,_,i;if(null!=(a=e._w).GG||null!=a.W||null!=a.E)d=1,r=4,t=ua(a.GG,e._a[he],Ie(Sa(),1,4).year),s=ua(a.W,1),((n=ua(a.E,1))<1||7<n)&&(i=!0);else{d=e._locale._week.dow,r=e._locale._week.doy;var o=Ie(Sa(),d,r);t=ua(a.gg,e._a[he],o.year),s=ua(a.w,o.week),null!=a.d?((n=a.d)<0||6<n)&&(i=!0):null!=a.e?(n=a.e+d,(a.e<0||6<a.e)&&(i=!0)):n=d}s<1||s>Ce(t,d,r)?Y(e)._overflowWeeks=!0:null!=i?Y(e)._overflowWeekday=!0:(_=Re(t,s,n,d,r),e._a[he]=_.year,e._dayOfYear=_.dayOfYear)}(e),null!=e._dayOfYear&&(d=ua(e._a[he],s[he]),(e._dayOfYear>Te(d)||0===e._dayOfYear)&&(Y(e)._overflowDayOfYear=!0),t=Je(d,0,e._dayOfYear),e._a[Le]=t.getUTCMonth(),e._a[ce]=t.getUTCDate()),a=0;a<3&&null==e._a[a];++a)e._a[a]=r[a]=s[a];for(;a<7;
vendor: 31,714 bytes, line 51149
51149a++)e._a[a]=r[a]=null==e._a[a]?2===a?1:0:e._a[a];24===e._a[Ye]&&0===e._a[ye]&&0===e._a[fe]&&0===e._a[ke]&&(e._nextDay=!0,e._a[Ye]=0),e._d=(e._useUTC?Je:function(e,a,t,s,n,d,r){var _=new Date(e,a,t,s,n,d,r);return e<100&&0<=e&&isFinite(_.getFullYear())&&_.setFullYear(e),_}).apply(null,r),n=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[Ye]=24),e._w&&void 0!==e._w.d&&e._w.d!==n&&(Y(e).weekdayMismatch=!0)}}var Ma=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ha=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,La=/Z|[+-]\d\d(?::?\d\d)?/,ca=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Ya=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],ya=/^\/?Date\((\-?\d+)/i;function fa(e){var a,t,s,n,d,r,_=e._i,i=Ma.exec(_)||ha.exec(_);if(i){for(Y(e).iso=!0,a=0,t=ca.length;a<t;a++)if(ca[a][1].exec(i[1])){n=ca[a][0],s=!1!==ca[a][2];break}if(null==n)return void(e._isValid=!1);if(i[3]){for(a=0,t=Ya.length;a<t;a++)if(Ya[a][1].exec(i[3])){d=(i[2]||" ")+Ya[a][0];break}if(null==d)return void(e._isValid=!1)}if(!s&&null!=d)return void(e._isValid=!1);if(i[4]){if(!La.exec(i[4]))return void(e._isValid=!1);r="Z"}e._f=n+(d||"")+(r||""),ga(e)}else e._isValid=!1}var ka=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;function pa(e,a,t,s,n,d){var r=[function(e){var a=parseInt(e,10);{if(a<=49)return 2e3+a;if(a<=999)return 1900+a}return a}(e),Oe.indexOf(a),parseInt(t,10),parseInt(s,10),parseInt(n,10)];return d&&r.push(parseInt(d,10)),r}var Da={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Ta(e){var a,t,s,n=ka.exec(e._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").trim());if(n){var d=pa(n[4],n[3],n[2],n[5],n[6],n[7]);if(a=n[1],t=d,s=e,a&&Ue.indexOf(a)!==new Date(t[0],t[1],t[2]).getDay()&&(Y(s).weekdayMismatch=!0,!(s._isValid=!1)))return;e._a=d,e._tzm=function(e,a,t){if(e)return Da[e];if(a)return 0;var s=parseInt(t,10),n=s%100;return(s-n)/100*60+n}(n[8],n[9],n[10]),e._d=Je.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),Y(e).rfc2822=!0}else e._isValid=!1}function ga(e){if(e._f!==l.ISO_8601)if(e._f!==l.RFC_2822){e._a=[],Y(e).empty=!0;var a,t,s,n,d,r,_,i,o=""+e._i,m=o.length,u=0;for(s=G(e._f,e._locale).match(z)||[],a=0;a<s.length;a++)n=s[a],(t=(o.match(oe(n,e))||[])[0])&&(0<(d=o.substr(0,o.indexOf(t))).length&&Y(e).unusedInput.push(d),o=o.slice(o.indexOf(t)+t.length),u+=t.length),R[n]?(t?Y(e).empty=!1:Y(e).unusedTokens.push(n),r=n,i=e,null!=(_=t)&&h(ue,r)&&ue[r](_,i._a,i,r)):e._strict&&!t&&Y(e).unusedTokens.push(n);Y(e).charsLeftOver=m-u,0<o.length&&Y(e).unusedInput.push(o),e._a[Ye]<=12&&!0===Y(e).bigHour&&0<e._a[Ye]&&(Y(e).bigHour=void 0),Y(e).parsedDateParts=e._a.slice(0),Y(e).meridiem=e._meridiem,e._a[Ye]=function(e,a,t){var s;if(null==t)return a;return null!=e.meridiemHour?e.meridiemHour(a,t):(null!=e.isPM&&((s=e.isPM(t))&&a<12&&(a+=12),s||12!==a||(a=0)),a)}(e._locale,e._a[Ye],e._meridiem),la(e),ma(e)}else Ta(e);else fa(e)}function wa(e){var a,t,s,n,d=e._i,r=e._f;return e._locale=e._locale||oa(e._l),null===d||void 0===r&&""===d?f({nullInput:!0}):("string"==typeof d&&(e._i=d=e._locale.preparse(d)),D(d)?new p(ma(d)):(u(d)?e._d=d:_(r)?function(e){var a,t,s,n,d;if(0===e._f.length)return Y(e).invalidFormat=!0,e._d=new Date(NaN);for(n=0;n<e._f.length;n++)d=0,a=k({},e),null!=e._useUTC&&(a._useUTC=e._useUTC),a._f=e._f[n],ga(a),y(a)&&(d+=Y(a).charsLeftOver,d+=10*Y(a).unusedTokens.length,Y(a).score=d,(null==s||d<s)&&(s=d,t=a));L(e,t||a)}(e):r?ga(e):o(t=(a=e)._i)?a._d=new Date(l.now()):u(t)?a._d=new Date(t.valueOf()):"string"==typeof t?(s=a,null===(n=ya.exec(s._i))?(fa(s),!1===s._isValid&&(delete s._isValid,Ta(s),!1===s._isValid&&(delete s._isValid,l.createFromInputFallback(s)))):s._d=new Date(+n[1])):_(t)?(a._a=M(t.slice(0),function(e){return parseInt(e,10)}),la(a)):i(t)?function(e){if(!e._d){var a=W(e._i);e._a=M([a.year,a.month,a.day||a.date,a.hour,a.minute,a.second,a.millisecond],function(e){return e&&parseInt(e,10)}),la(e)}}(a):m(t)?a._d=new Date(t):l.createFromInputFallback(a),y(e)||(e._d=null),e))}function va(e,a,t,s,n){var d,r={};return!0!==t&&!1!==t||(s=t,t=void 0),(i(e)&&function(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var a;for(a in e)if(e.hasOwnProperty(a))return!1;return!0}(e)||_(e)&&0===e.length)&&(e=void 0),r._isAMomentObject=!0,r._useUTC=r._isUTC=n,r._l=t,r._i=e,r._f=a,r._strict=s,(d=new p(ma(wa(r))))._nextDay&&(d.add(1,"d"),d._nextDay=void 0),d}function Sa(e,a,t,s){return va(e,a,t,s,!1)}l.createFromInputFallback=t("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),l.ISO_8601=function(){},l.RFC_2822=function(){};var Ha=t("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Sa.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:f()}),ba=t("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Sa.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:f()});function ja(e,a){var t,s;if(1===a.length&&_(a[0])&&(a=a[0]),!a.length)return Sa();for(t=a[0],s=1;s<a.length;++s)a[s].isValid()&&!a[s][e](t)||(t=a[s]);return t}var xa=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Pa(e){var a=W(e),t=a.year||0,s=a.quarter||0,n=a.month||0,d=a.week||0,r=a.day||0,_=a.hour||0,i=a.minute||0,o=a.second||0,m=a.millisecond||0;this._isValid=function(e){for(var a in e)if(-1===we.call(xa,a)||null!=e[a]&&isNaN(e[a]))return!1;for(var t=!1,s=0;s<xa.length;++s)if(e[xa[s]]){if(t)return!1;parseFloat(e[xa[s]])!==g(e[xa[s]])&&(t=!0)}return!0}(a),this._milliseconds=+m+1e3*o+6e4*i+1e3*_*60*60,this._days=+r+7*d,this._months=+n+3*s+12*t,this._data={},this._locale=oa(),this._bubble()}function Oa(e){return e instanceof Pa}function Wa(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ea(e,t){I(e,0,0,function(){var e=this.utcOffset(),a="+";return e<0&&(e=-e,a="-"),a+F(~~(e/60),2)+t+F(~~e%60,2)})}Ea("Z",":"),Ea("ZZ",""),ie("Z",de),ie("ZZ",de),le(["Z","ZZ"],function(e,a,t){t._useUTC=!0,t._tzm=Fa(de,e)});var Aa=/([\+\-]|\d\d)/gi;function Fa(e,a){var t=(a||"").match(e);if(null===t)return null;var s=((t[t.length-1]||[])+"").match(Aa)||["-",0,0],n=60*s[1]+g(s[2]);return 0===n?0:"+"===s[0]?n:-n}function za(e,a){var t,s;return a._isUTC?(t=a.clone(),s=(D(e)||u(e)?e.valueOf():Sa(e).valueOf())-t.valueOf(),t._d.setTime(t._d.valueOf()+s),l.updateOffset(t,!1),t):Sa(e).local()}function Ja(e){return 15*-Math.round(e._d.getTimezoneOffset()/15)}function Na(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}l.updateOffset=function(){};var Ra=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ia=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function Ca(e,a){var t,s,n,d=e,r=null;return Oa(e)?d={ms:e._milliseconds,d:e._days,M:e._months}:m(e)?(d={},a?d[a]=e:d.milliseconds=e):(r=Ra.exec(e))?(t="-"===r[1]?-1:1,d={y:0,d:g(r[ce])*t,h:g(r[Ye])*t,m:g(r[ye])*t,s:g(r[fe])*t,ms:g(Wa(1e3*r[ke]))*t}):(r=Ia.exec(e))?(t="-"===r[1]?-1:(r[1],1),d={y:Ga(r[2],t),M:Ga(r[3],t),w:Ga(r[4],t),d:Ga(r[5],t),h:Ga(r[6],t),m:Ga(r[7],t),s:Ga(r[8],t)}):null==d?d={}:"object"==typeof d&&("from"in d||"to"in d)&&(n=function(e,a){var t;if(!e.isValid()||!a.isValid())return{milliseconds:0,months:0};a=za(a,e),e.isBefore(a)?t=Ua(e,a):((t=Ua(a,e)).milliseconds=-t.milliseconds,t.months=-t.months);return t}(Sa(d.from),Sa(d.to)),(d={}).ms=n.milliseconds,d.M=n.months),s=new Pa(d),Oa(e)&&h(e,"_locale")&&(s._locale=e._locale),s}function Ga(e,a){var t=e&&parseFloat(e.replace(",","."));return(isNaN(t)?0:t)*a}function Ua(e,a){var t={milliseconds:0,months:0};return t.months=a.month()-e.month()+12*(a.year()-e.year()),e.clone().add(t.months,"M").isAfter(a)&&--t.months,t.milliseconds=+a-+e.clone().add(t.months,"M"),t}function Va(s,n){return function(e,a){var t;return null===a||isNaN(+a)||(S(n,"moment()."+n+"(period, number) is deprecated. Please use moment()."+n+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),t=e,e=a,a=t),Ka(this,Ca(e="string"==typeof e?+e:e,a),s),this}}function Ka(e,a,t,s){var n=a._milliseconds,d=Wa(a._days),r=Wa(a._months);e.isValid()&&(s=null==s||s,r&&We(e,He(e,"Month")+r*t),d&&be(e,"Date",He(e,"Date")+d*t),n&&e._d.setTime(e._d.valueOf()+n*t),s&&l.updateOffset(e,d||r))}Ca.fn=Pa.prototype,Ca.invalid=function(){return Ca(NaN)};var Za=Va(1,"add"),$a=Va(-1,"subtract");function Ba(e,a){var t=12*(a.year()-e.year())+(a.month()-e.month()),s=e.clone().add(t,"months");return-(t+(a-s<0?(a-s)/(s-e.clone().add(t-1,"months")):(a-s)/(e.clone().add(t+1,"months")-s)))||0}function qa(e){var a;return void 0===e?this._locale._abbr:(null!=(a=oa(e))&&(this._locale=a),this)}l.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",l.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Qa=t("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function Xa(){return this._locale}function et(e,a){I(0,[e,e.length],0,a)}function at(e,a,t,s,n){var d;return null==e?Ie(this,s,n).year:((d=Ce(e,s,n))<a&&(a=d),function(e,a,t,s,n){var d=Re(e,a,t,s,n),r=Je(d.year,0,d.dayOfYear);return this.year(r.getUTCFullYear()),this.month(r.getUTCMonth()),this.date(r.getUTCDate()),this}.call(this,e,a,t,s,n))}I(0,["gg",2],0,function(){return this.weekYear()%100}),I(0,["GG",2],0,function(){return this.isoWeekYear()%100}),et("gggg","weekYear"),et("ggggg","weekYear"),et("GGGG","isoWeekYear"),et("GGGGG","isoWeekYear"),P("weekYear","gg"),P("isoWeekYear","GG"),A("weekYear",1),A("isoWeekYear",1),ie("G",se),ie("g",se),ie("GG",B,V),ie("gg",B,V),ie("GGGG",ee,Z),ie("gggg",ee,Z),ie("GGGGG",ae,$),ie("ggggg",ae,$),Me(["gggg","ggggg","GGGG","GGGGG"],function(e,a,t,s){a[s.substr(0,2)]=g(e)}),Me(["gg","GG"],function(e,a,t,s){a[s]=l.parseTwoDigitYear(e)}),I("Q",0,"Qo","quarter"),P("quarter","Q"),A("quarter",7),ie("Q",U),le("Q",function(e,a){a[Le]=3*(g(e)-1)}),I("D",["DD",2],"Do","date"),P("date","D"),A("date",9),ie("D",B),ie("DD",B,V),ie("Do",function(e,a){return e?a._dayOfMonthOrdinalParse||a._ordinalParse:a._dayOfMonthOrdinalParseLenient}),le(["D","DD"],ce),le("Do",function(e,a){a[ce]=g(e.match(B)[0])});var tt=Se("Date",!0);I("DDD",["DDDD",3],"DDDo","dayOfYear"),P("dayOfYear","DDD"),A("dayOfYear",4),ie("DDD",X),ie("DDDD",K),le(["DDD","DDDD"],function(e,a,t){t._dayOfYear=g(e)}),I("m",["mm",2],0,"minute"),P("minute","m"),A("minute",14),ie("m",B),ie("mm",B,V),le(["m","mm"],ye);var st=Se("Minutes",!1);I("s",["ss",2],0,"second"),P("second","s"),A("second",15),ie("s",B),ie("ss",B,V),le(["s","ss"],fe);var nt,dt=Se("Seconds",!1);for(I("S",0,0,function(){return~~(this.millisecond()/100)}),I(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),I(0,["SSS",3],0,"millisecond"),I(0,["SSSS",4],0,function(){return 10*this.millisecond()}),I(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),I(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),I(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),I(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),I(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),P("millisecond","ms"),A("millisecond",16),ie("S",X,U),ie("SS",X,V),ie("SSS",X,K),nt="SSSS";nt.length<=9;nt+="S")ie(nt,te);function rt(e,a){a[ke]=g(1e3*("0."+e))}for(nt="S";nt.length<=9;nt+="S")le(nt,rt);var _t=Se("Milliseconds",!1);I("z",0,0,"zoneAbbr"),I("zz",0,0,"zoneName");var it=p.prototype;function ot(e){return e}it.add=Za,it.calendar=function(e,a){var t=e||Sa(),s=za(t,this).startOf("day"),n=l.calendarFormat(this,s)||"sameElse",d=a&&(H(a[n])?a[n].call(this,t):a[n]);return this.format(d||this.localeData().calendar(n,this,Sa(t)))},it.clone=function(){return new p(this)},it.diff=function(e,a,t){var s,n,d;if(!this.isValid())return NaN;if(!(s=za(e,this)).isValid())return NaN;switch(n=6e4*(s.utcOffset()-this.utcOffset()),a=O(a)){case"year":d=Ba(this,s)/12;break;case"month":d=Ba(this,s);break;case"quarter":d=Ba(this,s)/3;break;case"second":d=(this-s)/1e3;break;case"minute":d=(this-s)/6e4;break;case"hour":d=(this-s)/36e5;break;case"day":d=(this-s-n)/864e5;break;case"week":d=(this-s-n)/6048e5;break;default:d=this-s}return t?d:T(d)},it.endOf=function(e){return void 0===(e=O(e))||"millisecond"===e?this:("date"===e&&(e="day"),this.startOf(e).add(1,"isoWeek"===e?"week":e).subtract(1,"ms"))},it.format=function(e){e||(e=this.isUtc()?l.defaultFormatUtc:l.defaultFormat);var a=C(this,e);return this.localeData().postformat(a)},it.from=function(e,a){return this.isValid()&&(D(e)&&e.isValid()||Sa(e).isValid())?Ca({to:this,from:e}).locale(this.locale()).humanize(!a):this.localeData().invalidDate()},it.fromNow=function(e){return this.from(Sa(),e)},it.to=function(e,a){return this.isValid()&&(D(e)&&e.isValid()||Sa(e).isValid())?Ca({from:this,to:e}).locale(this.locale()).humanize(!a):this.localeData().invalidDate()},it.toNow=function(e){return this.to(Sa(),e)},it.get=function(e){return H(this[e=O(e)])?this[e]():this},it.invalidAt=function(){return Y(this).overflow},it.isAfter=function(e,a){var t=D(e)?e:Sa(e);return!(!this.isValid()||!t.isValid())&&("millisecond"===(a=O(o(a)?"millisecond":a))?this.valueOf()>t.valueOf():t.valueOf()<this.clone().startOf(a).valueOf())},it.isBefore=function(e,a){var t=D(e)?e:Sa(e);return!(!this.isValid()||!t.isValid())&&("millisecond"===(a=O(o(a)?"millisecond":a))?this.valueOf()<t.valueOf():this.clone().endOf(a).valueOf()<t.valueOf())},it.isBetween=function(e,a,t,s){return("("===(s=s||"()")[0]?this.isAfter(e,t):!this.isBefore(e,t))&&(")"===s[1]?this.isBefore(a,t):!this.isAfter(a,t))},it.isSame=function(e,a){var t,s=D(e)?e:Sa(e);return!(!this.isValid()||!s.isValid())&&("millisecond"===(a=O(a||"millisecond"))?this.valueOf()===s.valueOf():(t=s.valueOf(),this.clone().startOf(a).valueOf()<=t&&t<=this.clone().endOf(a).valueOf()))},it.isSameOrAfter=function(e,a){return this.isSame(e,a)||this.isAfter(e,a)},it.isSameOrBefore=function(e,a){return this.isSame(e,a)||this.isBefore(e,a)},it.isValid=function(){return y(this)},it.lang=Qa,it.locale=qa,it.localeData=Xa,it.max=ba,it.min=Ha,it.parsingFlags=function(){return L({},Y(this))},it.set=function(e,a){if("object"==typeof e)for(var t=function(e){var a=[];for(var t in e)a.push({unit:t,priority:E[t]});return a.sort(function(e,a){return e.priority-a.priority}),a}(e=W(e)),s=0;s<t.length;s++)this[t[s].unit](e[t[s].unit]);else if(H(this[e=O(e)]))return this[e](a);return this},it.startOf=function(e){switch(e=O(e)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===e&&this.weekday(0),"isoWeek"===e&&this.isoWeekday(1),"quarter"===e&&this.month(3*Math.floor(this.month()/3)),this},it.subtract=$a,it.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},it.toObject=function(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}},it.toDate=function(){return new Date(this.valueOf())},it.toISOString=function(e){if(!this.isValid())return null;var a=!0!==e,t=a?this.clone().utc():this;return t.year()<0||9999<t.year()?C(t,a?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):H(Date.prototype.toISOString)?a?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",C(t,"Z")):C(t,a?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},it.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",a="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",a="Z");var t="["+e+'("]',s=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",n=a+'[")]';return this.format(t+s+"-MM-DD[T]HH:mm:ss.SSS"+n)},it.toJSON=function(){return this.isValid()?this.toISOString():null},it.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},it.unix=function(){return Math.floor(this.valueOf()/1e3)},it.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},it.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},it.year=ve,it.isLeapYear=function(){return ge(this.year())},it.weekYear=function(e){return at.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},it.isoWeekYear=function(e){return at.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},it.quarter=it.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},it.month=Ee,it.daysInMonth=function(){return je(this.year(),this.month())},it.week=it.weeks=function(e){var a=this.localeData().week(this);return null==e?a:this.add(7*(e-a),"d")},it.isoWeek=it.isoWeeks=function(e){var a=Ie(this,1,4).week;return null==e?a:this.add(7*(e-a),"d")},it.weeksInYear=function(){var e=this.localeData()._week;return Ce(this.year(),e.dow,e.doy)},it.isoWeeksInYear=function(){return Ce(this.year(),1,4)},it.date=tt,it.day=it.days=function(e){if(!this.isValid())return null!=e?this:NaN;var a,t,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(a=e,t=this.localeData(),e="string"!=typeof a?a:isNaN(a)?"number"==typeof(a=t.weekdaysParse(a))?a:null:parseInt(a,10),this.add(e-s,"d")):s},it.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var a=(this.day()+7-this.localeData()._week.dow)%7;return null==e?a:this.add(e-a,"d")},it.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var a=(t=e,s=this.localeData(),"string"==typeof t?s.weekdaysParse(t)%7||7:isNaN(t)?null:t);return this.day(this.day()%7?a:a-7)}return this.day()||7;var t,s},it.dayOfYear=function(e){var a=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?a:this.add(e-a,"d")},it.hour=it.hours=aa,it.minute=it.minutes=st,it.second=it.seconds=dt,it.millisecond=it.milliseconds=_t,it.utcOffset=function(e,a,t){var s,n=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(null===(e=Fa(de,e)))return this}else Math.abs(e)<16&&!t&&(e*=60);return!this._isUTC&&a&&(s=Ja(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),n!==e&&(!a||this._changeInProgress?Ka(this,Ca(e-n,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,l.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?n:Ja(this)},it.utc=function(e){return this.utcOffset(0,e)},it.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Ja(this),"m")),this},it.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Fa(ne,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},it.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Sa(e).utcOffset():0,(this.utcOffset()-e)%60==0)},it.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},it.isLocal=function(){return!!this.isValid()&&!this._isUTC},it.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},it.isUtc=Na,it.isUTC=Na,it.zoneAbbr=function(){return this._isUTC?"UTC":""},it.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},it.dates=t("dates accessor is deprecated. Use date instead.",tt),it.months=t("months accessor is deprecated. Use month instead",Ee),it.years=t("years accessor is deprecated. Use year instead",ve),it.zone=t("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,a){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,a),this):-this.utcOffset()}),it.isDSTShifted=t("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var e={};if(k(e,this),(e=wa(e))._a){var a=e._isUTC?c(e._a):Sa(e._a);this._isDSTShifted=this.isValid()&&0<r(e._a,a.toArray())}else this._isDSTShifted=!1;return this._isDSTShifted});var mt=j.prototype;function ut(e,a,t,s){var n=oa(),d=c().set(s,a);return n[t](d,e)}function lt(e,a,t){if(m(e)&&(a=e,e=void 0),e=e||"",null!=a)return ut(e,a,t,"month");var s,n=[];for(s=0;s<12;s++)n[s]=ut(e,s,t,"month");return n}function Mt(e,a,t,s){"boolean"==typeof e?m(a)&&(t=a,a=void 0):(a=e,e=!1,m(t=a)&&(t=a,a=void 0)),a=a||"";var n,d=oa(),r=e?d._week.dow:0;if(null!=t)return ut(a,(t+r)%7,s,"day");var _=[];for(n=0;n<7;n++)_[n]=ut(a,(n+r)%7,s,"day");return _}mt.calendar=function(e,a,t){var s=this._calendar[e]||this._calendar.sameElse;return H(s)?s.call(a,t):s},mt.longDateFormat=function(e){var a=this._longDateFormat[e],t=this._longDateFormat[e.toUpperCase()];return a||!t?a:(this._longDateFormat[e]=t.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])},mt.invalidDate=function(){return this._invalidDate},mt.ordinal=function(e){return this._ordinal.replace("%d",e)},mt.preparse=ot,mt.postformat=ot,mt.relativeTime=function(e,a,t,s){var n=this._relativeTime[t];return H(n)?n(e,a,t,s):n.replace(/%d/i,e)},mt.pastFuture=function(e,a){var t=this._relativeTime[0<e?"future":"past"];return H(t)?t(a):t.replace(/%s/i,a)},mt.set=function(e){var a,t;for(t in e)H(a=e[t])?this[t]=a:this["_"+t]=a;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},mt.months=function(e,a){return e?_(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||xe).test(a)?"format":"standalone"][e.month()]:_(this._months)?this._months:this._months.standalone},mt.monthsShort=function(e,a){return e?_(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[xe.test(a)?"format":"standalone"][e.month()]:_(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},mt.monthsParse=function(e,a,t){var s,n,d;if(this._monthsParseExact)return function(e,a,t){var s,n,d,r=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)d=c([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(d,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(d,"").toLocaleLowerCase();return t?"MMM"===a?-1!==(n=we.call(this._shortMonthsParse,r))?n:null:-1!==(n=we.call(this._longMonthsParse,r))?n:null:"MMM"===a?-1!==(n=we.call(this._shortMonthsParse,r))?n:-1!==(n=we.call(this._longMonthsParse,r))?n:null:-1!==(n=we.call(this._longMonthsParse,r))?n:-1!==(n=we.call(this._shortMonthsParse,r))?n:null}.call(this,e,a,t);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(n=c([2e3,s]),t&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(n,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(n,"").replace(".","")+"$","i")),t||this._monthsParse[s]||(d="^"+this.months(n,"")+"|^"+this.monthsShort(n,""),this._monthsParse[s]=new RegExp(d.replace(".",""),"i")),t&&"MMMM"===a&&this._longMonthsParse[s].test(e))return s;if(t&&"MMM"===a&&this._shortMonthsParse[s].test(e))return s;if(!t&&this._monthsParse[s].test(e))return s}},mt.monthsRegex=function(e){return this._monthsParseExact?(h(this,"_monthsRegex")||ze.call(this),e?this._monthsStrictRegex:this._monthsRegex):(h(this,"_monthsRegex")||(this._monthsRegex=Fe),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},mt.monthsShortRegex=function(e){return this._monthsParseExact?(h(this,"_monthsRegex")||ze.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(h(this,"_monthsShortRegex")||(this._monthsShortRegex=Ae),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},mt.week=function(e){return Ie(e,this._week.dow,this._week.doy).week},mt.firstDayOfYear=function(){return this._week.doy},mt.firstDayOfWeek=function(){return this._week.dow},mt.weekdays=function(e,a){return e?_(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(a)?"format":"standalone"][e.day()]:_(this._weekdays)?this._weekdays:this._weekdays.standalone},mt.weekdaysMin=function(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin},mt.weekdaysShort=function(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort},mt.weekdaysParse=function(e,a,t){var s,n,d;if(this._weekdaysParseExact)return function(e,a,t){var s,n,d,r=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)d=c([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(d,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(d,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(d,"").toLocaleLowerCase();return t?"dddd"===a?-1!==(n=we.call(this._weekdaysParse,r))?n:null:"ddd"===a?-1!==(n=we.call(this._shortWeekdaysParse,r))?n:null:-1!==(n=we.call(this._minWeekdaysParse,r))?n:null:"dddd"===a?-1!==(n=we.call(this._weekdaysParse,r))?n:-1!==(n=we.call(this._shortWeekdaysParse,r))?n:-1!==(n=we.call(this._minWeekdaysParse,r))?n:null:"ddd"===a?-1!==(n=we.call(this._shortWeekdaysParse,r))?n:-1!==(n=we.call(this._weekdaysParse,r))?n:-1!==(n=we.call(this._minWeekdaysParse,r))?n:null:-1!==(n=we.call(this._minWeekdaysParse,r))?n:-1!==(n=we.call(this._weekdaysParse,r))?n:-1!==(n=we.call(this._shortWeekdaysParse,r))?n:null}.call(this,e,a,t);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(n=c([2e3,1]).day(s),t&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(n,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(n,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(n,"").replace(".",".?")+"$","i")),this._weekdaysParse[s]||(d="^"+this.weekdays(n,"")+"|^"+this.weekdaysShort(n,"")+"|^"+this.weekdaysMin(n,""),this._weekdaysParse[s]=new RegExp(d.replace(".",""),"i")),t&&"dddd"===a&&this._fullWeekdaysParse[s].test(e))return s;if(t&&"ddd"===a&&this._shortWeekdaysParse[s].test(e))return s;if(t&&"dd"===a&&this._minWeekdaysParse[s].test(e))return s;if(!t&&this._weekdaysParse[s].test(e))return s}},mt.weekdaysRegex=function(e){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(h(this,"_weekdaysRegex")||(this._weekdaysRegex=Ke),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},mt.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(h(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Ze),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},mt.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(h(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=$e),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},mt.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},mt.meridiem=function(e,a,t){return 11<e?t?"pm":"PM":t?"am":"AM"},_a("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var a=e%10;return e+(1===g(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")}}),l.lang=t("moment.lang is deprecated. Use moment.locale instead.",_a),l.langData=t("moment.langData is deprecated. Use moment.localeData instead.",oa);var ht=Math.abs;function Lt(e,a,t,s){var n=Ca(a,t);return e._milliseconds+=s*n._milliseconds,e._days+=s*n._days,e._months+=s*n._months,e._bubble()}function ct(e){return e<0?Math.floor(e):Math.ceil(e)}function Yt(e){return 4800*e/146097}function yt(e){return 146097*e/4800}function ft(e){return function(){return this.as(e)}}var kt=ft("ms"),pt=ft("s"),Dt=ft("m"),Tt=ft("h"),gt=ft("d"),wt=ft("w"),vt=ft("M"),St=ft("y");function Ht(e){return function(){return this.isValid()?this._data[e]:NaN}}var bt=Ht("milliseconds"),jt=Ht("seconds"),xt=Ht("minutes"),Pt=Ht("hours"),Ot=Ht("days"),Wt=Ht("months"),Et=Ht("years");var At=Math.round,Ft={ss:44,s:45,m:45,h:22,d:26,M:11};var zt=Math.abs;function Jt(e){return(0<e)-(e<0)||+e}function Nt(){if(!this.isValid())return this.localeData().invalidDate();var e,a,t=zt(this._milliseconds)/1e3,s=zt(this._days),n=zt(this._months);a=T((e=T(t/60))/60),t%=60,e%=60;var d=T(n/12),r=n%=12,_=s,i=a,o=e,m=t?t.toFixed(3).replace(/\.?0+$/,""):"",u=this.asSeconds();if(!u)return"P0D";var l=u<0?"-":"",M=Jt(this._months)!==Jt(u)?"-":"",h=Jt(this._days)!==Jt(u)?"-":"",L=Jt(this._milliseconds)!==Jt(u)?"-":"";return l+"P"+(d?M+d+"Y":"")+(r?M+r+"M":"")+(_?h+_+"D":"")+(i||o||m?"T":"")+(i?L+i+"H":"")+(o?L+o+"M":"")+(m?L+m+"S":"")}var Rt=Pa.prototype;Rt.isValid=function(){return this._isValid},Rt.abs=function(){var e=this._data;return this._milliseconds=ht(this._milliseconds),this._days=ht(this._days),this._months=ht(this._months),e.milliseconds=ht(e.milliseconds),e.seconds=ht(e.seconds),e.minutes=ht(e.minutes),e.hours=ht(e.hours),e.months=ht(e.months),e.years=ht(e.years),this},Rt.add=function(e,a){return Lt(this,e,a,1)},Rt.subtract=function(e,a){return Lt(this,e,a,-1)},Rt.as=function(e){if(!this.isValid())return NaN;var a,t,s=this._milliseconds;if("month"===(e=O(e))||"year"===e)return a=this._days+s/864e5,t=this._months+Yt(a),"month"===e?t:t/12;switch(a=this._days+Math.round(yt(this._months)),e){case"week":return a/7+s/6048e5;case"day":return a+s/864e5;case"hour":return 24*a+s/36e5;case"minute":return 1440*a+s/6e4;case"second":return 86400*a+s/1e3;case"millisecond":return Math.floor(864e5*a)+s;default:throw new Error("Unknown unit "+e)}},Rt.asMilliseconds=kt,Rt.asSeconds=pt,Rt.asMinutes=Dt,Rt.asHours=Tt,Rt.asDays=gt,Rt.asWeeks=wt,Rt.asMonths=vt,Rt.asYears=St,Rt.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*g(this._months/12):NaN},Rt._bubble=function(){var e,a,t,s,n,d=this._milliseconds,r=this._days,_=this._months,i=this._data;
vendor: 4,355 bytes, line 51149
51149return 0<=d&&0<=r&&0<=_||d<=0&&r<=0&&_<=0||(d+=864e5*ct(yt(_)+r),_=r=0),i.milliseconds=d%1e3,e=T(d/1e3),i.seconds=e%60,a=T(e/60),i.minutes=a%60,t=T(a/60),i.hours=t%24,_+=n=T(Yt(r+=T(t/24))),r-=ct(yt(n)),s=T(_/12),_%=12,i.days=r,i.months=_,i.years=s,this},Rt.clone=function(){return Ca(this)},Rt.get=function(e){return e=O(e),this.isValid()?this[e+"s"]():NaN},Rt.milliseconds=bt,Rt.seconds=jt,Rt.minutes=xt,Rt.hours=Pt,Rt.days=Ot,Rt.weeks=function(){return T(this.days()/7)},Rt.months=Wt,Rt.years=Et,Rt.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var a,t,s,n,d,r,_,i,o,m,u,l=this.localeData(),M=(t=!e,s=l,n=Ca(a=this).abs(),d=At(n.as("s")),r=At(n.as("m")),_=At(n.as("h")),i=At(n.as("d")),o=At(n.as("M")),m=At(n.as("y")),(u=d<=Ft.ss&&["s",d]||d<Ft.s&&["ss",d]||r<=1&&["m"]||r<Ft.m&&["mm",r]||_<=1&&["h"]||_<Ft.h&&["hh",_]||i<=1&&["d"]||i<Ft.d&&["dd",i]||o<=1&&["M"]||o<Ft.M&&["MM",o]||m<=1&&["y"]||["yy",m])[2]=t,u[3]=0<+a,u[4]=s,function(e,a,t,s,n){return n.relativeTime(a||1,!!t,e,s)}.apply(null,u));return e&&(M=l.pastFuture(+this,M)),l.postformat(M)},Rt.toISOString=Nt,Rt.toString=Nt,Rt.toJSON=Nt,Rt.locale=qa,Rt.localeData=Xa,Rt.toIsoString=t("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Nt),Rt.lang=Qa,I("X",0,0,"unix"),I("x",0,0,"valueOf"),ie("x",se),ie("X",/[+-]?\d+(\.\d{1,3})?/),le("X",function(e,a,t){t._d=new Date(1e3*parseFloat(e,10))}),le("x",function(e,a,t){t._d=new Date(g(e))}),l.version="2.22.1",e=Sa,l.fn=it,l.min=function(){return ja("isBefore",[].slice.call(arguments,0))},l.max=function(){return ja("isAfter",[].slice.call(arguments,0))},l.now=function(){return Date.now?Date.now():+new Date},l.utc=c,l.unix=function(e){return Sa(1e3*e)},l.months=function(e,a){return lt(e,a,"months")},l.isDate=u,l.locale=_a,l.invalid=f,l.duration=Ca,l.isMoment=D,l.weekdays=function(e,a,t){return Mt(e,a,t,"weekdays")},l.parseZone=function(){return Sa.apply(null,arguments).parseZone()},l.localeData=oa,l.isDuration=Oa,l.monthsShort=function(e,a){return lt(e,a,"monthsShort")},l.weekdaysMin=function(e,a,t){return Mt(e,a,t,"weekdaysMin")},l.defineLocale=ia,l.updateLocale=function(e,a){if(null!=a){var t,s,n=ta;null!=(s=ra(e))&&(n=s._config),(t=new j(a=b(n,a))).parentLocale=sa[e],sa[e]=t,_a(e)}else null!=sa[e]&&(null!=sa[e].parentLocale?sa[e]=sa[e].parentLocale:null!=sa[e]&&delete sa[e]);return sa[e]},l.locales=function(){return s(sa)},l.weekdaysShort=function(e,a,t){return Mt(e,a,t,"weekdaysShort")},l.normalizeUnits=O,l.relativeTimeRounding=function(e){return void 0===e?At:"function"==typeof e&&(At=e,!0)},l.relativeTimeThreshold=function(e,a){return void 0!==Ft[e]&&(void 0===a?Ft[e]:(Ft[e]=a,"s"===e&&(Ft.ss=a-1),!0))},l.calendarFormat=function(e,a){var t=e.diff(a,"days",!0);return t<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"},l.prototype=it,l.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},l.defineLocale("af",{months:"Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"),weekdays:"Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"),weekdaysShort:"Son_Maa_Din_Woe_Don_Vry_Sat".split("_"),weekdaysMin:"So_Ma_Di_Wo_Do_Vr_Sa".split("_"),meridiemParse:/vm|nm/i,isPM:function(e){return/^nm$/i.test(e)},meridiem:function(e,a,t){return e<12?t?"vm":"VM":t?"nm":"NM"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Vandag om] LT",nextDay:"[M\xf4re om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gister om] LT",lastWeek:"[Laas] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oor %s",past:"%s gelede",s:"'n paar sekondes",ss:"%d sekondes",m:"'n minuut",mm:"%d minute",h:"'n uur",hh:"%d ure",d:"'n dag",dd:"%d dae",M:"'n maand",MM:"%d maande",y:"'n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||20<=e?"ste":"de")},week:{dow:1,doy:4}}),l.defineLocale("ar-dz",{months:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u064
511491\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u0623\u062d_\u0625\u062b_\u062b\u0644\u0627_\u0623\u0631_\u062e\u0645_\u062c\u0645_\u0633\u0628".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:0,doy:4}}),l.defineLocale("ar-kw",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062a\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062a\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:0,doy:12}});var It={1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},Ct=function(e){return 0===e?0:1===e?1:2===e?2:3<=e%100&&e%100<=10?3:11<=e%100?4:5},Gt={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},Ut=function(r){return function(e,a,t,s){var n=Ct(e),d=Gt[r][Ct(e)];return 2===n&&(d=d[a?0:1]),d.replace(/%d/i,e)}},Vt=["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0648","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];l.defineLocale("ar-ly",{months:Vt,monthsShort:Vt,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(e){return"\u0645"===e},meridiem:function(e,a,t){return e<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:Ut("s"),ss:Ut("s"),m:Ut("m"),mm:Ut("m"),h:Ut("h"),hh:Ut("h"),d:Ut("d"),dd:Ut("d"),M:Ut("M"),MM:Ut("M"),y:Ut("y"),yy:Ut("y")},preparse:function(e){return e.replace(/\u060c/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return It[e]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}}),l.defineLocale("ar-ma",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062a\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062a\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:6,doy:12}});var Kt={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},Zt={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"};l.defineLocale("ar-sa",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a\u0648_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648_\u0623\u063a\u0633\u0637\u0633_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a\u0648_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648_\u0623\u063a\u0633\u0637\u0633_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(e){return"\u0645"===e},meridiem:function(e,a,t){return e<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},preparse:function(e){return e.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(e){return Zt[e]}).replace(/\u060c/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return Kt[e]}).replace(/,/g,"\u060c")},week:{dow:0,doy:6}}),l.defineLocale("ar-tn",{months:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u064
511491\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:1,doy:4}});var $t={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},Bt={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"},qt=function(e){return 0===e?0:1===e?1:2===e?2:3<=e%100&&e%100<=10?3:11<=e%100?4:5},Qt={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},Xt=function(r){return function(e,a,t,s){var n=qt(e),d=Qt[r][qt(e)];return 2===n&&(d=d[a?0:1]),d.replace(/%d/i,e)}},es=["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0648","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];l.defineLocale("ar",{months:es,monthsShort:es,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(e){return"\u0645"===e},meridiem:function(e,a,t){return e<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:Xt("s"),ss:Xt("s"),m:Xt("m"),mm:Xt("m"),h:Xt("h"),hh:Xt("h"),d:Xt("d"),dd:Xt("d"),M:Xt("M"),MM:Xt("M"),y:Xt("y"),yy:Xt("y")},preparse:function(e){return e.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(e){return Bt[e]}).replace(/\u060c/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return $t[e]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}});var as={1:"-inci",5:"-inci",8:"-inci",70:"-inci",80:"-inci",2:"-nci",7:"-nci",20:"-nci",50:"-nci",3:"-\xfcnc\xfc",4:"-\xfcnc\xfc",100:"-\xfcnc\xfc",6:"-nc\u0131",9:"-uncu",10:"-uncu",30:"-uncu",60:"-\u0131nc\u0131",90:"-\u0131nc\u0131"};function ts(e,a,t){var s,n;return"m"===t?a?"\u0445\u0432\u0456\u043b\u0456\u043d\u0430":"\u0445\u0432\u0456\u043b\u0456\u043d\u0443":"h"===t?a?"\u0433\u0430\u0434\u0437\u0456\u043d\u0430":"\u0433\u0430\u0434\u0437\u0456\u043d\u0443":e+" "+(s=+e,n={ss:a?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434",mm:a?"\u0445\u0432\u0456\u043b\u0456\u043d\u0430_\u0445\u0432\u0456\u043b\u0456\u043d\u044b_\u0445\u0432\u0456\u043b\u0456\u043d":"\u0445\u0432\u0456\u043b\u0456\u043d\u0443_\u0445\u0432\u0456\u043b\u0456\u043d\u044b_\u0445\u0432\u0456\u043b\u0456\u043d",hh:a?"\u0433\u0430\u0434\u0437\u0456\u043d\u0430_\u0433\u0430\u0434\u0437\u0456\u043d\u044b_\u0433\u0430\u0434\u0437\u0456\u043d":"\u0433\u0430\u0434\u0437\u0456\u043d\u0443_\u0433\u0430\u0434\u0437\u0456\u043d\u044b_\u0433\u0430\u0434\u0437\u0456\u043d",dd:"\u0434\u0437\u0435\u043d\u044c_\u0434\u043d\u0456_\u0434\u0437\u0451\u043d",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u044b_\u043c\u0435\u0441\u044f\u0446\u0430\u045e",yy:"\u0433\u043e\u0434_\u0433\u0430\u0434\u044b_\u0433\u0430\u0434\u043e\u045e"}[t].split("_"),s%10==1&&s%100!=11?n[0]:2<=s%10&&s%10<=4&&(s%100<10||20<=s%100)?n[1]:n[2])}l.defineLocale("az",{months:"yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),monthsShort:"yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),weekdays:"Bazar_Bazar ert\u0259si_\xc7\u0259r\u015f\u
511490259nb\u0259 ax\u015fam\u0131_\xc7\u0259r\u015f\u0259nb\u0259_C\xfcm\u0259 ax\u015fam\u0131_C\xfcm\u0259_\u015e\u0259nb\u0259".split("_"),weekdaysShort:"Baz_BzE_\xc7Ax_\xc7\u0259r_CAx_C\xfcm_\u015e\u0259n".split("_"),weekdaysMin:"Bz_BE_\xc7A_\xc7\u0259_CA_C\xfc_\u015e\u0259".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bug\xfcn saat] LT",nextDay:"[sabah saat] LT",nextWeek:"[g\u0259l\u0259n h\u0259ft\u0259] dddd [saat] LT",lastDay:"[d\xfcn\u0259n] LT",lastWeek:"[ke\xe7\u0259n h\u0259ft\u0259] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s \u0259vv\u0259l",s:"birne\xe7\u0259 saniyy\u0259",ss:"%d saniy\u0259",m:"bir d\u0259qiq\u0259",mm:"%d d\u0259qiq\u0259",h:"bir saat",hh:"%d saat",d:"bir g\xfcn",dd:"%d g\xfcn",M:"bir ay",MM:"%d ay",y:"bir il",yy:"%d il"},meridiemParse:/gec\u0259|s\u0259h\u0259r|g\xfcnd\xfcz|ax\u015fam/,isPM:function(e){return/^(g\xfcnd\xfcz|ax\u015fam)$/.test(e)},meridiem:function(e,a,t){return e<4?"gec\u0259":e<12?"s\u0259h\u0259r":e<17?"g\xfcnd\xfcz":"ax\u015fam"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0131nc\u0131|inci|nci|\xfcnc\xfc|nc\u0131|uncu)/,ordinal:function(e){if(0===e)return e+"-\u0131nc\u0131";var a=e%10;return e+(as[a]||as[e%100-a]||as[100<=e?100:null])},week:{dow:1,doy:7}}),l.defineLocale("be",{months:{format:"\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044f_\u043b\u044e\u0442\u0430\u0433\u0430_\u0441\u0430\u043a\u0430\u0432\u0456\u043a\u0430_\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a\u0430_\u0442\u0440\u0430\u045e\u043d\u044f_\u0447\u044d\u0440\u0432\u0435\u043d\u044f_\u043b\u0456\u043f\u0435\u043d\u044f_\u0436\u043d\u0456\u045e\u043d\u044f_\u0432\u0435\u0440\u0430\u0441\u043d\u044f_\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a\u0430_\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434\u0430_\u0441\u043d\u0435\u0436\u043d\u044f".split("_"),standalone:"\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044c_\u043b\u044e\u0442\u044b_\u0441\u0430\u043a\u0430\u0432\u0456\u043a_\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a_\u0442\u0440\u0430\u0432\u0435\u043d\u044c_\u0447\u044d\u0440\u0432\u0435\u043d\u044c_\u043b\u0456\u043f\u0435\u043d\u044c_\u0436\u043d\u0456\u0432\u0435\u043d\u044c_\u0432\u0435\u0440\u0430\u0441\u0435\u043d\u044c_\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a_\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434_\u0441\u043d\u0435\u0436\u0430\u043d\u044c".split("_")},monthsShort:"\u0441\u0442\u0443\u0434_\u043b\u044e\u0442_\u0441\u0430\u043a_\u043a\u0440\u0430\u0441_\u0442\u0440\u0430\u0432_\u0447\u044d\u0440\u0432_\u043b\u0456\u043f_\u0436\u043d\u0456\u0432_\u0432\u0435\u0440_\u043a\u0430\u0441\u0442_\u043b\u0456\u0441\u0442_\u0441\u043d\u0435\u0436".
vendor: 7,189 bytes, line 51149
51149split("_"),weekdays:{format:"\u043d\u044f\u0434\u0437\u0435\u043b\u044e_\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a_\u0430\u045e\u0442\u043e\u0440\u0430\u043a_\u0441\u0435\u0440\u0430\u0434\u0443_\u0447\u0430\u0446\u0432\u0435\u0440_\u043f\u044f\u0442\u043d\u0456\u0446\u0443_\u0441\u0443\u0431\u043e\u0442\u0443".split("_"),standalone:"\u043d\u044f\u0434\u0437\u0435\u043b\u044f_\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a_\u0430\u045e\u0442\u043e\u0440\u0430\u043a_\u0441\u0435\u0440\u0430\u0434\u0430_\u0447\u0430\u0446\u0432\u0435\u0440_\u043f\u044f\u0442\u043d\u0456\u0446\u0430_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),isFormat:/\[ ?[\u0412\u0432] ?(?:\u043c\u0456\u043d\u0443\u043b\u0443\u044e|\u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0443\u044e)? ?\] ?dddd/},weekdaysShort:"\u043d\u0434_\u043f\u043d_\u0430\u0442_\u0441\u0440_\u0447\u0446_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0430\u0442_\u0441\u0440_\u0447\u0446_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0433.",LLL:"D MMMM YYYY \u0433., HH:mm",LLLL:"dddd, D MMMM YYYY \u0433., HH:mm"},calendar:{sameDay:"[\u0421\u0451\u043d\u043d\u044f \u045e] LT",nextDay:"[\u0417\u0430\u045e\u0442\u0440\u0430 \u045e] LT",lastDay:"[\u0423\u0447\u043e\u0440\u0430 \u045e] LT",nextWeek:function(){return"[\u0423] dddd [\u045e] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[\u0423 \u043c\u0456\u043d\u0443\u043b\u0443\u044e] dddd [\u045e] LT";case 1:case 2:case 4:return"[\u0423 \u043c\u0456\u043d\u0443\u043b\u044b] dddd [\u045e] LT"}},sameElse:"L"},relativeTime:{future:"\u043f\u0440\u0430\u0437 %s",past:"%s \u0442\u0430\u043c\u0443",s:"\u043d\u0435\u043a\u0430\u043b\u044c\u043a\u0456 \u0441\u0435\u043a\u0443\u043d\u0434",m:ts,mm:ts,h:ts,hh:ts,d:"\u0434\u0437\u0435\u043d\u044c",dd:ts,M:"\u043c\u0435\u0441\u044f\u0446",MM:ts,y:"\u0433\u043e\u0434",yy:ts},meridiemParse:/\u043d\u043e\u0447\u044b|\u0440\u0430\u043d\u0456\u0446\u044b|\u0434\u043d\u044f|\u0432\u0435\u0447\u0430\u0440\u0430/,isPM:function(e){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u0430\u0440\u0430)$/.test(e)},meridiem:function(e,a,t){return e<4?"\u043d\u043e\u0447\u044b":e<12?"\u0440\u0430\u043d\u0456\u0446\u044b":e<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u0430\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0456|\u044b|\u0433\u0430)/,ordinal:function(e,a){switch(a){case"M":case"d":case"DDD":case"w":case"W":return e%10!=2&&e%10!=3||e%100==12||e%100==13?e+"-\u044b":e+"-\u0456";case"D":return e+"-\u0433\u0430";default:return e}},week:{dow:1,doy:7}}),l.defineLocale("bg",{months:"\u044f\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u044f\u043d\u0440_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u044f\u0434\u0430_\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a_\u043f\u0435\u0442\u044a\u043a_\u0441\u044a\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u044f_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u044a\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[\u0414\u043d\u0435\u0441 \u0432] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432] LT",nextWeek:"dddd [\u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0430\u0442\u0430] dddd [\u0432] LT";case 1:case 2:case 4:case 5:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0438\u044f] dddd [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0441\u043b\u0435\u0434 %s",past:"\u043f\u0440\u0435\u0434\u0438 %s",s:"\u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u043d\u0438",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0430",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0435\u0432|\u0435\u043d|\u0442\u0438|\u0432\u0438|\u0440\u0438|\u043c\u0438)/,ordinal:function(e){var a=e%10,t=e%100;return 0===e?e+"-\u0435\u0432":0===t?e+"-\u0435\u043d":10<t&&t<20?e+"-\u0442\u0438":1===a?e+"-\u0432\u0438":2===a?e+"-\u0440\u0438":7===a||8===a?e+"-\u043c\u0438":e+"-\u0442\u0438"},week:{dow:1,doy:7}}),l.defineLocale("bm",{months:"Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_M\u025bkalo_Zuw\u025bnkalo_Zuluyekalo_Utikalo_S\u025btanburukalo_\u0254kut\u0254burukalo_Nowanburukalo_Desanburukalo".split("_"),monthsShort:"Zan_Few_Mar_Awi_M\u025b_Zuw_Zul_Uti_S\u025bt_\u0254ku_Now_Des".split("_"),weekdays:"Kari_Nt\u025bn\u025bn_Tarata_Araba_Alamisa_Juma_Sibiri".split("_"),weekdaysShort:"Kar_Nt\u025b_Tar_Ara_Ala_Jum_Sib".split("_"),weekdaysMin:"Ka_Nt_Ta_Ar_Al_Ju_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"MMMM [tile] D [san] YYYY",LLL:"MMMM [tile] D [san] YYYY [l\u025br\u025b] HH:mm",LLLL:"dddd MMMM [tile] D [san] YYYY [l\u025br\u025b] HH:mm"},calendar:{sameDay:"[Bi l\u025br\u025b] LT",nextDay:"[Sini l\u025br\u025b] LT",nextWeek:"dddd [don l\u025br\u025b] LT",lastDay:"[Kunu l\u025br\u025b] LT",lastWeek:"dddd [t\u025bm\u025bnen l\u025br\u025b] LT",sameElse:"L"},relativeTime:{future:"%s k\u0254n\u0254",past:"a b\u025b %s b\u0254",s:"sanga dama dama",ss:"sekondi %d",m:"miniti kelen",mm:"miniti %d",h:"l\u025br\u025b kelen",hh:"l\u025br\u025b %d",d:"tile kelen",dd:"tile %d",M:"kalo kelen",MM:"kalo %d",y:"san kelen",yy:"san %d"},week:{dow:1,doy:4}});var ss={1:"\u09e7",2:"\u09e8",3:"\u09e9",4:"\u09ea",5:"\u09eb",6:"\u09ec",7:"\u09ed",8:"\u09ee",9:"\u09ef",0:"\u09e6"},ns={"\u09e7":"1","\u09e8":"2","\u09e9":"3","\u09ea":"4","\u09eb":"5","\u09ec":"6","\u09ed":"7","\u09ee":"8","\u09ef":"9","\u09e6":"0"};l.defineLocale("bn",{months:"\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09c0_\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09bf_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0\u09bf\u09b2_\u
5114909ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2\u09be\u0987_\u0986\u0997\u09b8\u09cd\u099f_\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0_\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0_\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0_\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0".split("_"),monthsShort:"\u099c\u09be\u09a8\u09c1_\u09ab\u09c7\u09ac_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2_\u0986\u0997_\u09b8\u09c7\u09aa\u09cd\u099f_\u0985\u0995\u09cd\u099f\u09cb_\u09a8\u09ad\u09c7_\u09a1\u09bf\u09b8\u09c7".split("_"),weekdays:"\u09b0\u09ac\u09bf\u09ac\u09be\u09b0_\u09b8\u09cb\u09ae\u09ac\u09be\u09b0_\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0_\u09ac\u09c1\u09a7\u09ac\u09be\u09b0_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0_\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0_\u09b6\u09a8\u09bf\u09ac\u09be\u09b0".split("_"),weekdaysShort:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997\u09b2_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),weekdaysMin:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9\u0983_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),longDateFormat:{LT:"A h:mm \u09b8\u09ae\u09df",LTS:"A h:mm:ss \u09b8\u09ae\u09df",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u09b8\u09ae\u09df",LLLL:"dddd, D MMMM YYYY, A h:mm \u09b8\u09ae\u09df"},calendar:{sameDay:"[\u0986\u099c] LT",nextDay:"[\u0986\u0997\u09be\u09ae\u09c0\u0995\u09be\u09b2] LT",nextWeek:"dddd, LT",lastDay:"[\u0997\u09a4\u0995\u09be\u09b2] LT",lastWeek:"[\u0997\u09a4] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u09aa\u09b0\u09c7",past:"%s \u0986\u0997\u09c7",s:"\u0995\u09df\u09c7\u0995 \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",ss:"%d \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",m:"\u098f\u0995 \u09ae\u09bf\u09a8\u09bf\u099f",mm:"%d \u09ae\u09bf\u09a8\u09bf\u099f",h:"\u098f\u0995 \u0998\u09a8\u09cd\u099f\u09be",hh:"%d \u0998\u09a8\u09cd\u099f\u09be",d:"\u098f\u0995 \u09a6\u09bf\u09a8",dd:"%d \u09a6\u09bf\u09a8",M:"\u098f\u0995 \u09ae\u09be\u09b8",MM:"%d \u09ae\u09be\u09b8",y:"\u098f\u0995 \u09ac\u099b\u09b0",yy:"%d \u09ac\u099b\u09b0"},preparse:function(e){return e.replace(/[\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09e6]/g,function(e){return ns[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return ss[e]})},meridiemParse:/\u09b0\u09be\u09a4|\u09b8\u0995\u09be\u09b2|\u09a6\u09c1\u09aa\u09c1\u09b0|\u09ac\u09bf\u0995\u09be\u09b2|\u09b0\u09be\u09a4/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u09b0\u09be\u09a4"===a&&4<=e||"\u09a6\u09c1\u09aa\u09c1\u09b0"===a&&e<5||"\u09ac\u09bf\u0995\u09be\u09b2"===a?e+12:e},meridiem:function(e,a,t){return e<4?"\u09b0\u09be\u09a4":e<10?"\u09b8\u0995\u09be\u09b2":e<17?"\u09a6\u09c1\u09aa\u09c1\u09b0":e<20?"\u09ac\u09bf\u0995\u09be\u09b2":"\u09b0\u09be\u09a4"},week:{dow:0,doy:6}});var ds={1:"\u0f21",2:"\u0f22",3:"\u0f23",4:"\u0f24",5:"\u0f25",6:"\u0f26",7:"\u0f27",8:"\u0f28",9:"\u0f29",0:"\u0f20"},rs={"\u0f21":"1","\u0f22":"2","\u0f23":"3","\u0f24":"4","\u0f25":"5","\u0f26":"6","\u0f27":"7","\u0f28":"8","\u0f29":"9","\u0f20":"0"};function _s(e,a,t){return e+" "+function(e,a){if(2===a)return function(e){var a={m:"v",b:"v",d:"z"};if(void 0===a[e.charAt(0)])return e;return a[e.charAt(0)]+e.substring(1)}(e);return e}({mm:"munutenn",MM:"miz",dd:"devezh"}[t],e)}function is(e,a,t){var s=e+" ";switch(t){case"ss":return s+=1===e?"sekunda":2===e||3===e||4===e?"sekunde":"sekundi";case"m":return a?"jedna minuta":"jedne minute";case"mm":return s+=1===e?"minuta":2===e||3===e||4===e?"minute":"minuta";case"h":return a?"jedan sat":"jednog sata";case"hh":return s+=1===e?"sat":2===e||3===e||4===e?"sata":"sati";case"dd":return s+=1===e?"dan":"dana";case"MM":return s+=1===e?"mjesec":2===e||3===e||4===e?"mjeseca":"mjeseci";case"yy":return s+=1===e?"godina":2===e||3===e||4===e?"godine":"godina"}}l.defineLocale("bo",{months:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f44\u0f0b\u0f54\u0f7c_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f66\u0f74\u0f58\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f5e\u0f72\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f63\u0f94\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0fb2\u0f74\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f42\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f45\u0f72\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54".split("_"),monthsShort:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f44\u0f0b\u0f54\u0f7c_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f66\u0f74\u0f58\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f5e\u0f72\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f63\u0f94\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0fb2\u0f74\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f42\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f45\u0f72\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54".split("_"),weekdays:"\u0f42\u0f5f\u0f60\u0f0b\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f42\u0f5f\u0f60\u0f0b\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),weekdaysShort:"\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),weekdaysMin:"\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0f51\u0f72\u0f0b\u0f62\u0f72\u0f44] LT",nextDay:"[\u0f66\u0f44\u0f0b\u0f49\u0f72\u0f53] LT",nextWeek:"[\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f55\u0fb2\u0f42\u0f0b\u0f62\u0f97\u0f7a\u0f66\u0f0b\u0f58], LT",lastDay:"[\u0f41\u0f0b\u0f66\u0f44] LT",lastWeek:"[\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f55\u0fb2\u0f42\u0f0b\u0f58\u0f50\u0f60\u0f0b\u0f58] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0f63\u0f0b",past:"%s \u0f66\u0f94\u0f53\u0f0b\u0f63",s:"\u0f63\u0f58\u0f0b\u0f66\u0f44",ss:"%d \u0f66\u0f90\u0f
5114962\u0f0b\u0f46\u0f0d",m:"\u0f66\u0f90\u0f62\u0f0b\u0f58\u0f0b\u0f42\u0f45\u0f72\u0f42",mm:"%d \u0f66\u0f90\u0f62\u0f0b\u0f58",h:"\u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51\u0f0b\u0f42\u0f45\u0f72\u0f42",hh:"%d \u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51",d:"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f45\u0f72\u0f42",dd:"%d \u0f49\u0f72\u0f53\u0f0b",M:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f45\u0f72\u0f42",MM:"%d \u0f5f\u0fb3\u0f0b\u0f56",y:"\u0f63\u0f7c\u0f0b\u0f42\u0f45\u0f72\u0f42",yy:"%d \u0f63\u0f7c"},preparse:function(e){return e.replace(/[\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u0f20]/g,function(e){return rs[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return ds[e]})},meridiemParse:/\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c|\u0f5e\u0f7c\u0f42\u0f66\u0f0b\u0f40\u0f66|\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44|\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42|\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c"===a&&4<=e||"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44"===a&&e<5||"\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42"===a?e+12:e},meridiem:function(e,a,t){return e<4?"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c":e<10?"\u0f5e\u0f7c\u0f42\u0f66\u0f0b\u0f40\u0f66":e<17?"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44":e<20?"\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42":"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c"},week:{dow:0,doy:6}}),l.defineLocale("br",{months:"Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h[e]mm A",LTS:"h[e]mm:ss A",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY h[e]mm A",LLLL:"dddd, D [a viz] MMMM YYYY h[e]mm A"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warc'hoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Dec'h da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s 'zo",s:"un nebeud segondenno\xf9",ss:"%d eilenn",m:"ur vunutenn",mm:_s,h:"un eur",hh:"%d eur",d:"un devezh",dd:_s,M:"ur miz",MM:_s,y:"ur bloaz",yy:function(e){switch(function e(a){return 9<a?e(a%10):a}(e)){case 1:case 3:case 4:case 5:case 9:return e+" bloaz";default:return e+" vloaz"}}},dayOfMonthOrdinalParse:/\d{1,2}(a\xf1|vet)/,ordinal:function(e){return e+(1===e?"a\xf1":"vet")},week:{dow:1,doy:4}}),l.defineLocale("bs",{months:"januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010der u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[pro\u0161lu] dddd [u] LT";case 6:return"[pro\u0161le] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[pro\u0161li] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:is,m:is,mm:is,h:is,hh:is,d:"dan",dd:is,M:"mjesec",MM:is,y:"godinu",yy:is},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}}),l.defineLocale("ca",{months:{standalone:"gener_febrer_mar\xe7_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),format:"de gener_de febrer_de mar\xe7_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._mar\xe7_abr._maig_juny_jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dt_dc_dj_dv_ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a les] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a les] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[dem\xe0 a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"d'aqu\xed %s",past:"fa %s",s:"uns segons",ss:"%d segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%
51149d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|\xe8|a)/,ordinal:function(e,a){var t=1===e?"r":2===e?"n":3===e?"r":4===e?"t":"\xe8";return"w"!==a&&"W"!==a||(t="a"),e+t},week:{dow:1,doy:4}});var os="leden_\xfanor_b\u0159ezen_duben_kv\u011bten_\u010derven_\u010dervenec_srpen_z\xe1\u0159\xed_\u0159\xedjen_listopad_prosinec".split("_"),ms="led_\xfano_b\u0159e_dub_kv\u011b_\u010dvn_\u010dvc_srp_z\xe1\u0159_\u0159\xedj_lis_pro".split("_");function us(e){return 1<e&&e<5&&1!=~~(e/10)}function ls(e,a,t,s){var n=e+" ";switch(t){case"s":return a||s?"p\xe1r sekund":"p\xe1r sekundami";case"ss":return a||s?n+(us(e)?"sekundy":"sekund"):n+"sekundami";break;case"m":return a?"minuta":s?"minutu":"minutou";case"mm":return a||s?n+(us(e)?"minuty":"minut"):n+"minutami";break;case"h":return a?"hodina":s?"hodinu":"hodinou";case"hh":return a||s?n+(us(e)?"hodiny":"hodin"):n+"hodinami";break;case"d":return a||s?"den":"dnem";case"dd":return a||s?n+(us(e)?"dny":"dn\xed"):n+"dny";break;case"M":return a||s?"m\u011bs\xedc":"m\u011bs\xedcem";case"MM":return a||s?n+(us(e)?"m\u011bs\xedce":"m\u011bs\xedc\u016f"):n+"m\u011bs\xedci";break;case"y":return a||s?"rok":"rokem";case"yy":return a||s?n+(us(e)?"roky":"let"):n+"lety";break}}function Ms(e,a,t,s){var n={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return a?n[t][0]:n[t][1]}function hs(e,a,t,s){var n={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return a?n[t][0]:n[t][1]}function Ls(e,a,t,s){var n={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return a?n[t][0]:n[t][1]}l.defineLocale("cs",{months:os,monthsShort:ms,monthsParse:function(e,a){var t,s=[];for(t=0;t<12;t++)s[t]=new RegExp("^"+e[t]+"$|^"+a[t]+"$","i");return s}(os,ms),shortMonthsParse:function(e){var a,t=[];for(a=0;a<12;a++)t[a]=new RegExp("^"+e[a]+"$","i");return t}(ms),longMonthsParse:function(e){var a,t=[];for(a=0;a<12;a++)t[a]=new RegExp("^"+e[a]+"$","i");return t}(os),weekdays:"ned\u011ble_pond\u011bl\xed_\xfater\xfd_st\u0159eda_\u010dtvrtek_p\xe1tek_sobota".split("_"),weekdaysShort:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),weekdaysMin:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[z\xedtra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v ned\u011bli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve st\u0159edu v] LT";case 4:return"[ve \u010dtvrtek v] LT";case 5:return"[v p\xe1tek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[v\u010dera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou ned\u011bli v] LT";case 1:case 2:return"[minul\xe9] dddd [v] LT";case 3:return"[minulou st\u0159edu v] LT";case 4:case 5:return"[minul\xfd] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"p\u0159ed %s",s:ls,ss:ls,m:ls,mm:ls,h:ls,hh:ls,d:ls,dd:ls,M:ls,MM:ls,y:ls,yy:ls},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("cv",{months:"\u043a\u04d1\u0440\u043b\u0430\u0447_\u043d\u0430\u0440\u04d1\u0441_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u04ab\u04d7\u0440\u0442\u043c\u0435_\u0443\u0442\u04d1_\u04ab\u0443\u0440\u043b\u0430_\u0430\u0432\u04d1\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448\u0442\u0430\u0432".split("_"),monthsShort:"\u043a\u04d1\u0440_\u043d\u0430\u0440_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u04ab\u04d7\u0440_\u0443\u0442\u04d1_\u04ab\u0443\u0440_\u0430\u0432\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448".split("_"),weekdays:"\u0432\u044b\u0440\u0441\u0430\u0440\u043d\u0438\u043a\u0443\u043d_\u0442\u0443\u043d\u0442\u0438\u043a\u0443\u043d_\u044b\u0442\u043b\u0430\u0440\u0438\u043a\u0443\u043d_\u044e\u043d\u043a\u0443\u043d_\u043a\u04d7\u04ab\u043d\u0435\u0440\u043d\u0438\u043a\u0443\u043d_\u044d\u0440\u043d\u0435\u043a\u0443\u043d_\u0448\u04d1\u043c\u0430\u0442\u043a\u0443\u043d".split("_"),weekdaysShort:"\u0432\u044b\u0440_\u0442\u0443\u043d_\u044b\u0442\u043b_\u044e\u043d_\u043a\u04d7\u04ab_\u044d\u0440\u043d_\u0448\u04d1\u043c".split("_"),weekdaysMin:"\u0432\u0440_\u0442\u043d_\u044b\u0442_\u044e\u043d_\u043a\u04ab_\u044d\u0440_\u0448\u043c".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7]",LLL:"YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7], HH:mm",LLLL:"dddd, YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7], HH:mm"},calendar:{sameDay:"[\u041f\u0430\u044f\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextDay:"[\u042b\u0440\u0430\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastDay:"[\u04d6\u043d\u0435\u0440] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextWeek:"[\u04aa\u0438\u0442\u0435\u0441] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastWeek:"[\u0418\u0440\u0442\u043d\u04d7] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",sameElse:"L"},relativeTime:{future:function(e){return e+(/\u0441\u0435\u0445\u0435\u0442$/i.exec(e)?"\u0440\u0435\u043d":/\u04ab\u0443\u043b$/i.exec(e)?"\u0442\u0430\u043d":"\u0440\u0430\u043d")},past:"%s \u043a\u0430\u044f\u043b\u043b\u0430",s:"\u043f\u04d7\u0440-\u0438\u043a \u04ab\u0435\u043a\u043a\u0443\u043d\u0442",ss:"%d \u04ab\u0435\u043a\u043a\u0443\u043d\u0442",m:"\u043f\u04d7\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u043f\u04d7\u0440 \u0441\u0435\u0445\u0435\u0442",hh:"%d \u0441\u0435\u0445\u0435\u0442",d:"\u043f\u04d7\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u043f\u04d7\u0440 \u0443\u0439\u04d1\u0445",MM:"%d \u0443\u0439\u04d1\u0445",y:"\u043f\u04d7\u0440 \u04ab\u0443\u043b",yy:"%d \u04ab\u0443\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-\u043c\u04d7\u0448/,ordinal:"%d-\u043c\u04d7\u0448",week:{dow:1,doy:7}}
vendor: 8,525 bytes, line 51149
51149),l.defineLocale("cy",{months:"Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),monthsShort:"Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),weekdays:"Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),weekdaysShort:"Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),weekdaysMin:"Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Heddiw am] LT",nextDay:"[Yfory am] LT",nextWeek:"dddd [am] LT",lastDay:"[Ddoe am] LT",lastWeek:"dddd [diwethaf am] LT",sameElse:"L"},relativeTime:{future:"mewn %s",past:"%s yn \xf4l",s:"ychydig eiliadau",ss:"%d eiliad",m:"munud",mm:"%d munud",h:"awr",hh:"%d awr",d:"diwrnod",dd:"%d diwrnod",M:"mis",MM:"%d mis",y:"blwyddyn",yy:"%d flynedd"},dayOfMonthOrdinalParse:/\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,ordinal:function(e){var a="";return 20<e?a=40===e||50===e||60===e||80===e||100===e?"fed":"ain":0<e&&(a=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"][e]),e+a},week:{dow:1,doy:4}}),l.defineLocale("da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"s\xf8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\xf8rdag".split("_"),weekdaysShort:"s\xf8n_man_tir_ons_tor_fre_l\xf8r".split("_"),weekdaysMin:"s\xf8_ma_ti_on_to_fr_l\xf8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd [d.] D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"p\xe5 dddd [kl.] LT",lastDay:"[i g\xe5r kl.] LT",lastWeek:"[i] dddd[s kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"f\xe5 sekunder",ss:"%d sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en m\xe5ned",MM:"%d m\xe5neder",y:"et \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("de-at",{months:"J\xe4nner_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"J\xe4n._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:Ms,mm:"%d Minuten",h:Ms,hh:"%d Stunden",d:Ms,dd:Ms,M:Ms,MM:Ms,y:Ms,yy:Ms},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("de-ch",{months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:hs,mm:"%d Minuten",h:hs,hh:"%d Stunden",d:hs,dd:hs,M:hs,MM:hs,y:hs,yy:hs},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("de",{months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:Ls,mm:"%d Minuten",h:Ls,hh:"%d Stunden",d:Ls,dd:Ls,M:Ls,MM:Ls,y:Ls,yy:Ls},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});var cs=["\u0796\u07ac\u0782\u07aa\u0787\u07a6\u0783\u07a9","\u078a\u07ac\u0784\u07b0\u0783\u07aa\u0787\u07a6\u0783\u07a9","\u0789\u07a7\u0783\u07a8\u0797\u07aa","\u0787\u07ad\u0795\u07b0\u0783\u07a9\u078d\u07aa","\u0789\u07ad","\u0796\u07ab\u0782\u07b0","\u0796\u07aa\u078d\u07a6\u0787\u07a8","\u0787\u07af\u078e\u07a6\u0790\u07b0\u0793\u07aa","\u0790\u07ac\u0795\u07b0\u0793\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa","\u0787\u07ae\u0786\u07b0\u0793\u07af\u0784\u07a6\u0783\u07aa","\u0782\u07ae\u0788\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa","\u0791\u07a8\u0790\u07ac\u0789\u07b0\u0784\u07a6\u0783\u07aa"],Ys=["\u0787\u07a7\u078b\u07a8\u0787\u07b0\u078c\u07a6","\u0780\u07af\u0789\u07a6","\u0787\u07a6\u0782\u07b0\u078e\u07a7\u0783\u07a6","\u0784\u07aa\u078b\u07a6","\u0784\u07aa\u0783\u07a7\u0790\u07b0\u078a\u07a6\u078c\u07a8","\u0780\u07aa\u0786\u07aa\u0783\u07aa","\u0780\u07ae\u0782\u07a8\u0780\u07a8\u0783\u07aa"];l.defineLocale("dv",{months:cs,monthsShort:cs,weekdays:Ys,weekdaysShort:Ys,weekdaysMin:"\u0787\u07a7\u078b\u07a8_\u0780\u07af\u0789\u07a6_\u0787\u07a6\u0782\u07b0_\u0784\u07aa\u078b\u07a6_\u0784\u07aa\u0783\u07a7_\u0780\u07aa\u0786\u07aa_\u0780\u07ae\u0782\u07a8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0789\u0786|\u0789\u078a/,isPM:function(e){return"\u0789\u078a"===e},meridiem:function(e,a,t){return e<12?"\u0789\u0786":"\u0789\u078a"},calendar:{sameDay:"[\u0789\u07a8\u0787\u07a6\u078b\u07aa] LT",nextDay:"[\u0789\u07a7\u078b\u07a6\u0789\u07a7] LT",nextWeek:"dddd LT",lastDay:"[\u0787\u07a8\u0787\u07b0\u0794\u07ac] LT",lastWeek:"[\u078a\u07a7\u0787\u07a8\u078c\u07aa\u0788\u07a8] dddd LT",sameElse:"L"},relativeTime:{future:"\u078c\u07ac\u0783\u07ad\u078e\u07a6\u0787\u07a8 %s",past:"\u0786\u07aa\u0783\u07a8\u0782\u07b0 %s",s:"\u0790\u07a8\u0786\u07aa\u0782\u07b0\u078c\u07aa\u0786\u07ae\u0785\u07ac\u0787\u07b0",ss:"d% \u0790\u07a8\u0786\u07aa\u0782\u07b0\u078c\u07aa",m:"\u0789\u07a8\u0782\u07a8\u0793\u07ac\u0787\u07b0",mm:"\u0789\u07a8\u0782\u07a8\u0793\u07aa %d",h:"\u078e\u07a6\u0791\u07a8\u0787\u07a8\u0783\u07ac\u0787\u07b0",hh:"\u078e\u07a6\u0791\u07a8\u0787\u07a8\u0783\u07aa %d",d:"\u078b\u07aa\u0788\u07a6\u0780\u07ac\u0787\u07b0",dd:"\u078b\u07aa\u0788\u07a6\u0790\u07b0 %d",M:"\u0789\u07a6\u0780\u07ac\u0787\u07b0",MM:"\u0789\u07a6\u0790\u07b0 %d",y:"\u0787\u07a6\u0780\u07a6\u0783\u07ac\u0787\u07b0",yy:"\u0787\u07a6\u0780\u07a6\u0783\u07aa %d"},preparse:function(e){return e.replace(/\u060c/g,",")},postformat:function(e){return e.replace(/,/g,"\u060c")},week:{dow:7,doy:12}}),l.defineLocale("el",{monthsNominativeEl:"\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2_\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2_\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2_\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2_\u039c\u03ac\u03b9\u03bf\u03c2_\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2_\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2_\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2_\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2_\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2_\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2_\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2".split("_"),monthsGenitiveEl:"\u
511490399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5_\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5_\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5_\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5_\u039c\u03b1\u0390\u03bf\u03c5_\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5_\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5_\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5_\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5_\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5_\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5_\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5".split("_"),months:function(e,a){return e?"string"==typeof a&&/D/.test(a.substring(0,a.indexOf("MMMM")))?this._monthsGenitiveEl[e.month()]:this._monthsNominativeEl[e.month()]:this._monthsNominativeEl},monthsShort:"\u0399\u03b1\u03bd_\u03a6\u03b5\u03b2_\u039c\u03b1\u03c1_\u0391\u03c0\u03c1_\u039c\u03b1\u03ca_\u0399\u03bf\u03c5\u03bd_\u0399\u03bf\u03c5\u03bb_\u0391\u03c5\u03b3_\u03a3\u03b5\u03c0_\u039f\u03ba\u03c4_\u039d\u03bf\u03b5_\u0394\u03b5\u03ba".split("_"),weekdays:"\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae_\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1_\u03a4\u03c1\u03af\u03c4\u03b7_\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7_\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7_\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae_\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf".split("_"),weekdaysShort:"\u039a\u03c5\u03c1_\u0394\u03b5\u03c5_\u03a4\u03c1\u03b9_\u03a4\u03b5\u03c4_\u03a0\u03b5\u03bc_\u03a0\u03b1\u03c1_\u03a3\u03b1\u03b2".split("_"),weekdaysMin:"\u039a\u03c5_\u0394\u03b5_\u03a4\u03c1_\u03a4\u03b5_\u03a0\u03b5_\u03a0\u03b1_\u03a3\u03b1".split("_"),meridiem:function(e,a,t){return 11<e?t?"\u03bc\u03bc":"\u039c\u039c":t?"\u03c0\u03bc":"\u03a0\u039c"},isPM:function(e){return"\u03bc"===(e+"").toLowerCase()[0]},meridiemParse:/[\u03a0\u039c]\.?\u039c?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 {}] LT",nextDay:"[\u0391\u03cd\u03c1\u03b9\u03bf {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[\u03a7\u03b8\u03b5\u03c2 {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[\u03c4\u03bf \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf] dddd [{}] LT";default:return"[\u03c4\u03b7\u03bd \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03b7] dddd [{}] LT"}},sameElse:"L"},calendar:function(e,a){var t=this._calendarEl[e],s=a&&a.hours();return H(t)&&(t=t.apply(a)),t.replace("{}",s%12==1?"\u03c3\u03c4\u03b7":"\u03c3\u03c4\u03b9\u03c2")},relativeTime:{future:"\u03c3\u03b5 %s",past:"%s \u03c0\u03c1\u03b9\u03bd",s:"\u03bb\u03af\u03b3\u03b1 \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1",ss:"%d \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1",m:"\u03ad\u03bd\u03b1 \u03bb\u03b5\u03c0\u03c4\u03cc",mm:"%d \u03bb\u03b5\u03c0\u03c4\u03ac",h:"\u03bc\u03af\u03b1 \u03ce\u03c1\u03b1",hh:"%d \u03ce\u03c1\u03b5\u03c2",d:"\u03bc\u03af\u03b1 \u03bc\u03ad\u03c1\u03b1",dd:"%d \u03bc\u03ad\u03c1\u03b5\u03c2",M:"\u03ad\u03bd\u03b1\u03c2 \u03bc\u03ae\u03bd\u03b1\u03c2",MM:"%d \u03bc\u03ae\u03bd\u03b5\u03c2",y:"\u03ad\u03bd\u03b1\u03c2 \u03c7\u03c1\u03cc\u03bd\u03bf\u03c2",yy:"%d \u03c7\u03c1\u03cc\u03bd\u03b9\u03b1"},dayOfMonthOrdinalParse:/\d{1,2}\u03b7/,ordinal:"%d\u03b7",week:{dow:1,doy:4}}),l.defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")},week:{dow:1,doy:4}}),l.defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LT
51149S:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")}}),l.defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")},week:{dow:1,doy:4}}),l.defineLocale("en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")},week:{dow:1,doy:4}}),l.defineLocale("en-il",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")}}),l.defineLocale("en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LT
51149S:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")},week:{dow:1,doy:4}}),l.defineLocale("eo",{months:"januaro_februaro_marto_aprilo_majo_junio_julio_a\u016dgusto_septembro_oktobro_novembro_decembro".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_a\u016dg_sep_okt_nov_dec".split("_"),weekdays:"diman\u0109o_lundo_mardo_merkredo_\u0135a\u016ddo_vendredo_sabato".split("_"),weekdaysShort:"dim_lun_mard_merk_\u0135a\u016d_ven_sab".split("_"),weekdaysMin:"di_lu_ma_me_\u0135a_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D[-a de] MMMM, YYYY",LLL:"D[-a de] MMMM, YYYY HH:mm",LLLL:"dddd, [la] D[-a de] MMMM, YYYY HH:mm"},meridiemParse:/[ap]\.t\.m/i,isPM:function(e){return"p"===e.charAt(0).toLowerCase()},meridiem:function(e,a,t){return 11<e?t?"p.t.m.":"P.T.M.":t?"a.t.m."
vendor: 11,082 bytes, line 51149
51149:"A.T.M."},calendar:{sameDay:"[Hodia\u016d je] LT",nextDay:"[Morga\u016d je] LT",nextWeek:"dddd [je] LT",lastDay:"[Hiera\u016d je] LT",lastWeek:"[pasinta] dddd [je] LT",sameElse:"L"},relativeTime:{future:"post %s",past:"anta\u016d %s",s:"sekundoj",ss:"%d sekundoj",m:"minuto",mm:"%d minutoj",h:"horo",hh:"%d horoj",d:"tago",dd:"%d tagoj",M:"monato",MM:"%d monatoj",y:"jaro",yy:"%d jaroj"},dayOfMonthOrdinalParse:/\d{1,2}a/,ordinal:"%da",week:{dow:1,doy:7}});var ys="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),fs="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),ks=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],ps=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;l.defineLocale("es-do",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,a){return e?/-MMM-/.test(a)?fs[e.month()]:ys[e.month()]:ys},monthsRegex:ps,monthsShortRegex:ps,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:ks,longMonthsParse:ks,shortMonthsParse:ks,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}});var Ds="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),Ts="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_");l.defineLocale("es-us",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,a){return e?/-MMM-/.test(a)?Ts[e.month()]:Ds[e.month()]:Ds},monthsParseExact:!0,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"MM/DD/YYYY",LL:"MMMM [de] D [de] YYYY",LLL:"MMMM [de] D [de] YYYY h:mm A",LLLL:"dddd, MMMM [de] D [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:0,doy:6}});var gs="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),ws="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),vs=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],Ss=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;function Hs(e,a,t,s){var n={s:["m\xf5ne sekundi","m\xf5ni sekund","paar sekundit"],ss:[e+"sekundi",e+"sekundit"],m:["\xfche minuti","\xfcks minut"],mm:[e+" minuti",e+" minutit"],h:["\xfche tunni","tund aega","\xfcks tund"],hh:[e+" tunni",e+" tundi"],d:["\xfche p\xe4eva","\xfcks p\xe4ev"],M:["kuu aja","kuu aega","\xfcks kuu"],MM:[e+" kuu",e+" kuud"],y:["\xfche aasta","aasta","\xfcks aasta"],yy:[e+" aasta",e+" aastat"]};return a?n[t][2]?n[t][2]:n[t][1]:s?n[t][0]:n[t][1]}l.defineLocale("es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,a){return e?/-MMM-/.test(a)?ws[e.month()]:gs[e.month()]:gs},monthsRegex:Ss,monthsShortRegex:Ss,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:vs,longMonthsParse:vs,shortMonthsParse:vs,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}}),l.defineLocale("et",{months:"jaanuar_veebruar_m\xe4rts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),monthsShort:"jaan_veebr_m\xe4rts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),weekdays:"p\xfchap\xe4ev_esmasp\xe4ev_teisip\xe4ev_kolmap\xe4ev_neljap\xe4ev_reede_laup\xe4ev".split("_"),weekdaysShort:"P_E_T_K_N_R_L".split("_"),weekdaysMin:"P_E_T_K_N_R_L".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[T\xe4na,] LT",nextDay:"[Homme,] LT",nextWeek:"[J\xe4rgmine] dddd LT",lastDay:"[Eile,] LT",lastWeek:"[Eelmine] dddd LT",sameElse:"L"},relativeTime:{future:"%s p\xe4rast",past:"%s tagasi",s:Hs,ss:Hs,m:Hs,mm:Hs,h:Hs,hh:Hs,d:Hs,dd:"%d p\xe4eva",M:Hs,MM:Hs,y:Hs,yy:Hs},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("eu",{months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),monthsParseExact:!0,weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY[ko] MMMM[ren] D[a]",LLL:"YYYY[ko] MMMM[ren] D[a] HH:mm",LLLL:"dddd, YYYY[ko] MMMM[ren] D[a] HH:mm",l:"YYYY-M-D",ll:"YYYY[ko] MMM D[a]",lll:"YYYY[ko] MMM D[a] HH:mm",llll:"ddd, YYYY[ko] MMM D[a] HH:mm"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",ss:"%d segundo",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});var bs={1:"\u06f1",2:"\u06f2",3:"\u06f3",4:"\u06f4",5:"\u06f5",6:"\u06f6",7:"\u06f7",8:"\u06f8",9:"\u06f9",0:"\u06f0"},js={"\u06f1":"1","\u06f2":"2","\u06f3":"3","\u06f4":"4","\u06f5":"5","\u06f6":"6","\u06f7":"7","\u06f8":"8","\u06f9":"9","\u06f0":"0"};l.defineLocale("fa",{months:"\u0698\u0627\u0646\u0648\u06cc\u0647_\u0641\u0648\u0631\u06cc\u0647_\u0645\u0627\u0631\u0633_\u0622\u0648\u0631\u06cc\u0644_\u0645\u0647_\u0698\u0648\u0626\u0646_\u0698\u0648\u0626\u06cc\u0647_\u0627\u0648\u062a_\u0633\u067e\u062a\u0627\u0645\u0628\u0631_\u0627\u06a9\u062a\u0628\u0631_\u0646\u0648\u0627\u0645\u0628\u0631_\u062f\u0633\u0627\u0645\u0628\u0631".split("_"),monthsShort:"\u0698\u0627\u0646\u0648\u06cc\u0647_\u0641\u0648\u0631\u06cc\u0647_\u0645\u0627\u0631\u0633_\u0622\u0648\u0631\u06cc\u0644_\u0645\u0647_\u0698\u0648\u0626\u0646_\u0698\u0648\u0626\u06cc\u0647_\u0627\u0648\u062a_\u0633\u067e\u062a\u0627\u0645\u0628\u0631_\u0627\u06a9\u062a\u0628\u0631_\u0646\u0648\u0627\u0645\u0628\u0631_\u062f\u0633\u0627\u0645\u0628\u0631".split("_"),weekdays:"\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647_\u062f\u0648\u0634\u0646\u0628\u0647_\u0633\u0647\u200c\u0634\u0646\u0628\u0647_\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647_\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647_\u062c\u0645\u0639\u0647_\u0634\u0646\u0628\u0647".split("_"),weekdaysShort:"\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647_\u062f\u0648\u0634\u0646\u0628\u0647_\u0633\u0647\u200c\u0634\u0646\u0628\u0647_\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647_\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647_\u062c\u0645\u0639\u0647_\u0634\u0646\u0628\u0647".split("_"),weekdaysMin:"\u06cc_\u062f_\u0633_\u0686_\u067e_\u062c_\u0634".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/\u0642\u0628\u0644 \u0627\u0632 \u0638\u0647\u0631|\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631/,isPM:function(e){return/\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631/.test(e)},meridiem:function(e,a,t){return e<12?"\u0642\u0628\u0644 \u0627\u0632 \u0638\u0647\u0631":"\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631"},calendar:{sameDay:"[\u0627\u0645\u0631\u0648\u0632 \u0633\u0627\u0639\u062a] LT",nextDay:"[\u0641\u0631\u062f\u0627 \u0633\u0627\u0639\u062a] LT",nextWeek:"dddd [\u0633\u0627\u0639\u062a] LT",lastDay:"[\u062f\u06cc\u0631\u0648\u0632 \u0633\u0627\u0639\u062a] LT",lastWeek:"dddd [\u067e\u06cc\u0634] [\u0633\u0627\u0639\u062a] LT",sameElse:"L"}
vendor: 10,452 bytes, line 51149
51149,relativeTime:{future:"\u062f\u0631 %s",past:"%s \u067e\u06cc\u0634",s:"\u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647",ss:"\u062b\u0627\u0646\u06cc\u0647 d%",m:"\u06cc\u06a9 \u062f\u0642\u06cc\u0642\u0647",mm:"%d \u062f\u0642\u06cc\u0642\u0647",h:"\u06cc\u06a9 \u0633\u0627\u0639\u062a",hh:"%d \u0633\u0627\u0639\u062a",d:"\u06cc\u06a9 \u0631\u0648\u0632",dd:"%d \u0631\u0648\u0632",M:"\u06cc\u06a9 \u0645\u0627\u0647",MM:"%d \u0645\u0627\u0647",y:"\u06cc\u06a9 \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(e){return e.replace(/[\u06f0-\u06f9]/g,function(e){return js[e]}).replace(/\u060c/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return bs[e]}).replace(/,/g,"\u060c")},dayOfMonthOrdinalParse:/\d{1,2}\u0645/,ordinal:"%d\u0645",week:{dow:6,doy:12}});var xs="nolla yksi kaksi kolme nelj\xe4 viisi kuusi seitsem\xe4n kahdeksan yhdeks\xe4n".split(" "),Ps=["nolla","yhden","kahden","kolmen","nelj\xe4n","viiden","kuuden",xs[7],xs[8],xs[9]];function Os(e,a,t,s){var n,d,r="";switch(t){case"s":return s?"muutaman sekunnin":"muutama sekunti";case"ss":return s?"sekunnin":"sekuntia";case"m":return s?"minuutin":"minuutti";case"mm":r=s?"minuutin":"minuuttia";break;case"h":return s?"tunnin":"tunti";case"hh":r=s?"tunnin":"tuntia";break;case"d":return s?"p\xe4iv\xe4n":"p\xe4iv\xe4";case"dd":r=s?"p\xe4iv\xe4n":"p\xe4iv\xe4\xe4";break;case"M":return s?"kuukauden":"kuukausi";case"MM":r=s?"kuukauden":"kuukautta";break;case"y":return s?"vuoden":"vuosi";case"yy":r=s?"vuoden":"vuotta";break}return d=s,r=((n=e)<10?d?Ps[n]:xs[n]:n)+" "+r}l.defineLocale("fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kes\xe4kuu_hein\xe4kuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kes\xe4_hein\xe4_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[t\xe4n\xe4\xe4n] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s p\xe4\xe4st\xe4",past:"%s sitten",s:Os,ss:Os,m:Os,mm:Os,h:Os,hh:Os,d:Os,dd:Os,M:Os,MM:Os,y:Os,yy:Os},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("fo",{months:"januar_februar_mars_apr\xedl_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sunnudagur_m\xe1nadagur_t\xfdsdagur_mikudagur_h\xf3sdagur_fr\xedggjadagur_leygardagur".split("_"),weekdaysShort:"sun_m\xe1n_t\xfds_mik_h\xf3s_fr\xed_ley".split("_"),weekdaysMin:"su_m\xe1_t\xfd_mi_h\xf3_fr_le".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D. MMMM, YYYY HH:mm"},calendar:{sameDay:"[\xcd dag kl.] LT",nextDay:"[\xcd morgin kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\xcd gj\xe1r kl.] LT",lastWeek:"[s\xed\xf0stu] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"um %s",past:"%s s\xed\xf0ani",s:"f\xe1 sekund",ss:"%d sekundir",m:"ein minutt",mm:"%d minuttir",h:"ein t\xedmi",hh:"%d t\xedmar",d:"ein dagur",dd:"%d dagar",M:"ein m\xe1na\xf0i",MM:"%d m\xe1na\xf0ir",y:"eitt \xe1r",yy:"%d \xe1r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("fr-ca",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(e,a){switch(a){default:case"M":case"Q":case"D":case"DDD":case"d":return e+(1===e?"er":"e");case"w":case"W":return e+(1===e?"re":"e")}}}),l.defineLocale("fr-ch",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(e,a){switch(a){default:case"M":case"Q":case"D":case"DDD":case"d":return e+(1===e?"er":"e");case"w":case"W":return e+(1===e?"re":"e")}},week:{dow:1,doy:4}}),l.defineLocale("fr",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|)/,ordinal:function(e,a){switch(a){case"D":return e+(1===e?"er":"");default:case"M":case"Q":case"DDD":case"d":return e+(1===e?"er":"e");case"w":case"W":return e+(1===e?"re":"e")}},week:{dow:1,doy:4}});var Ws="jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.".split("_"),Es="jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_");l.defineLocale("fy",{months:"jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber".split("_"),monthsShort:function(e,a){return e?/-MMM-/.test(a)?Es[e.month()]:Ws[e.month()]:Ws},monthsParseExact:!0,weekdays:"snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon".split("_"),weekdaysShort:"si._mo._ti._wo._to._fr._so.".split("_"),weekdaysMin:"Si_Mo_Ti_Wo_To_Fr_So".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[hjoed om] LT",nextDay:"[moarn om] LT",nextWeek:"dddd [om] LT",lastDay:"[juster om] LT",lastWeek:"[\xf4fr\xfbne] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oer %s",past:"%s lyn",s:"in pear sekonden",ss:"%d sekonden",m:"ien min\xfat",mm:"%d minuten",h:"ien oere",hh:"%d oeren",d:"ien dei",dd:"%d dagen",M:"ien moanne",MM:"%d moannen",y:"ien jier",yy:"%d jierren"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||20<=e?"ste":"de")},week:{dow:1,doy:4}});function As(e,a,t,s){var n={s:["thodde secondanim","thodde second"],ss:[e+" secondanim",e+" second"],m:["eka mintan","ek minute"],mm:[e+" mintanim",e+" mintam"],h:["eka horan","ek hor"],hh:[e+" horanim",e+" horam"],d:["eka disan","ek dis"],dd:[e+" disanim",e+" dis"],M:["eka mhoinean","ek mhoino"],MM:[e+" mhoineanim",e+" mhoine"],y:["eka vorsan","ek voros"],yy:[e+" vorsanim",e+" vorsam"]};return a?n[t][0]:n[t][1]}l.defineLocale("gd",{months:["Am Faoilleach","An Gearran","Am M\xe0rt","An Giblean","An C\xe8itean","An t-\xd2gmhios","An t-Iuchar","An L\xf9nastal","An t-Sultain","An D\xe0mhair","An t-Samhain","An D\xf9bhlachd"],monthsShort:["Faoi","Gear","M\xe0rt","Gibl","C\xe8it","\xd2gmh","Iuch","L\xf9n","Sult","D\xe0mh","Samh","D\xf9bh"],monthsParseExact:!0,weekdays:["Did\xf2mhnaich","Diluain","Dim\xe0irt","Diciadain","Diardaoin","Dihaoine","Disathairne"],weekdaysShort:["Did","Dil","Dim","Dic","Dia","Dih","Dis"],weekdaysMin:["D\xf2","Lu","M\xe0","Ci","Ar","Ha","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[An-diugh aig] LT",nextDay:"[A-m\xe0ireach aig] LT",nextWeek:"dddd [aig] LT",lastDay:"[An-d\xe8 aig] LT",lastWeek:"dddd [seo chaidh] [aig] LT",sameElse:"L"},relativeTime:{future:"ann an %s",past:"bho chionn %s",s:"beagan diogan",ss:"%d diogan",m:"mionaid",mm:"%d mionaidean",h:"uair",hh:"%d uairean",d:"latha",dd:"%d latha",M:"m\xecos",MM:"%d m\xecosan",y:"bliadhna",yy:"%d bliadhna"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(e){return e+(1===e?"d":e%10==2?"na":"mh")},week:{dow:1,doy:4}}),l.defineLocale("gl",{months:"xaneiro_febreiro_marzo_abril_maio_xu\xf1o_xullo_agosto_setembro_outubro_novembro_decembro".split("_"),monthsShort:"xan._feb._mar._abr._mai._xu\xf1._xul._ago._set._out._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"domingo_luns_martes_m\xe9rcores_xoves_venres_s\xe1bado".
vendor: 4,942 bytes, line 51149
51149split("_"),weekdaysShort:"dom._lun._mar._m\xe9r._xov._ven._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_m\xe9_xo_ve_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"\xe1s":"\xe1")+"] LT"},nextDay:function(){return"[ma\xf1\xe1 "+(1!==this.hours()?"\xe1s":"\xe1")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"\xe1s":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"\xe1":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"\xe1s":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(e){return 0===e.indexOf("un")?"n"+e:"en "+e},past:"hai %s",s:"uns segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}}),l.defineLocale("gom-latn",{months:"Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr".split("_"),monthsShort:"Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son'var".split("_"),weekdaysShort:"Ait._Som._Mon._Bud._Bre._Suk._Son.".split("_"),weekdaysMin:"Ai_Sm_Mo_Bu_Br_Su_Sn".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A h:mm [vazta]",LTS:"A h:mm:ss [vazta]",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY A h:mm [vazta]",LLLL:"dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]",llll:"ddd, D MMM YYYY, A h:mm [vazta]"},calendar:{sameDay:"[Aiz] LT",nextDay:"[Faleam] LT",nextWeek:"[Ieta to] dddd[,] LT",lastDay:"[Kal] LT",lastWeek:"[Fatlo] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s",past:"%s adim",s:As,ss:As,m:As,mm:As,h:As,hh:As,d:As,dd:As,M:As,MM:As,y:As,yy:As},dayOfMonthOrdinalParse:/\d{1,2}(er)/,ordinal:function(e,a){switch(a){case"D":return e+"er";default:case"M":case"Q":case"DDD":case"d":case"w":case"W":return e}},week:{dow:1,doy:4},meridiemParse:/rati|sokalli|donparam|sanje/,meridiemHour:function(e,a){return 12===e&&(e=0),"rati"===a?e<4?e:e+12:"sokalli"===a?e:"donparam"===a?12<e?e:e+12:"sanje"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"rati":e<12?"sokalli":e<16?"donparam":e<20?"sanje":"rati"}});var Fs={1:"\u0ae7",2:"\u0ae8",3:"\u0ae9",4:"\u0aea",5:"\u0aeb",6:"\u0aec",7:"\u0aed",8:"\u0aee",9:"\u0aef",0:"\u0ae6"},zs={"\u0ae7":"1","\u0ae8":"2","\u0ae9":"3","\u0aea":"4","\u0aeb":"5","\u0aec":"6","\u0aed":"7","\u0aee":"8","\u0aef":"9","\u0ae6":"0"};l.defineLocale("gu",{months:"\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1\u0a86\u0ab0\u0ac0_\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1\u0a86\u0ab0\u0ac0_\u0aae\u0abe\u0ab0\u0acd\u0a9a_\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2_\u0aae\u0ac7_\u0a9c\u0ac2\u0aa8_\u0a9c\u0ac1\u0ab2\u0abe\u0a88_\u0a91\u0a97\u0ab8\u0acd\u0a9f_\u0ab8\u0aaa\u0acd\u0a9f\u0ac7\u0aae\u0acd\u0aac\u0ab0_\u0a91\u0a95\u0acd\u0a9f\u0acd\u0aac\u0ab0_\u0aa8\u0ab5\u0ac7\u0aae\u0acd\u0aac\u0ab0_\u0aa1\u0abf\u0ab8\u0ac7\u0aae\u0acd\u0aac\u0ab0".split("_"),monthsShort:"\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1._\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1._\u0aae\u0abe\u0ab0\u0acd\u0a9a_\u0a8f\u0aaa\u0acd\u0ab0\u0abf._\u0aae\u0ac7_\u0a9c\u0ac2\u0aa8_\u0a9c\u0ac1\u0ab2\u0abe._\u0a91\u0a97._\u0ab8\u0aaa\u0acd\u0a9f\u0ac7._\u0a91\u0a95\u0acd\u0a9f\u0acd._\u0aa8\u0ab5\u0ac7._\u0aa1\u0abf\u0ab8\u0ac7.".split("_"),monthsParseExact:!0,weekdays:"\u0ab0\u0ab5\u0abf\u0ab5\u0abe\u0ab0_\u0ab8\u0acb\u0aae\u0ab5\u0abe\u0ab0_\u0aae\u0a82\u0a97\u0ab3\u0ab5\u0abe\u0ab0_\u0aac\u0ac1\u0aa7\u0acd\u0ab5\u0abe\u0ab0_\u0a97\u0ac1\u0ab0\u0ac1\u0ab5\u0abe\u0ab0_\u0ab6\u0ac1\u0a95\u0acd\u0ab0\u0ab5\u0abe\u0ab0_\u0ab6\u0aa8\u0abf\u0ab5\u0abe\u0ab0".split("_"),weekdaysShort:"\u0ab0\u0ab5\u0abf_\u0ab8\u0acb\u0aae_\u0aae\u0a82\u0a97\u0ab3_\u0aac\u0ac1\u0aa7\u0acd_\u0a97\u0ac1\u0ab0\u0ac1_\u0ab6\u0ac1\u0a95\u0acd\u0ab0_\u0ab6\u0aa8\u0abf".split("_"),weekdaysMin:"\u0ab0_\u0ab8\u0acb_\u0aae\u0a82_\u0aac\u0ac1_\u0a97\u0ac1_\u0ab6\u0ac1_\u0ab6".split("_"),longDateFormat:{LT:"A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",LTS:"A h:mm:ss \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",LLLL:"dddd, D MMMM YYYY, A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7"},calendar:{sameDay:"[\u0a86\u0a9c] LT",nextDay:"[\u0a95\u0abe\u0ab2\u0ac7] LT",nextWeek:"dddd, LT",lastDay:"[\u0a97\u0a87\u0a95\u0abe\u0ab2\u0ac7] LT",lastWeek:"[\u0aaa\u0abe\u0a9b\u0ab2\u0abe] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0aae\u0abe",past:"%s \u0aaa\u0ac7\u0ab9\u0ab2\u0abe",s:"\u0a85\u0aae\u0ac1\u0a95 \u0aaa\u0ab3\u0acb",ss:"%d \u0ab8\u0ac7\u0a95\u0a82\u0aa1",m:"\u0a8f\u0a95 \u0aae\u0abf\u0aa8\u0abf\u0a9f",mm:"%d \u0aae\u0abf\u0aa8\u0abf\u0a9f",h:"\u0a8f\u0a95 \u0a95\u0ab2\u0abe\u0a95",hh:"%
51149d \u0a95\u0ab2\u0abe\u0a95",d:"\u0a8f\u0a95 \u0aa6\u0abf\u0ab5\u0ab8",dd:"%d \u0aa6\u0abf\u0ab5\u0ab8",M:"\u0a8f\u0a95 \u0aae\u0ab9\u0abf\u0aa8\u0acb",MM:"%d \u0aae\u0ab9\u0abf\u0aa8\u0acb",y:"\u0a8f\u0a95 \u0ab5\u0ab0\u0acd\u0ab7",yy:"%d \u0ab5\u0ab0\u0acd\u0ab7"},preparse:function(e){return e.replace(/[\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0ae6]/g,function(e){return zs[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return Fs[e]})},meridiemParse:/\u0ab0\u0abe\u0aa4|\u0aac\u0aaa\u0acb\u0ab0|\u0ab8\u0ab5\u0abe\u0ab0|\u0ab8\u0abe\u0a82\u0a9c/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0ab0\u0abe\u0aa4"===a?e<4?e:e+12:"\u0ab8\u0ab5\u0abe\u0ab0"===a?e:"\u0aac\u0aaa\u0acb\u0ab0"===a?10<=e?e:e+12:"\u0ab8\u0abe\u0a82\u0a9c"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"\u0ab0\u0abe\u0aa4":e<10?"\u0ab8\u0ab5\u0abe\u0ab0":e<17?"\u0aac\u0aaa\u0acb\u0ab0":e<20?"\u0ab8\u0abe\u0a82\u0a9c":"\u0ab0\u0abe\u0aa4"},week:{dow:0,doy:6}}),l.defineLocale("he",{months:"\u05d9\u05e0\u05d5\u05d0\u05e8_\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8_\u05de\u05e8\u05e5_\u05d0\u05e4\u05e8\u
5114905d9\u05dc_\u05de\u05d0\u05d9_\u05d9\u05d5\u05e0\u05d9_\u05d9\u05d5\u05dc\u05d9_\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8_\u05e1\u05e4\u05d8\u05de\u05d1\u05e8_\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8_\u05e0\u05d5\u05d1\u05de\u05d1\u05e8_\u05d3\u05e6\u05de\u05d1\u05e8".split("_"),monthsShort:"\u05d9\u05e0\u05d5\u05f3_\u05e4\u05d1\u05e8\u05f3_\u05de\u05e8\u05e5_\u05d0\u05e4\u05e8\u05f3_\u05de\u05d0\u05d9_\u05d9\u05d5\u05e0\u05d9_\u05d9\u05d5\u05dc\u05d9_\u05d0\u05d5\u05d2\u05f3_\u05e1\u05e4\u05d8\u05f3_\u05d0\u05d5\u05e7\u05f3_\u05e0\u05d5\u05d1\u05f3_\u05d3\u05e6\u05de\u05f3".split("_"),weekdays:"\u05e8\u05d0\u05e9\u05d5\u05df_\u05e9\u05e0\u05d9_\u05e9\u05dc\u05d9\u05e9\u05d9_\u05e8\u05d1\u05d9\u05e2\u05d9_\u05d7\u05de\u05d9\u05e9\u05d9_\u05e9\u05d9\u05e9\u05d9_\u05e9\u05d1\u05ea".split("_"),weekdaysShort:"\u05d0\u05f3_\u05d1\u05f3_\u05d2\u05f3_\u05d3\u05f3_\u05d4\u05f3_\u05d5\u05f3_\u05e9\u05f3".split("_"),weekdaysMin:"\u05d0_\u05d1_\u05d2_\u05d3_\u05d4_\u05d5_\u05e9".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [\u05d1]MMMM YYYY",LLL:"D [\u05d1]MMMM YYYY HH:mm",LLLL:"dddd, D [\u05d1]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[\u05d4\u05d9\u05d5\u05dd \u05d1\u05be]LT",nextDay:"[\u05de\u05d7\u05e8 \u05d1\u05be]LT",nextWeek:"dddd [\u05d1\u05e9\u05e2\u05d4] LT",lastDay:"[\u05d0\u05ea\u05de\u05d5\u05dc \u05d1\u05be]LT",lastWeek:"[\u05d1\u05d9\u05d5\u05dd] dddd [\u05d4\u05d0\u05d7\u05e8\u05d5\u05df \u05d1\u05e9\u05e2\u05d4] LT",sameElse:"L"},relativeTime:{future:"\u05d1\u05e2\u05d5\u05d3 %s",past:"\u05dc\u05e4\u05e0\u05d9 %s",s:"\u05de\u05e1\u05e4\u05e8 \u05e9\u05e0\u05d9\u05d5\u05ea",ss:"%d \u05e9\u05e0\u05d9\u05d5\u05ea",m:"\u05d3\u05e7\u05d4",mm:"%d \u05d3\u05e7\u05d5\u05ea",h:"\u05e9\u05e2\u05d4",hh:function(e){return 2===e?"\u05e9\u05e2\u05ea\u05d9\u05d9\u05dd":e+" \u05e9\u05e2\u05d5\u05ea"},d:"\u05d9\u05d5\u05dd",dd:function(e){return 2===e?"\u05d9\u05d5\u05de\u05d9\u05d9\u05dd":e+" \u05d9\u05de\u05d9\u05dd"},M:"\u05d7\u05d5\u05d3\u05e9",MM:function(e){return 2===e?"\u05d7\u05d5\u05d3\u05e9\u05d9\u05d9\u05dd":e+" \u05d7\u05d5\u05d3\u05e9\u05d9\u05dd"},y:"\u05e9\u05e0\u05d4",yy:function(e){return 2===e?"\u05e9\u05e0\u05ea\u05d9\u05d9\u05dd":e%10==0&&10!==e?e+" \u05e9\u05e0\u05d4":e+" \u05e9\u05e0\u05d9\u05dd"}},meridiemParse:/\u05d0\u05d7\u05d4"\u05e6|\u05dc\u05e4\u05e0\u05d4"\u05e6|\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05dc\u05e4\u05e0\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05dc\u05e4\u05e0\u05d5\u05ea \u05d1\u05d5\u05e7\u05e8|\u05d1\u05d1\u05d5\u05e7\u05e8|\u05d1\u05e2\u05e8\u05d1/i,isPM:function(e){return/^(\u05d0\u05d7\u05d4"\u05e6|\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05d1\u05e2\u05e8\u05d1)$/.test(e)},meridiem:function(e,a,t){return e<5?"\u05dc\u05e4\u05e0\u05d5\u05ea \u05d1\u05d5\u05e7\u05e8":e<10?"\u05d1\u05d1\u05d5\u05e7\u05e8":e<12?t?'\u05dc\u05e4\u05e0\u05d4"\u05e6':"\u05dc\u05e4\u05e0\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd":e<18?t?'\u05d0\u05d7\u05d4"\u05e6':"\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd":"\u05d1\u05e2\u05e8\u05d1"}});var Js={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},Ns={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};function Rs(e,a,t){var s=e+" ";switch(t){case"ss":return s+=1===e?"sekunda":2===e||3===e||4===e?"sekunde":"sekundi";case"m":return a?"jedna minuta":"jedne minute";case"mm":return s+=1===e?"minuta":2===e||3===e||4===e?"minute":"minuta";case"h":return a?"jedan sat":"jednog sata";case"hh":return s+=1===e?"sat":2===e||3===e||4===e?"sata":"sati";case"dd":return s+=1===e?"dan":"dana";case"MM":return s+=1===e?"mjesec":2===e||3===e||4===e?"mjeseca":"mjeseci";case"yy":return s+=1===e?"godina":2===e||3===e||4===e?"godine":"godina"}}l.defineLocale("hi",{months:"\u091c\u0928\u0935\u0930\u0940_\u092b\u093c\u0930\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948\u
511490932_\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0938\u094d\u0924_\u0938\u093f\u0924\u092e\u094d\u092c\u0930_\u0905\u0915\u094d\u091f\u0942\u092c\u0930_\u0928\u0935\u092e\u094d\u092c\u0930_\u0926\u093f\u0938\u092e\u094d\u092c\u0930".split("_"),monthsShort:"\u091c\u0928._\u092b\u093c\u0930._\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948._\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932._\u0905\u0917._\u0938\u093f\u0924._\u0905\u0915\u094d\u091f\u0942._\u0928\u0935._\u0926\u093f\u0938.".split("_"),monthsParseExact:!0,weekdays:"\u0930\u0935\u093f\u0935\u093e\u0930_\u0938\u094b\u092e\u0935\u093e\u0930_\u092e\u0902\u0917\u0932\u0935\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u0917\u0941\u0930\u0942\u0935\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930_\u0936\u0928\u093f\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0930\u0935\u093f_\u0938\u094b\u092e_\u092e\u0902\u0917\u0932_\u092c\u0941\u0927_\u0917\u0941\u0930\u0942_\u0936\u0941\u0915\u094d\u0930_\u0936\u0928\u093f".split("_"),weekdaysMin:"\u0930_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u0917\u0941_\u0936\u0941_\u0936".split("_"),longDateFormat:{LT:"A h:mm \u092c\u091c\u0947",LTS:"A h:mm:ss \u092c\u091c\u0947",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u092c\u091c\u0947",LLLL:"dddd, D MMMM YYYY, A h:mm \u092c\u091c\u0947"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u0915\u0932] LT",nextWeek:"dddd, LT",lastDay:"[\u0915\u0932] LT",lastWeek:"[\u092a\u093f\u091b\u0932\u0947] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u092e\u0947\u0902",past:"%s \u092a\u0939\u0932\u0947",s:"\u0915\u0941\u091b \u0939\u0940 \u0915\u094d\u0937\u0923",ss:"%d \u0938\u0947\u0915\u0902\u0921",m:"\u090f\u0915 \u092e\u093f\u0928\u091f",mm:"%d \u092e\u093f\u0928\u091f",h:"\u090f\u0915 \u0918\u0902\u091f\u093e",hh:"%d \u0918\u0902\u091f\u0947",d:"\u090f\u0915 \u0926\u093f\u0928",dd:"%d \u0926\u093f\u0928",M:"\u090f\u0915 \u092e\u0939\u0940\u0928\u0947",MM:"%d \u092e\u0939\u0940\u0928\u0947",y:"\u090f\u0915 \u0935\u0930\u094d\u0937",yy:"%d \u0935\u0930\u094d\u0937"},preparse:function(e){return e.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(e){return Ns[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return Js[e]})},meridiemParse:/\u0930\u093e\u0924|\u0938\u0941\u092c\u0939|\u0926\u094b\u092a\u0939\u0930|\u0936\u093e\u092e/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0930\u093e\u0924"===a?e<4?e:e+12:"\u0938\u0941\u092c\u0939"===a?e:"\u0926\u094b\u092a\u0939\u0930"===a?10<=e?e:e+12:"\u0936\u093e\u092e"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"\u0930\u093e\u0924":e<10?"\u0938\u0941\u092c\u0939":e<17?"\u0926\u094b\u092a\u0939\u0930":e<20?"\u0936\u093e\u092e":"\u0930\u093e\u0924"},week:{dow:0,doy:6}}),l.defineLocale("hr",{months:{format:"sije\u010dnja_velja\u010de_o\u017eujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"sije\u010danj_velja\u010da_o\u017eujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._o\u017eu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010der u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[pro\u0161lu] dddd [u] LT";case 6:return"[pro\u0161le] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[pro\u0161li] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:Rs,m:Rs,mm:Rs,h:Rs,hh:Rs,d:"dan",dd:Rs,M:"mjesec",MM:Rs,y:"godinu",yy:Rs},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});var Is="vas\xe1rnap h\xe9tf\u0151n kedden szerd\xe1n cs\xfct\xf6rt\xf6k\xf6n p\xe9nteken szombaton".split(" ");function Cs(e,a,t,s){var n=e;switch(t){case"s":return s||a?"n\xe9h\xe1ny m\xe1sodperc":"n\xe9h\xe1ny m\xe1sodperce";case"ss":return n+(s||a)?" m\xe1sodperc":" m\xe1sodperce";case"m":return"egy"+(s||a?" perc":" perce");case"mm":return n+(s||a?" perc":" perce");case"h":return"egy"+(s||a?" \xf3ra":" \xf3r\xe1ja");case"hh":return n+(s||a?" \xf3ra":" \xf3r\xe1ja");case"d":return"egy"+(s||a?" nap":" napja");case"dd":return n+(s||a?" nap":" napja");case"M":return"egy"+(s||a?" h\xf3nap":" h\xf3napja");case"MM":return n+(s||a?" h\xf3nap":" h\xf3napja");case"y":return"egy"+(s||a?" \xe9v":" \xe9ve");case"yy":return n+(s||a?" \xe9v":" \xe9ve")}return""}function Gs(e){return(e?"":"[m\xfalt] ")+"["+Is[this.day()]+"] LT[-kor]"}function Us(e){return e%100==11||e%10!=1}function Vs(e,a,t,s){var n=e+" ";switch(t){case"s":return a||s?"nokkrar sek\xfandur":"nokkrum sek\xfandum";
vendor: 8,893 bytes, line 51149
51149case"ss":return Us(e)?n+(a||s?"sek\xfandur":"sek\xfandum"):n+"sek\xfanda";case"m":return a?"m\xedn\xfata":"m\xedn\xfatu";case"mm":return Us(e)?n+(a||s?"m\xedn\xfatur":"m\xedn\xfatum"):a?n+"m\xedn\xfata":n+"m\xedn\xfatu";case"hh":return Us(e)?n+(a||s?"klukkustundir":"klukkustundum"):n+"klukkustund";case"d":return a?"dagur":s?"dag":"degi";case"dd":return Us(e)?a?n+"dagar":n+(s?"daga":"d\xf6gum"):a?n+"dagur":n+(s?"dag":"degi");case"M":return a?"m\xe1nu\xf0ur":s?"m\xe1nu\xf0":"m\xe1nu\xf0i";case"MM":return Us(e)?a?n+"m\xe1nu\xf0ir":n+(s?"m\xe1nu\xf0i":"m\xe1nu\xf0um"):a?n+"m\xe1nu\xf0ur":n+(s?"m\xe1nu\xf0":"m\xe1nu\xf0i");case"y":return a||s?"\xe1r":"\xe1ri";case"yy":return Us(e)?n+(a||s?"\xe1r":"\xe1rum"):n+(a||s?"\xe1r":"\xe1ri")}}l.defineLocale("hu",{months:"janu\xe1r_febru\xe1r_m\xe1rcius_\xe1prilis_m\xe1jus_j\xfanius_j\xfalius_augusztus_szeptember_okt\xf3ber_november_december".split("_"),monthsShort:"jan_feb_m\xe1rc_\xe1pr_m\xe1j_j\xfan_j\xfal_aug_szept_okt_nov_dec".split("_"),weekdays:"vas\xe1rnap_h\xe9tf\u0151_kedd_szerda_cs\xfct\xf6rt\xf6k_p\xe9ntek_szombat".split("_"),weekdaysShort:"vas_h\xe9t_kedd_sze_cs\xfct_p\xe9n_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D. H:mm",LLLL:"YYYY. MMMM D., dddd H:mm"},meridiemParse:/de|du/i,isPM:function(e){return"u"===e.charAt(1).toLowerCase()},meridiem:function(e,a,t){return e<12?!0===t?"de":"DE":!0===t?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return Gs.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return Gs.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s m\xfalva",past:"%s",s:Cs,ss:Cs,m:Cs,mm:Cs,h:Cs,hh:Cs,d:Cs,dd:Cs,M:Cs,MM:Cs,y:Cs,yy:Cs},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("hy-am",{months:{format:"\u0570\u0578\u0582\u0576\u057e\u0561\u0580\u056b_\u0583\u0565\u057f\u0580\u057e\u0561\u0580\u056b_\u0574\u0561\u0580\u057f\u056b_\u0561\u057a\u0580\u056b\u056c\u056b_\u0574\u0561\u0575\u056b\u057d\u056b_\u0570\u0578\u0582\u0576\u056b\u057d\u056b_\u0570\u0578\u0582\u056c\u056b\u057d\u056b_\u0585\u0563\u0578\u057d\u057f\u0578\u057d\u056b_\u057d\u0565\u057a\u057f\u0565\u0574\u0562\u0565\u0580\u056b_\u0570\u0578\u056f\u057f\u0565\u0574\u0562\u0565\u0580\u056b_\u0576\u0578\u0575\u0565\u0574\u0562\u0565\u0580\u056b_\u0564\u0565\u056f\u057f\u0565\u0574\u0562\u0565\u0580\u056b".split("_"),standalone:"\u0570\u0578\u0582\u0576\u057e\u0561\u0580_\u0583\u0565\u057f\u0580\u057e\u0561\u0580_\u0574\u0561\u0580\u057f_\u0561\u057a\u0580\u056b\u056c_\u0574\u0561\u0575\u056b\u057d_\u0570\u0578\u0582\u0576\u056b\u057d_\u0570\u0578\u0582\u056c\u056b\u057d_\u0585\u0563\u0578\u057d\u057f\u0578\u057d_\u057d\u0565\u057a\u057f\u0565\u0574\u0562\u0565\u0580_\u0570\u0578\u056f\u057f\u0565\u0574\u0562\u0565\u0580_\u0576\u0578\u0575\u0565\u0574\u0562\u0565\u0580_\u0564\u0565\u056f\u057f\u0565\u0574\u0562\u0565\u0580".split("_")},monthsShort:"\u0570\u0576\u057e_\u0583\u057f\u0580_\u0574\u0580\u057f_\u0561\u057a\u0580_\u0574\u0575\u057d_\u0570\u0576\u057d_\u0570\u056c\u057d_\u0585\u0563\u057d_\u057d\u057a\u057f_\u0570\u056f\u057f_\u0576\u0574\u0562_\u0564\u056f\u057f".split("_"),weekdays:"\u056f\u056b\u0580\u0561\u056f\u056b_\u0565\u0580\u056f\u0578\u0582\u0577\u0561\u0562\u0569\u056b_\u0565\u0580\u0565\u0584\u0577\u0561\u0562\u0569\u056b_\u0579\u0578\u0580\u0565\u0584\u0577\u0561\u0562\u0569\u056b_\u0570\u056b\u0576\u0563\u0577\u0561\u0562\u0569\u056b_\u0578\u0582\u0580\u0562\u0561\u0569_\u0577\u0561\u0562\u0561\u0569".split("_"),weekdaysShort:"\u056f\u0580\u056f_\u0565\u0580\u056f_\u0565\u0580\u0584_\u0579\u0580\u0584_\u0570\u0576\u0563_\u0578\u0582\u0580\u0562_\u0577\u0562\u0569".split("_"),weekdaysMin:"\u056f\u0580\u056f_\u0565\u0580\u056f_\u0565\u0580\u0584_\u0579\u0580\u0584_\u0570\u0576\u0563_\u0578\u0582\u0580\u0562_\u0577\u0562\u0569".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0569.",LLL:"D MMMM YYYY \u0569., HH:mm",LLLL:"dddd, D MMMM YYYY \u0569., HH:mm"},calendar:{sameDay:"[\u0561\u0575\u057d\u0585\u0580] LT",nextDay:"[\u057e\u0561\u0572\u0568] LT",lastDay:"[\u0565\u0580\u0565\u056f] LT",nextWeek:function(){return"dddd [\u0585\u0580\u0568 \u056a\u0561\u0574\u0568] LT"},lastWeek:function(){return"[\u0561\u0576\u0581\u0561\u056e] dddd [\u0585\u0580\u0568 \u056a\u0561\u0574\u0568] LT"},sameElse:"L"},relativeTime:{future:"%s \u0570\u0565\u057f\u0578",past:"%s \u0561\u057c\u0561\u057b",s:"\u0574\u056b \u0584\u0561\u0576\u056b \u057e\u0561\u0575\u0580\u056f\u0575\u0561\u0576",ss:"%d \u057e\u0561\u0575\u0580\u056f\u0575\u0561\u0576",m:"\u0580\u0578\u057a\u0565",mm:"%d \u0580\u0578\u057a\u0565",h:"\u056a\u0561\u0574",hh:"%d \u056a\u0561\u0574",d:"\u0585\u0580",dd:"%d \u0585\u0580",M:"\u0561\u0574\u056b\u057d",MM:"%d \u0561\u0574\u056b\u057d",y:"\u057f\u0561\u0580\u056b",yy:"%d \u057f\u0561\u0580\u056b"},meridiemParse:/\u0563\u056b\u0577\u0565\u0580\u057e\u0561|\u0561\u057c\u0561\u057e\u0578\u057f\u057e\u0561|\u0581\u0565\u0580\u0565\u056f\u057e\u0561|\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576/,isPM:function(e){return/^(\u0581\u0565\u0580\u0565\u056f\u057e\u0561|\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576)$/.test(e)},meridiem:function(e){return e<4?"\u0563\u056b\u0577\u0565\u0580\u057e\u0561":e<12?"\u0561\u057c\u0561\u057e\u0578\u057f\u057e\u0561":e<17?"\u0581\u0565\u0580\u0565\u056f\u057e\u0561":"\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576"},dayOfMonthOrdinalParse:/\d{1,2}|\d{1,2}-(\u056b\u0576|\u0580\u0564)/,ordinal:function(e,a){switch(a){case"DDD":case"w":case"W":case"DDDo":return 1===e?e+"-\u056b\u0576":e+"-\u0580\u0564";default:return e}},week:{dow:1,doy:7}}),l.defineLocale("id",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(e,a){return 12===e&&(e=0),"pagi"===a?e:"siang"===a?11<=e?e:e+12:"sore"===a||"malam"===a?e+12:void 0},meridiem:function(e,a,t){return e<11?"pagi":e<15?"siang":e<19?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",ss:"%d detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}}),l.defineLocale("is",{months:"jan\xfaar_febr\xfaar_mars_apr\xedl_ma\xed_j\xfan\xed_j\xfal\xed_\xe1g\xfast_september_okt\xf3ber_n\xf3vember_desember".split("_"),monthsShort:"jan_feb_mar_apr_ma\xed_j\xfan_j\xfal_\xe1g\xfa_sep_okt_n\xf3v_des".split("_"),weekdays:"sunnudagur_m\xe1nudagur_\xferi\xf0judagur_mi\xf0vikudagur_fimmtudagur_f\xf6studagur_laugardagur".split("_"),weekdaysShort:"sun_m\xe1n_\xferi_mi\xf0_fim_f\xf6s_lau".split("_"),weekdaysMin:"Su_M\xe1_\xder_Mi_Fi_F\xf6_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd, D. MMMM YYYY [kl.] H:mm"},calendar:{sameDay:"[\xed dag kl.] LT",nextDay:"[\xe1 morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\xed g\xe6r kl.] LT",lastWeek:"[s\xed\xf0asta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s s\xed\xf0an",s:Vs,ss:Vs,m:Vs,mm:Vs,h:"klukkustund",hh:Vs,d:Vs,dd:Vs,M:Vs,MM:Vs,y:Vs,yy:Vs},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_luned\xec_marted\xec_mercoled\xec_gioved\xec_venerd\xec_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(e){return(/^[0-9].+$/.test(e)?"tra":"in")+" "+e},past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%
51149d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}}),l.defineLocale("ja",{months:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u65e5\u66dc\u65e5_\u6708\u66dc\u65e5_\u706b\u66dc\u65e5_\u6c34\u66dc\u65e5_\u6728\u66dc\u65e5_\u91d1\u66dc\u65e5_\u571f\u66dc\u65e5".split("_"),weekdaysShort:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),weekdaysMin:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5 dddd HH:mm",l:"YYYY/MM/DD",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5(ddd) HH:mm"},meridiemParse:/\u5348\u524d|\u5348\u5f8c/i,isPM:function(e){return"\u5348\u5f8c"===e},meridiem:function(e,a,t){return e<12?"\u5348\u524d":"\u5348\u5f8c"},calendar:{sameDay:"[\u4eca\u65e5] LT",nextDay:"[\u660e\u65e5] LT",nextWeek:function(e){return e.week()<this.week()?"[\u6765\u9031]dddd LT":"dddd LT"},lastDay:"[\u6628\u65e5] LT",lastWeek:function(e){return this.week()<e.week()?"[\u5148\u9031]dddd LT":"dddd LT"},sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}\u65e5/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"\u65e5";default:return e}},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u6570\u79d2",ss:"%d\u79d2",m:"1\u5206",mm:"%d\u5206",h:"1\u6642\u9593",hh:"%d\u6642\u9593",d:"1\u65e5",dd:"%d\u65e5",M:"1\u30f6\u6708",MM:"%d\u30f6\u6708",y:"1\u5e74",yy:"%d\u5e74"}}),l.defineLocale("jv",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des".split("_"),weekdays:"Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu".split("_"),weekdaysShort:"Min_Sen_Sel_Reb_Kem_Jem_Sep".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sp".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/enjing|siyang|sonten|ndalu/,meridiemHour:function(e,a){return 12===e&&(e=0),"enjing"===a?e:"siyang"===a?11<=e?e:e+12:"sonten"===a||"ndalu"===a?e+12:void 0},meridiem:function(e,a,t){return e<11?"enjing":e<15?"siyang":e<19?"sonten":"ndalu"},calendar:{sameDay:"[Dinten puniko pukul] LT",nextDay:"[Mbenjang pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kala wingi pukul] LT",lastWeek:"dddd [kepengker pukul] LT",sameElse:"L"},relativeTime:{future:"wonten ing %s",past:"%s ingkang kepengker",s:"sawetawis detik",ss:"%d detik",m:"setunggal menit",mm:"%d menit",h:"setunggal jam",hh:"%d jam",d:"sedinten",dd:"%d dinten",M:"sewulan",MM:"%d wulan",y:"setaun",yy:"%d taun"},week:{dow:1,doy:7}}),l.defineLocale("ka",{months:{standalone:"\u10d8\u10d0\u10dc\u10d5\u10d0\u10e0\u10d8_\u10d7\u10d4\u10d1\u10d4\u10e0\u10d5\u10d0\u10da\u10d8_\u10db\u10d0\u10e0\u10e2\u10d8_\u10d0\u10de\u10e0\u10d8\u10da\u10d8_\u10db\u10d0\u10d8\u10e1\u10d8_\u10d8\u10d5\u10dc\u10d8\u10e1\u10d8_\u10d8\u10d5\u10da\u10d8\u10e1\u10d8_\u10d0\u10d2\u10d5\u10d8\u10e1\u10e2\u10dd_\u10e1\u10d4\u10e5\u10e2\u10d4\u10db\u10d1\u10d4\u10e0\u10d8_\u10dd\u10e5\u10e2\u10dd\u10db\u10d1\u10d4\u10e0\u10d8_\u10dc\u10dd\u10d4\u10db\u10d1\u10d4\u10e0\u10d8_\u10d3\u10d4\u10d9\u10d4\u10db\u10d1\u10d4\u10e0\u10d8".split("_"),format:"\u10d8\u10d0\u10dc\u10d5\u10d0\u10e0\u10e1_\u10d7\u10d4\u10d1\u10d4\u10e0\u10d5\u10d0\u10da\u10e1_\u10db\u10d0\u10e0\u10e2\u10e1_\u10d0\u10de\u10e0\u10d8\u10da\u10d8\u10e1_\u10db\u10d0\u10d8\u10e1\u10e1_\u10d8\u10d5\u10dc\u10d8\u10e1\u10e1_\u10d8\u10d5\u10da\u10d8\u10e1\u10e1_\u10d0\u10d2\u10d5\u10d8\u10e1\u10e2\u10e1_\u10e1\u10d4\u10e5\u10e2\u10d4\u10db\u10d1\u10d4\u10e0\u10e1_\u10dd\u10e5\u10e2\u10dd\u10db\u10d1\u10d4\u10e0\u10e1_\u10dc\u10dd\u10d4\u10db\u10d1\u10d4\u10e0\u10e1_\u10d3\u10d4\u10d9\u10d4\u10db\u10d1\u10d4\u10e0\u10e1".split("_")},monthsShort:"\u10d8\u10d0\u10dc_\u10d7\u10d4\u10d1_\u10db\u10d0\u10e0_\u10d0\u10de\u10e0_\u10db\u10d0\u10d8_\u10d8\u10d5\u10dc_\u10d8\u10d5\u10da_\u10d0\u10d2\u10d5_\u10e1\u10d4\u10e5_\u10dd\u10e5\u10e2_\u10dc\u10dd\u10d4_\u10d3\u10d4\u10d9".split("_"),weekdays:{standalone:"\u10d9\u10d5\u10d8\u10e0\u10d0_\u10dd\u10e0\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10e1\u10d0\u10db\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10dd\u10d7\u10ee\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10ee\u10e3\u10d7\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10de\u10d0\u10e0\u10d0\u10e1\u10d9\u10d4\u10d5\u10d8_\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8".split("_"),format:"\u10d9\u10d5\u10d8\u10e0\u10d0\u10e1_\u10dd\u10e0\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10e1\u10d0\u10db\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10dd\u10d7\u10ee\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10ee\u10e3\u10d7\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10de\u10d0\u10e0\u10d0\u10e1\u10d9\u10d4\u10d5\u10e1_\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1".split("_"),isFormat:/(\u10ec\u10d8\u10dc\u10d0|\u10e8\u10d4\u10db\u10d3\u10d4\u10d2)/},weekdaysShort:"\u10d9\u10d5\u10d8_\u10dd\u10e0\u10e8_\u10e1\u10d0\u10db_\u10dd\u10d7\u10ee_\u10ee\u10e3\u10d7_\u10de\u10d0\u10e0_\u10e8\u10d0\u10d1".split("_"),weekdaysMin:"\u
5114910d9\u10d5_\u10dd\u10e0_\u10e1\u10d0_\u10dd\u10d7_\u10ee\u10e3_\u10de\u10d0_\u10e8\u10d0".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[\u10d3\u10e6\u10d4\u10e1] LT[-\u10d6\u10d4]",nextDay:"[\u10ee\u10d5\u10d0\u10da] LT[-\u10d6\u10d4]",lastDay:"[\u10d2\u10e3\u10e8\u10d8\u10dc] LT[-\u10d6\u10d4]",nextWeek:"[\u10e8\u10d4\u10db\u10d3\u10d4\u10d2] dddd LT[-\u10d6\u10d4]",lastWeek:"[\u10ec\u10d8\u10dc\u10d0] dddd LT-\u10d6\u10d4",sameElse:"L"},relativeTime:{future:function(e){return/(\u10ec\u10d0\u10db\u10d8|\u10ec\u10e3\u10d7\u10d8|\u10e1\u10d0\u10d0\u10d7\u10d8|\u10ec\u10d4\u10da\u10d8)/.test(e)?e.replace(/\u10d8$/,"\u10e8\u10d8"):e+"\u10e8\u10d8"},past:function(e){return/(\u10ec\u10d0\u10db\u10d8|\u10ec\u10e3\u10d7\u10d8|\u10e1\u10d0\u10d0\u10d7\u10d8|\u10d3\u10e6\u10d4|\u10d7\u10d5\u10d4)/.test(e)?e.replace(/(\u10d8|\u10d4)$/,"\u10d8\u10e1 \u10ec\u10d8\u10dc"):/\u10ec\u10d4\u10da\u10d8/.test(e)?e.replace(/\u10ec\u10d4\u10da\u10d8$/,"\u10ec\u10da\u10d8\u10e1 \u10ec\u10d8\u10dc"):void 0},s:"\u10e0\u10d0\u10db\u10d3\u10d4\u10dc\u10d8\u10db\u10d4 \u10ec\u10d0\u10db\u10d8",ss:"%d \u10ec\u10d0\u10db\u10d8",m:"\u10ec\u10e3\u10d7\u10d8",mm:"%d \u10ec\u10e3\u10d7\u10d8",h:"\u10e1\u10d0\u10d0\u10d7\u10d8",hh:"%d \u10e1\u10d0\u10d0\u10d7\u10d8",d:"\u10d3\u10e6\u10d4",dd:"%d \u10d3\u10e6\u10d4",M:"\u10d7\u10d5\u10d4",MM:"%d \u10d7\u10d5\u10d4",y:"\u10ec\u10d4\u10da\u10d8",yy:"%d \u10ec\u10d4\u10da\u10d8"},dayOfMonthOrdinalParse:/0|1-\u10da\u10d8|\u10db\u10d4-\d{1,2}|\d{1,2}-\u10d4/,ordinal:function(e){return 0===e?e:1===e?e+"-\u10da\u10d8":e<20||e<=100&&e%20==0||e%100==0?"\u10db\u10d4-"+e:e+"-\u10d4"},week:{dow:1,doy:7}});var Ks={0:"-\u0448\u0456",1:"-\u0448\u0456",2:"-\u0448\u0456",3:"-\u0448\u0456",4:"-\u0448\u0456",5:"-\u0448\u0456",6:"-\u0448\u044b",7:"-\u0448\u0456",8:"-\u0448\u0456",9:"-\u0448\u044b",10:"-\u0448\u044b",20:"-\u0448\u044b",30:"-\u0448\u044b",40:"-\u0448\u044b",50:"-\u0448\u0456",60:"-\u0448\u044b",70:"-\u0448\u0456",80:"-\u0448\u0456",90:"-\u0448\u044b",100:"-\u0448\u0456"};l.defineLocale("kk",{months:"\u049b\u0430\u04a3\u0442\u0430\u0440_\u0430\u049b\u043f\u0430\u043d_\u043d\u0430\u0443\u0440\u044b\u0437_\u0441\u04d9\u0443\u0456\u0440_\u043c\u0430\u043c\u044b\u0440_\u043c\u0430\u0443\u0441\u044b\u043c_\u0448\u0456\u043b\u0434\u0435_\u0442\u0430\u043c\u044b\u0437_\u049b\u044b\u0440\u043a\u04af\u0439\u0435\u043a_\u049b\u0430\u0437\u0430\u043d_\u049b\u0430\u0440\u0430\u0448\u0430_\u0436\u0435\u043b\u0442\u043e\u049b\u0441\u0430\u043d".split("_"),monthsShort:"\u049b\u0430\u04a3_\u0430\u049b\u043f_\u043d\u0430\u0443_\u0441\u04d9\u0443_\u043c\u0430\u043c_\u043c\u0430\u0443_\u0448\u0456\u043b_\u0442\u0430\u043c_\u049b\u044b\u0440_\u049b\u0430\u0437_\u049b\u0430\u0440_\u0436\u0435\u043b".split("_"),weekdays:"\u0436\u0435\u043a\u0441\u0435\u043d\u0431\u0456_\u0434\u04af\u0439\u0441\u0435\u043d\u0431\u0456_\u0441\u0435\u0439\u0441\u0435\u043d\u0431\u0456_\u0441\u04d9\u0440\u0441\u0435\u043d\u0431\u0456_\u0431\u0435\u0439\u0441\u0435\u043d\u0431\u0456_\u0436\u04b1\u043c\u0430_\u0441\u0435\u043d\u0431\u0456".split("_"),weekdaysShort:"\u0436\u0435\u043a_\u0434\u04af\u0439_\u0441\u0435\u0439_\u0441\u04d9\u0440_\u0431\u0435\u0439_\u0436\u04b1\u043c_\u0441\u0435\u043d".split("_"),weekdaysMin:"\u0436\u043a_\u0434\u0439_\u0441\u0439_\u0441\u0440_\u0431\u0439_\u0436\u043c_\u0441\u043d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0411\u04af\u0433\u0456\u043d \u0441\u0430\u0493\u0430\u0442] LT",nextDay:"[\u0415\u0440\u0442\u0435\u04a3 \u0441\u0430\u0493\u0430\u0442] LT",nextWeek:"dddd [\u0441\u0430\u0493\u0430\u0442] LT",lastDay:"[\u041a\u0435\u0448\u0435 \u0441\u0430\u0493\u0430\u0442] LT",lastWeek:"[\u04e8\u0442\u043a\u0435\u043d \u0430\u043f\u0442\u0430\u043d\u044b\u04a3] dddd [\u0441\u0430\u0493\u0430\u0442] LT",sameElse:"L"},relativeTime:{future:"%s \u0456\u0448\u0456\u043d\u0434\u0435",past:"%s \u0431\u04b1\u0440\u044b\u043d",s:"\u0431\u0456\u0440\u043d\u0435\u0448\u0435 \u0441\u0435\u043a\u0443\u043d\u0434",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434",m:"\u0431\u0456\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u0431\u0456\u0440 \u0441\u0430\u0493\u0430\u0442",hh:"%d \u0441\u0430\u0493\u0430\u0442",d:"\u0431\u0456\u0440 \u043a\u04af\u043d",dd:"%d \u043a\u04af\u043d",M:"\u0431\u0456\u0440 \u0430\u0439",MM:"%d \u0430\u0439",y:"\u0431\u0456\u0440 \u0436\u044b\u043b",yy:"%d \u0436\u044b\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0448\u0456|\u0448\u044b)/,ordinal:function(e){return e+(Ks[e]||Ks[e%10]||Ks[100<=e?100:null])},week:{dow:1,doy:7}});var Zs={1:"\u17e1",2:"\u17e2",3:"\u17e3",4:"\u17e4",5:"\u17e5",6:"\u17e6",7:"\u17e7",8:"\u17e8",9:"\u17e9",0:"\u17e0"},$s={"\u17e1":"1","\u17e2":"2","\u17e3":"3","\u17e4":"4","\u17e5":"5","\u17e6":"6","\u17e7":"7","\u17e8":"8","\u17e9":"9","\u17e0":"0"};l.defineLocale("km",{months:"\u1798\u1780\u179a\u17b6_\u1780\u17bb\u1798\u17d2\u1797\u17c8_\u1798\u17b8\u1793\u17b6_\u1798\u17c1\u179f\u17b6_\u17a7\u179f\u1797\u17b6_\u1798\u17b7\u1790\u17bb\u1793\u17b6_\u1780\u1780\u17d2\u1780\u178a\u17b6_\u179f\u17b8\u17a0\u17b6_\u1780\u1789\u17d2\u1789\u17b6_\u178f\u17bb\u179b\u17b6_\u179c\u17b7\u1785\u17d2\u1786\u17b7\u1780\u17b6_\u1792\u17d2\u1793\u17bc".split("_"),monthsShort:"\u1798\u1780\u179a\u17b6_\u1780\u17bb\u1798\u17d2\u1797\u17c8_\u1798\u17b8\u1793\u17b6_\u1798\u17c1\u179f\u17b6_\u17a7\u179f\u1797\u17b6_\u1798\u17b7\u1790\u17bb\u1793\u17b6_\u1780\u1780\u17d2\u1780\u178a\u17b6_\u179f\u17b8\u17a0\u17b6_\u1780\u1789\u17d2\u1789\u17b6_\u178f\u17bb\u179b\u17b6_\u179c\u17b7\u1785\u17d2\u1786\u17b7\u1780\u17b6_\u1792\u17d2\u1793\u17bc".split("_"),weekdays:"\u
5114917a2\u17b6\u1791\u17b7\u178f\u17d2\u1799_\u1785\u17d0\u1793\u17d2\u1791_\u17a2\u1784\u17d2\u1782\u17b6\u179a_\u1796\u17bb\u1792_\u1796\u17d2\u179a\u17a0\u179f\u17d2\u1794\u178f\u17b7\u17cd_\u179f\u17bb\u1780\u17d2\u179a_\u179f\u17c5\u179a\u17cd".split("_"),weekdaysShort:"\u17a2\u17b6_\u1785_\u17a2_\u1796_\u1796\u17d2\u179a_\u179f\u17bb_\u179f".split("_"),weekdaysMin:"\u17a2\u17b6_\u1785_\u17a2_\u1796_\u1796\u17d2\u179a_\u179f\u17bb_\u179f".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/\u1796\u17d2\u179a\u17b9\u1780|\u179b\u17d2\u1784\u17b6\u1785/,isPM:function(e){return"\u179b\u17d2\u1784\u17b6\u1785"===e},meridiem:function(e,a,t){return e<12?"\u1796\u17d2\u179a\u17b9\u1780":"\u179b\u17d2\u1784\u17b6\u1785"},calendar:{sameDay:"[\u1790\u17d2\u1784\u17c3\u1793\u17c1\u17c7 \u1798\u17c9\u17c4\u1784] LT",nextDay:"[\u179f\u17d2\u17a2\u17c2\u1780 \u1798\u17c9\u17c4\u1784] LT",nextWeek:"dddd [\u1798\u17c9\u17c4\u1784] LT",lastDay:"[\u1798\u17d2\u179f\u17b7\u179b\u1798\u17b7\u1789 \u1798\u17c9\u17c4\u1784] LT",lastWeek:"dddd [\u179f\u1794\u17d2\u178f\u17b6\u17a0\u17cd\u1798\u17bb\u1793] [\u1798\u17c9\u17c4\u1784] LT",sameElse:"L"},relativeTime:{future:"%s\u1791\u17c0\u178f",past:"%s\u1798\u17bb\u1793",s:"\u1794\u17c9\u17bb\u1793\u17d2\u1798\u17b6\u1793\u179c\u17b7\u1793\u17b6\u1791\u17b8",ss:"%d \u179c\u17b7\u1793\u17b6\u1791\u17b8",m:"\u1798\u17bd\u1799\u1793\u17b6\u1791\u17b8",mm:"%d \u1793\u17b6\u1791\u17b8",h:"\u1798\u17bd\u1799\u1798\u17c9\u17c4\u1784",hh:"%d \u1798\u17c9\u17c4\u1784",d:"\u1798\u17bd\u1799\u1790\u17d2\u1784\u17c3",dd:"%d \u1790\u17d2\u1784\u17c3",M:"\u1798\u17bd\u1799\u1781\u17c2",MM:"%d \u1781\u17c2",y:"\u1798\u17bd\u1799\u1786\u17d2\u1793\u17b6\u17c6",yy:"%d \u1786\u17d2\u1793\u17b6\u17c6"},dayOfMonthOrdinalParse:/\u1791\u17b8\d{1,2}/,ordinal:"\u1791\u17b8%d",preparse:function(e){return e.replace(/[\u17e1\u17e2\u17e3\u17e4\u17e5\u17e6\u17e7\u17e8\u17e9\u17e0]/g,function(e){return $s[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return Zs[e]})},week:{dow:1,doy:4}});var Bs={1:"\u0ce7",2:"\u0ce8",3:"\u0ce9",4:"\u0cea",5:"\u0ceb",6:"\u0cec",7:"\u0ced",8:"\u0cee",9:"\u0cef",0:"\u0ce6"},qs={"\u0ce7":"1","\u0ce8":"2","\u0ce9":"3","\u0cea":"4","\u0ceb":"5","\u0cec":"6","\u0ced":"7","\u0cee":"8","\u0cef":"9","\u0ce6":"0"};l.defineLocale("kn",{months:"\u0c9c\u0ca8\u0cb5\u0cb0\u0cbf_\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cbf_\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd_\u0c8f\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd_\u0cae\u0cc6\u0cd5_\u0c9c\u0cc2\u0ca8\u0ccd_\u0c9c\u0cc1\u0cb2\u0cc6\u0cd6_\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd_\u0cb8\u0cc6\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd_\u0c85\u0c95\u0ccd\u0c9f\u0cc6\u0cc2\u0cd5\u0cac\u0cb0\u0ccd_\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd_\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd".split("_"),monthsShort:"\u0c9c\u0ca8_\u0cab\u0cc6\u0cac\u0ccd\u0cb0_\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd_\u0c8f\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd_\u0cae\u0cc6\u0cd5_\u0c9c\u0cc2\u0ca8\u0ccd_\u0c9c\u0cc1\u0cb2\u0cc6\u0cd6_\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd_\u0cb8\u0cc6\u0caa\u0ccd\u0c9f\u0cc6\u0c82_\u0c85\u0c95\u0ccd\u0c9f\u0cc6\u0cc2\u0cd5_\u0ca8\u0cb5\u0cc6\u0c82_\u0ca1\u0cbf\u0cb8\u0cc6\u0c82".split("_"),monthsParseExact:!0,weekdays:"\u0cad\u0cbe\u0ca8\u0cc1\u0cb5\u0cbe\u0cb0_\u0cb8\u0cc6\u0cc2\u0cd5\u0cae\u0cb5\u0cbe\u0cb0_\u0cae\u0c82\u0c97\u0cb3\u0cb5\u0cbe\u0cb0_\u0cac\u0cc1\u0ca7\u0cb5\u0cbe\u0cb0_\u0c97\u0cc1\u0cb0\u0cc1\u0cb5\u0cbe\u0cb0_\u0cb6\u0cc1\u0c95\u0ccd\u0cb0\u0cb5\u0cbe\u0cb0_\u0cb6\u0ca8\u0cbf\u0cb5\u0cbe\u0cb0".split("_"),weekdaysShort:"\u0cad\u0cbe\u0ca8\u0cc1_\u0cb8\u0cc6\u0cc2\u0cd5\u0cae_\u0cae\u0c82\u0c97\u0cb3_\u0cac\u0cc1\u0ca7_\u0c97\u0cc1\u0cb0\u0cc1_\u0cb6\u0cc1\u0c95\u0ccd\u0cb0_\u0cb6\u0ca8\u0cbf".split("_"),weekdaysMin:"\u0cad\u0cbe_\u0cb8\u0cc6\u0cc2\u0cd5_\u0cae\u0c82_\u0cac\u0cc1_\u0c97\u0cc1_\u0cb6\u0cc1_\u0cb6".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0c87\u0c82\u0ca6\u0cc1] LT",nextDay:"[\u0ca8\u0cbe\u0cb3\u0cc6] LT",nextWeek:"dddd, LT",lastDay:"[\u0ca8\u0cbf\u0ca8\u0ccd\u0ca8\u0cc6] LT",lastWeek:"[\u0c95\u0cc6\u0cc2\u0ca8\u0cc6\u0caf] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0ca8\u0c82\u0ca4\u0cb0",past:"%s \u0cb9\u0cbf\u0c82\u0ca6\u0cc6",s:"\u0c95\u0cc6\u0cb2\u0cb5\u0cc1 \u0c95\u0ccd\u0cb7\u0ca3\u0c97\u0cb3\u0cc1",ss:"%d \u0cb8\u0cc6\u0c95\u0cc6\u0c82\u0ca1\u0cc1\u0c97\u0cb3\u0cc1",m:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca8\u0cbf\u0cae\u0cbf\u0cb7",mm:"%d \u0ca8\u0cbf\u0cae\u0cbf\u0cb7",h:"\u0c92\u0c82\u0ca6\u0cc1 \u0c97\u0c82\u0c9f\u0cc6",hh:"%
51149d \u0c97\u0c82\u0c9f\u0cc6",d:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca6\u0cbf\u0ca8",dd:"%d \u0ca6\u0cbf\u0ca8",M:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca4\u0cbf\u0c82\u0c97\u0cb3\u0cc1",MM:"%d \u0ca4\u0cbf\u0c82\u0c97\u0cb3\u0cc1",y:"\u0c92\u0c82\u0ca6\u0cc1 \u0cb5\u0cb0\u0ccd\u0cb7",yy:"%d \u0cb5\u0cb0\u0ccd\u0cb7"},preparse:function(e){return e.replace(/[\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0ce6]/g,function(e){return qs[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return Bs[e]})},meridiemParse:/\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf|\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6|\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8|\u0cb8\u0c82\u0c9c\u0cc6/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf"===a?e<4?e:e+12:"\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6"===a?e:"\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8"===a?10<=e?e:e+12:"\u0cb8\u0c82\u0c9c\u0cc6"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf":e<10?"\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6":e<17?"\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8":e<20?"\u0cb8\u0c82\u0c9c\u0cc6":"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf"},dayOfMonthOrdinalParse:/\d{1,2}(\u0ca8\u0cc6\u0cd5)/,ordinal:function(e){return e+"\u0ca8\u0cc6\u0cd5"},week:{dow:0,doy:6}}),l.defineLocale("ko",{months:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),monthsShort:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),weekdays:"\uc77c\uc694\uc77c_\uc6d4\uc694\uc77c_\ud654\uc694\uc77c_\uc218\uc694\uc77c_\ubaa9\uc694\uc77c_\uae08\uc694\uc77c_\ud1a0\uc694\uc77c".split("_"),weekdaysShort:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),weekdaysMin:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY\ub144 MMMM D\uc77c",LLL:"YYYY\ub144 MMMM D\uc77c A h:mm",LLLL:"YYYY\ub144 MMMM D\uc77c dddd A h:mm",l:"YYYY.MM.DD.",ll:"YYYY\ub144 MMMM D\uc77c",lll:"YYYY\ub144 MMMM D\uc77c A h:mm",llll:"YYYY\ub144 MMMM D\uc77c dddd A h:mm"},calendar:{sameDay:"\uc624\ub298 LT",nextDay:"\ub0b4\uc77c LT",nextWeek:"dddd LT",lastDay:"\uc5b4\uc81c LT",lastWeek:"\uc9c0\ub09c\uc8fc dddd LT",sameElse:"L"},relativeTime:{future:"%s \ud6c4",past:"%s \uc804",s:"\uba87 \ucd08",ss:"%d\ucd08",m:"1\ubd84",mm:"%d\ubd84",h:"\ud55c \uc2dc\uac04",hh:"%d\uc2dc\uac04",d:"\ud558\ub8e8",dd:"%d\uc77c",M:"\ud55c \ub2ec",MM:"%d\ub2ec",y:"\uc77c \ub144",yy:"%d\ub144"},dayOfMonthOrdinalParse:/\d{1,2}(\uc77c|\uc6d4|\uc8fc)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"\uc77c";case"M":return e+"\uc6d4";case"w":case"W":return e+"\uc8fc";default:return e}},meridiemParse:/\uc624\uc804|\uc624\ud6c4/,isPM:function(e){return"\uc624\ud6c4"===e},meridiem:function(e,a,t){return e<12?"\uc624\uc804":"\uc624\ud6c4"}});var Qs={0:"-\u0447\u04af",1:"-\u0447\u0438",2:"-\u0447\u0438",3:"-\u0447\u04af",4:"-\u0447\u04af",5:"-\u0447\u0438",6:"-\u0447\u044b",7:"-\u0447\u0438",8:"-\u0447\u0438",9:"-\u0447\u0443",10:"-\u0447\u0443",20:"-\u0447\u044b",30:"-\u0447\u0443",40:"-\u0447\u044b",50:"-\u0447\u04af",60:"-\u0447\u044b",70:"-\u0447\u0438",80:"-\u0447\u0438",90:"-\u0447\u0443",100:"-\u0447\u04af"};function Xs(e,a,t,s){var n={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return a?n[t][0]:n[t][1]}function en(e){if(e=parseInt(e,10),isNaN(e))return!1;if(e<0)return!0;if(e<10)return 4<=e&&e<=7;if(e<100){var a=e%10;return en(0===a?e/10:a)}if(e<1e4){for(;10<=e;)e/=10;return en(e)}return en(e/=1e3)}l.defineLocale("ky",{months:"\u044f\u043d\u0432\u0430\u0440\u044c_\u0444\u0435\u0432\u0440\u0430\u043b\u044c_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b\u044c_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c_\u043e\u043a\u0442\u044f\u0431\u0440\u044c_\u043d\u043e\u044f\u0431\u0440\u044c_\u0434\u0435\u043a\u0430\u0431\u0440\u044c".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u0416\u0435\u043a\u0448\u0435\u043c\u0431\u0438_\u0414\u04af\u0439\u0448\u04e9\u043c\u0431\u04af_\u0428\u0435\u0439\u0448\u0435\u043c\u0431\u0438_\u0428\u0430\u0440\u0448\u0435\u043c\u0431\u0438_\u0411\u0435\u0439\u0448\u0435\u043c\u0431\u0438_\u0416\u0443\u043c\u0430_\u0418\u0448\u0435\u043c\u0431\u0438".split("_"),weekdaysShort:"\u0416\u0435\u043a_\u0414\u04af\u0439_\u0428\u0435\u0439_\u0428\u0430\u0440_\u0411\u0435\u0439_\u0416\u0443\u043c_\u0418\u0448\u0435".split("_"),weekdaysMin:"\u0416\u043a_\u0414\u0439_\u0428\u0439_\u0428\u0440_\u0411\u0439_\u0416\u043c_\u0418\u0448".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0411\u04af\u0433\u04af\u043d \u0441\u0430\u0430\u0442] LT",nextDay:"[\u042d\u0440\u0442\u0435\u04a3 \u0441\u0430\u0430\u0442] LT",nextWeek:"dddd [\u0441\u0430\u0430\u0442] LT",lastDay:"[\u041a\u0435\u0447\u0435 \u0441\u0430\u0430\u0442] LT",lastWeek:"[\u04e8\u0442\u043a\u0435\u043d \u0430\u043f\u0442\u0430\u043d\u044b\u043d] dddd [\u043a\u04af\u043d\u04af] [\u0441\u0430\u0430\u0442] LT",sameElse:"L"},relativeTime:{future:"%s \u0438\u0447\u0438\u043d\u0434\u0435",past:"%s \u043c\u0443\u0440\u0443\u043d",s:"\u0431\u0438\u0440\u043d\u0435\u0447\u0435 \u0441\u0435\u043a\u0443\u043d\u0434",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434",m:"\u0431\u0438\u0440 \u043c\u04af\u043d\u04e9\u0442",mm:"%d \u043c\u04af\u043d\u04e9\u0442",h:"\u0431\u0438\u0440 \u0441\u0430\u0430\u0442",hh:"%d \u0441\u0430\u0430\u0442",d:"\u0431\u0438\u0440 \u043a\u04af\u043d",dd:"%d \u043a\u04af\u043d",M:"\u0431\u0438\u0440 \u0430\u0439",MM:"%d \u0430\u0439",y:"\u0431\u0438\u0440 \u0436\u044b\u043b",yy:"%d \u0436\u044b\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0447\u0438|\u0447\u044b|\u0447\u04af|\u0447\u0443)/,ordinal:function(e){return e+(Qs[e]||Qs[e%10]||Qs[100<=e?100:null])},week:{dow:1,doy:7}}),l.defineLocale("lb",{months:"Januar_Februar_M\xe4erz_Abr\xebll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonndeg_M\xe9indeg_D\xebnschdeg_M\xebttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._M\xe9._D\xeb._M\xeb._Do._Fr._Sa.".split("_"),weekdaysMin:"So_M\xe9_D\xeb_M\xeb_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm [Auer]",LLLL:"dddd, D. MMMM YYYY H:mm [Auer]"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[G\xebschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:function(e){return en(e.substr(0,e.indexOf(" ")))?"a "+e:"an "+e},past:function(e){return en(e.substr(0,e.indexOf(" ")))?"viru "+e:"virun "+e},s:"e puer Sekonnen",ss:"%d Sekonnen",m:Xs,mm:"%d Minutten",h:Xs,hh:"%d Stonnen",d:Xs,dd:"%d Deeg",M:Xs,MM:"%d M\xe9int",y:Xs,yy:"%d Joer"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("lo",{months:"\u0ea1\u0eb1\u0e87\u0e81\u0ead\u0e99_\u0e81\u0eb8\u0ea1\u0e9e\u0eb2_\u0ea1\u0eb5\u0e99\u0eb2_\u0ec0\u0ea1\u0eaa\u0eb2_\u0e9e\u0eb6\u0e94\u0eaa\u0eb0\u0e9e\u0eb2_\u0ea1\u0eb4\u0e96\u0eb8\u0e99\u0eb2_\u0e81\u0ecd\u0ea5\u0eb0\u0e81\u0ebb\u0e94_\u0eaa\u0eb4\u0e87\u0eab\u0eb2_\u0e81\u0eb1\u0e99\u0e8d\u0eb2_\u0e95\u0eb8\u0ea5\u0eb2_\u0e9e\u0eb0\u0e88\u0eb4\u0e81_\u0e97\u0eb1\u0e99\u0ea7\u0eb2".split("_"),monthsShort:"\u0ea1\u0eb1\u0e87\u0e81\u0ead\u0e99_\u0e81\u0eb8\u0ea1\u0e9e\u0eb2_\u0ea1\u0eb5\u0e99\u0eb2_\u0ec0\u0ea1\u0eaa\u0eb2_\u0e9e\u0eb6\u0e94\u0eaa\u0eb0\u0e9e\u0eb2_\u0ea1\u0eb4\u0e96\u0eb8\u0e99\u0eb2_\u0e81\u0ecd\u0ea5\u0eb0\u0e81\u0ebb\u0e94_\u0eaa\u0eb4\u0e87\u0eab\u0eb2_\u0e81\u0eb1\u0e99\u0e8d\u0eb2_\u0e95\u0eb8\u0ea5\u0eb2_\u0e9e\u0eb0\u0e88\u0eb4\u0e81_\u0e97\u0eb1\u0e99\u0ea7\u0eb2".split("_"),weekdays:"\u0ead\u0eb2\u0e97\u0eb4\u0e94_\u0e88\u0eb1\u0e99_\u0ead\u0eb1\u0e87\u0e84\u0eb2\u0e99_\u0e9e\u0eb8\u0e94_\u0e9e\u0eb0\u0eab\u0eb1\u0e94_\u0eaa\u0eb8\u0e81_\u0ec0\u0eaa\u0ebb\u0eb2".split("_"),weekdaysShort:"\u0e97\u0eb4\u0e94_\u0e88\u0eb1\u0e99_\u0ead\u0eb1\u0e87\u0e84\u0eb2\u0e99_\u0e9e\u0eb8\u0e94_\u0e9e\u0eb0\u0eab\u0eb1\u0e94_\u0eaa\u0eb8\u0e81_\u0ec0\u0eaa\u0ebb\u0eb2".split("_"),weekdaysMin:"\u0e97_\u0e88_\u0ead\u0e84_\u0e9e_\u0e9e\u0eab_\u0eaa\u0e81_\u0eaa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"\u0ea7\u0eb1\u0e99dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0e95\u0ead\u0e99\u0ec0\u0e8a\u0ebb\u0ec9\u0eb2|\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87/,isPM:function(e){return"\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87"===e},meridiem:function(e,a,t){return e<12?"\u0e95\u0ead\u0e99\u0ec0\u0e8a\u0ebb\u0ec9\u0eb2":"\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87"},calendar:{sameDay:"[\u0ea1\u0eb7\u0ec9\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",nextDay:"[\u0ea1\u0eb7\u0ec9\u0ead\u0eb7\u0ec8\u0e99\u0ec0\u0ea7\u0ea5\u0eb2] LT",nextWeek:"[\u0ea7\u0eb1\u0e99]dddd[\u0edc\u0ec9\u0eb2\u0ec0\u0ea7\u0ea5\u0eb2] LT",lastDay:"[\u0ea1\u0eb7\u0ec9\u0ea7\u0eb2\u0e99\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",lastWeek:"[\u0ea7\u0eb1\u0e99]dddd[\u0ec1\u0ea5\u0ec9\u0ea7\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",sameElse:"L"},relativeTime:{future:"\u0ead\u0eb5\u0e81 %s",past:"%s\u0e9c\u0ec8\u0eb2\u0e99\u0ea1\u0eb2",s:"\u0e9a\u0ecd\u0ec8\u0ec0\u0e97\u0ebb\u0ec8\u0eb2\u0ec3\u0e94\u0ea7\u0eb4\u0e99\u0eb2\u0e97\u0eb5",ss:"%d \u0ea7\u0eb4\u0e99\u0eb2\u0e97\u0eb5",m:"1 \u0e99\u0eb2\u0e97\u0eb5",mm:"%d \u0e99\u0eb2\u0e97\u0eb5",h:"1 \u0e8a\u0ebb\u0ec8\u0ea7\u0ec2\u0ea1\u0e87",hh:"%
51149d \u0e8a\u0ebb\u0ec8\u0ea7\u0ec2\u0ea1\u0e87",d:"1 \u0ea1\u0eb7\u0ec9",dd:"%d \u0ea1\u0eb7\u0ec9",M:"1 \u0ec0\u0e94\u0eb7\u0ead\u0e99",MM:"%d \u0ec0\u0e94\u0eb7\u0ead\u0e99",y:"1 \u0e9b\u0eb5",yy:"%d \u0e9b\u0eb5"},dayOfMonthOrdinalParse:/(\u0e97\u0eb5\u0ec8)\d{1,2}/,ordinal:function(e){return"\u0e97\u0eb5\u0ec8"+e}});var an={ss:"sekund\u0117_sekund\u017ei\u0173_sekundes",m:"minut\u0117_minut\u0117s_minut\u0119",mm:"minut\u0117s_minu\u010di\u0173_minutes",h:"valanda_valandos_valand\u0105",hh:"valandos_valand\u0173_valandas",d:"diena_dienos_dien\u0105",dd:"dienos_dien\u0173_dienas",M:"m\u0117nuo_m\u0117nesio_m\u0117nes\u012f",MM:"m\u0117nesiai_m\u0117nesi\u0173_m\u0117nesius",y:"metai_met\u0173_metus",yy:"metai_met\u0173_metus"};function tn(e,a,t,s){return a?nn(t)[0]:s?nn(t)[1]:nn(t)[2]}function sn(e){return e%10==0||10<e&&e<20}function nn(e){return an[e].split("_")}function dn(e,a,t,s){var n=e+" ";return 1===e?n+tn(0,a,t[0],s):a?n+(sn(e)?nn(t)[1]:nn(t)[0]):s?n+nn(t)[1]:n+(sn(e)?nn(t)[1]:nn(t)[2])}l.defineLocale("lt",{months:{format:"sausio_vasario_kovo_baland\u017eio_gegu\u017e\u0117s_bir\u017eelio_liepos_rugpj\u016b\u010dio_rugs\u0117jo_spalio_lapkri\u010dio_gruod\u017eio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegu\u017e\u0117_bir\u017eelis_liepa_rugpj\u016btis_rugs\u0117jis_spalis_lapkritis_gruodis".split("_"),isFormat:/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadien\u012f_pirmadien\u012f_antradien\u012f_tre\u010diadien\u012f_ketvirtadien\u012f_penktadien\u012f_\u0161e\u0161tadien\u012f".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_tre\u010diadienis_ketvirtadienis_penktadienis_\u0161e\u0161tadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_\u0160e\u0161".split("_"),weekdaysMin:"S_P_A_T_K_Pn_\u0160".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[\u0160iandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Pra\u0117jus\u012f] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prie\u0161 %s",s:function(e,a,t,s){return a?"kelios sekund\u0117s":s?"keli\u0173 sekund\u017ei\u0173":"kelias sekundes"},ss:dn,m:tn,mm:dn,h:tn,hh:dn,d:tn,dd:dn,M:tn,MM:dn,y:tn,yy:dn},dayOfMonthOrdinalParse:/\d{1,2}-oji/,ordinal:function(e){return e+"-oji"},week:{dow:1,doy:4}});
vendor: 5,850 bytes, line 51149
51149var rn={ss:"sekundes_sekund\u0113m_sekunde_sekundes".split("_"),m:"min\u016btes_min\u016bt\u0113m_min\u016bte_min\u016btes".split("_"),mm:"min\u016btes_min\u016bt\u0113m_min\u016bte_min\u016btes".split("_"),h:"stundas_stund\u0101m_stunda_stundas".split("_"),hh:"stundas_stund\u0101m_stunda_stundas".split("_"),d:"dienas_dien\u0101m_diena_dienas".split("_"),dd:"dienas_dien\u0101m_diena_dienas".split("_"),M:"m\u0113ne\u0161a_m\u0113ne\u0161iem_m\u0113nesis_m\u0113ne\u0161i".split("_"),MM:"m\u0113ne\u0161a_m\u0113ne\u0161iem_m\u0113nesis_m\u0113ne\u0161i".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")};function _n(e,a,t){return t?a%10==1&&a%100!=11?e[2]:e[3]:a%10==1&&a%100!=11?e[0]:e[1]}function on(e,a,t){return e+" "+_n(rn[t],e,a)}function mn(e,a,t){return _n(rn[t],e,a)}l.defineLocale("lv",{months:"janv\u0101ris_febru\u0101ris_marts_apr\u012blis_maijs_j\u016bnijs_j\u016blijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_j\u016bn_j\u016bl_aug_sep_okt_nov_dec".split("_"),weekdays:"sv\u0113tdiena_pirmdiena_otrdiena_tre\u0161diena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[\u0160odien pulksten] LT",nextDay:"[R\u012bt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pag\u0101ju\u0161\u0101] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"p\u0113c %s",past:"pirms %s",s:function(e,a){return a?"da\u017eas sekundes":"da\u017e\u0101m sekund\u0113m"},ss:on,m:mn,mm:on,h:mn,hh:on,d:mn,dd:on,M:mn,MM:on,y:mn,yy:on},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});var un={words:{ss:["sekund","sekunda","sekundi"],m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mjesec","mjeseca","mjeseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(e,a){return 1===e?a[0]:2<=e&&e<=4?a[1]:a[2]},translate:function(e,a,t){var s=un.words[t];return 1===t.length?a?s[0]:s[1]:e+" "+un.correctGrammaticalCase(e,s)}};function ln(e,a,t,s){switch(t){case"s":return a?"\u0445\u044d\u0434\u0445\u044d\u043d \u0441\u0435\u043a\u0443\u043d\u0434":"\u0445\u044d\u0434\u0445\u044d\u043d \u0441\u0435\u043a\u0443\u043d\u0434\u044b\u043d";case"ss":return e+(a?" \u0441\u0435\u043a\u0443\u043d\u0434":" \u0441\u0435\u043a\u0443\u043d\u0434\u044b\u043d");case"m":case"mm":return e+(a?" \u043c\u0438\u043d\u0443\u0442":" \u043c\u0438\u043d\u0443\u0442\u044b\u043d");case"h":case"hh":return e+(a?" \u0446\u0430\u0433":" \u0446\u0430\u0433\u0438\u0439\u043d");case"d":case"dd":return e+(a?" \u04e9\u0434\u04e9\u0440":" \u04e9\u0434\u0440\u0438\u0439\u043d");case"M":case"MM":return e+(a?" \u0441\u0430\u0440":" \u0441\u0430\u0440\u044b\u043d");case"y":case"yy":return e+(a?" \u0436\u0438\u043b":" \u0436\u0438\u043b\u0438\u0439\u043d");default:return e}}l.defineLocale("me",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sjutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010de u] LT",lastWeek:function(){return["[pro\u0161le] [nedjelje] [u] LT","[pro\u0161log] [ponedjeljka] [u] LT","[pro\u0161log] [utorka] [u] LT","[pro\u0161le] [srijede] [u] LT","[pro\u0161log] [\u010detvrtka] [u] LT","[pro\u0161log] [petka] [u] LT","[pro\u0161le] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"nekoliko sekundi",ss:un.translate,m:un.translate,mm:un.translate,h:un.translate,hh:un.translate,d:"dan",dd:un.translate,M:"mjesec",MM:un.translate,y:"godinu",yy:un.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}}),l.defineLocale("mi",{months:"Kohi-t\u0101te_Hui-tanguru_Pout\u016b-te-rangi_Paenga-wh\u0101wh\u0101_Haratua_Pipiri_H\u014dngoingoi_Here-turi-k\u014dk\u0101_Mahuru_Whiringa-\u0101-nuku_Whiringa-\u0101-rangi_Hakihea".split("_"),monthsShort:"Kohi_Hui_Pou_Pae_Hara_Pipi_H\u014dngoi_Here_Mahu_Whi-nu_Whi-ra_Haki".split("_"),monthsRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,weekdays:"R\u0101tapu_Mane_T\u016brei_Wenerei_T\u0101ite_Paraire_H\u0101tarei".split("_"),weekdaysShort:"Ta_Ma_T\u016b_We_T\u0101i_Pa_H\u0101".split("_"),weekdaysMin:"Ta_Ma_T\u016b_We_T\u0101i_Pa_H\u0101".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [i] HH:mm",LLLL:"dddd, D MMMM YYYY [i] HH:mm"},calendar:{sameDay:"[i teie mahana, i] LT",nextDay:"[apopo i] LT",nextWeek:"dddd [i] LT",lastDay:"[inanahi i] LT",lastWeek:"dddd [whakamutunga i] LT",sameElse:"L"},relativeTime:{future:"i roto i %s",past:"%s i mua",s:"te h\u0113kona ruarua",ss:"%d h\u0113kona",m:"he meneti",mm:"%d meneti",h:"te haora",hh:"%
51149d haora",d:"he ra",dd:"%d ra",M:"he marama",MM:"%d marama",y:"he tau",yy:"%d tau"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}}),l.defineLocale("mk",{months:"\u0458\u0430\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0458_\u0458\u0443\u043d\u0438_\u0458\u0443\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u0458\u0430\u043d_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u0430_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0440\u0442\u043e\u043a_\u043f\u0435\u0442\u043e\u043a_\u0441\u0430\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u0435_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u0430\u0431".split("_"),weekdaysMin:"\u043de_\u043fo_\u0432\u0442_\u0441\u0440_\u0447\u0435_\u043f\u0435_\u0441a".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[\u0414\u0435\u043d\u0435\u0441 \u0432\u043e] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432\u043e] LT",nextWeek:"[\u0412\u043e] dddd [\u0432\u043e] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432\u043e] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0418\u0437\u043c\u0438\u043d\u0430\u0442\u0430\u0442\u0430] dddd [\u0432\u043e] LT";case 1:case 2:case 4:case 5:return"[\u0418\u0437\u043c\u0438\u043d\u0430\u0442\u0438\u043e\u0442] dddd [\u0432\u043e] LT"}},sameElse:"L"},relativeTime:{future:"\u043f\u043e\u0441\u043b\u0435 %s",past:"\u043f\u0440\u0435\u0434 %s",s:"\u043d\u0435\u043a\u043e\u043b\u043a\u0443 \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u0435\u043d\u0430",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0438",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0435\u0432|\u0435\u043d|\u0442\u0438|\u0432\u0438|\u0440\u0438|\u043c\u0438)/,ordinal:function(e){var a=e%10,t=e%100;return 0===e?e+"-\u0435\u0432":0===t?e+"-\u0435\u043d":10<t&&t<20?e+"-\u0442\u0438":1===a?e+"-\u0432\u0438":2===a?e+"-\u0440\u0438":7===a||8===a?e+"-\u043c\u0438":e+"-\u0442\u0438"},week:{dow:1,doy:7}}),l.defineLocale("ml",{months:"\u0d1c\u0d28\u0d41\u0d35\u0d30\u0d3f_\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41\u0d35\u0d30\u0d3f_\u0d2e\u0d3e\u0d7c\u0d1a\u0d4d\u0d1a\u0d4d_\u0d0f\u0d2a\u0d4d\u0d30\u0d3f\u0d7d_\u0d2e\u0d47\u0d2f\u0d4d_\u0d1c\u0d42\u0d7a_\u0d1c\u0d42\u0d32\u0d48_\u0d13\u0d17\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d4d_\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02\u0d2c\u0d7c_\u0d12\u0d15\u0d4d\u0d1f\u0d4b\u0d2c\u0d7c_\u0d28\u0d35\u0d02\u0d2c\u0d7c_\u0d21\u0d3f\u0d38\u0d02\u0d2c\u0d7c".split("_"),monthsShort:"\u0d1c\u0d28\u0d41._\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41._\u0d2e\u0d3e\u0d7c._\u0d0f\u0d2a\u0d4d\u0d30\u0d3f._\u0d2e\u0d47\u0d2f\u0d4d_\u0d1c\u0d42\u0d7a_\u0d1c\u0d42\u0d32\u0d48._\u0d13\u0d17._\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31._\u0d12\u0d15\u0d4d\u0d1f\u0d4b._\u0d28\u0d35\u0d02._\u0d21\u0d3f\u0d38\u0d02.".split("_"),monthsParseExact:!0,weekdays:"\u0d1e\u0d3e\u0d2f\u0d31\u0d3e\u0d34\u0d4d\u0d1a_\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d3e\u0d34\u0d4d\u0d1a_\u0d1a\u0d4a\u0d35\u0d4d\u0d35\u0d3e\u0d34\u0d4d\u0d1a_\u0d2c\u0d41\u0d27\u0d28\u0d3e\u0d34\u0d4d\u0d1a_\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d3e\u0d34\u0d4d\u0d1a_\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a_\u0d36\u0d28\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a".split("_"),weekdaysShort:"\u0d1e\u0d3e\u0d2f\u0d7c_\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d7e_\u0d1a\u0d4a\u0d35\u0d4d\u0d35_\u0d2c\u0d41\u0d27\u0d7b_\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d02_\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f_\u0d36\u0d28\u0d3f".split("_"),weekdaysMin:"\u0d1e\u0d3e_\u0d24\u0d3f_\u0d1a\u0d4a_\u0d2c\u0d41_\u0d35\u0d4d\u0d2f\u0d3e_\u0d35\u0d46_\u0d36".split("_"),longDateFormat:{LT:"A h:mm -\u0d28\u0d41",LTS:"A h:mm:ss -\u0d28\u0d41",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm -\u0d28\u0d41",LLLL:"dddd, D MMMM YYYY, A h:mm -\u0d28\u0d41"},calendar:{sameDay:"[\u0d07\u0d28\u0d4d\u0d28\u0d4d] LT",nextDay:"[\u0d28\u0d3e\u0d33\u0d46] LT",nextWeek:"dddd, LT",lastDay:"[\u0d07\u0d28\u0d4d\u0d28\u0d32\u0d46] LT",lastWeek:"[\u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d",past:"%s \u0d2e\u0d41\u0d7b\u0d2a\u0d4d",s:"\u0d05\u0d7d\u0d2a \u0d28\u0d3f\u0d2e\u0d3f\u0d37\u0d19\u0d4d\u0d19\u0d7e",ss:"%d \u0d38\u0d46\u0d15\u0d4d\u0d15\u0d7b\u0d21\u0d4d",m:"\u0d12\u0d30\u0d41 \u0d2e\u0d3f\u0d28\u0d3f\u0d31\u0d4d\u0d31\u0d4d",mm:"%d \u0d2e\u0d3f\u0d28\u0d3f\u0d31\u0d4d\u0d31\u0d4d",h:"\u0d12\u0d30\u0d41 \u0d2e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d42\u0d7c",hh:"%
51149d \u0d2e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d42\u0d7c",d:"\u0d12\u0d30\u0d41 \u0d26\u0d3f\u0d35\u0d38\u0d02",dd:"%d \u0d26\u0d3f\u0d35\u0d38\u0d02",M:"\u0d12\u0d30\u0d41 \u0d2e\u0d3e\u0d38\u0d02",MM:"%d \u0d2e\u0d3e\u0d38\u0d02",y:"\u0d12\u0d30\u0d41 \u0d35\u0d7c\u0d37\u0d02",yy:"%d \u0d35\u0d7c\u0d37\u0d02"},meridiemParse:/\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f|\u0d30\u0d3e\u0d35\u0d3f\u0d32\u0d46|\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d|\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02|\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f/i,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f"===a&&4<=e||"\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d"===a||"\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02"===a?e+12:e},meridiem:function(e,a,t){return e<4?"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f":e<12?"\u0d30\u0d3e\u0d35\u0d3f\u0d32\u0d46":e<17?"\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d":e<20?"\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02":"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f"}}),l.defineLocale("mn",{months:"\u041d\u044d\u0433\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0425\u043e\u0451\u0440\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0413\u0443\u0440\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0414\u04e9\u0440\u04e9\u0432\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0422\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0417\u0443\u0440\u0433\u0430\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0414\u043e\u043b\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u041d\u0430\u0439\u043c\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0415\u0441\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0410\u0440\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0410\u0440\u0432\u0430\u043d \u043d\u044d\u0433\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0410\u0440\u0432\u0430\u043d \u0445\u043e\u0451\u0440\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440".split("_"),monthsShort:"1 \u0441\u0430\u0440_2 \u0441\u0430\u0440_3 \u0441\u0430\u0440_4 \u0441\u0430\u0440_5 \u0441\u0430\u0440_6 \u0441\u0430\u0440_7 \u0441\u0430\u0440_8 \u0441\u0430\u0440_9 \u0441\u0430\u0440_10 \u0441\u0430\u0440_11 \u0441\u0430\u0440_12 \u0441\u0430\u0440".split("_"),monthsParseExact:!0,weekdays:"\u041d\u044f\u043c_\u0414\u0430\u0432\u0430\u0430_\u041c\u044f\u0433\u043c\u0430\u0440_\u041b\u0445\u0430\u0433\u0432\u0430_\u041f\u04af\u0440\u044d\u0432_\u0411\u0430\u0430\u0441\u0430\u043d_\u0411\u044f\u043c\u0431\u0430".split("_"),weekdaysShort:"\u041d\u044f\u043c_\u0414\u0430\u0432_\u041c\u044f\u0433_\u041b\u0445\u0430_\u041f\u04af\u0440_\u0411\u0430\u0430_\u0411\u044f\u043c".split("_"),weekdaysMin:"\u041d\u044f_\u0414\u0430_\u041c\u044f_\u041b\u0445_\u041f\u04af_\u0411\u0430_\u0411\u044f".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY \u043e\u043d\u044b MMMM\u044b\u043d D",LLL:"YYYY \u043e\u043d\u044b MMMM\u044b\u043d D HH:mm",LLLL:"dddd, YYYY \u043e\u043d\u044b MMMM\u044b\u043d D HH:mm"},meridiemParse:/\u04ae\u04e8|\u04ae\u0425/i,isPM:function(e){return"\u04ae\u0425"===e},meridiem:function(e,a,t){return e<12?"\u04ae\u04e8":"\u04ae\u0425"},calendar:{sameDay:"[\u04e8\u043d\u04e9\u04e9\u0434\u04e9\u0440] LT",nextDay:"[\u041c\u0430\u0440\u0433\u0430\u0430\u0448] LT",nextWeek:"[\u0418\u0440\u044d\u0445] dddd LT",lastDay:"[\u04e8\u0447\u0438\u0433\u0434\u04e9\u0440] LT",lastWeek:"[\u04e8\u043d\u0433\u04e9\u0440\u0441\u04e9\u043d] dddd LT",sameElse:"L"},relativeTime:{future:"%s \u0434\u0430\u0440\u0430\u0430",past:"%s \u04e9\u043c\u043d\u04e9",s:ln,ss:ln,m:ln,mm:ln,h:ln,hh:ln,d:ln,dd:ln,M:ln,MM:ln,y:ln,yy:ln},dayOfMonthOrdinalParse:/\d{1,2} \u04e9\u0434\u04e9\u0440/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+" \u04e9\u0434\u04e9\u0440";default:return e}}});var Mn={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},hn={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};function Ln(e,a,t,s){var n="";if(a)switch(t){case"s":n="\u0915\u093e\u0939\u0940 \u0938\u0947\u0915\u0902\u0926";break;case"ss":n="%d \u0938\u0947\u0915\u0902\u0926";break;case"m":n="\u090f\u0915 \u092e\u093f\u0928\u093f\u091f";break;case"mm":n="%d \u092e\u093f\u0928\u093f\u091f\u0947";break;case"h":n="\u090f\u0915 \u0924\u093e\u0938";break;case"hh":n="%d \u0924\u093e\u0938";break;case"d":n="\u090f\u0915 \u0926\u093f\u0935\u0938";break;case"dd":n="%d \u0926\u093f\u0935\u0938";break;case"M":n="\u090f\u0915 \u092e\u0939\u093f\u0928\u093e";break;case"MM":n="%d \u092e\u0939\u093f\u0928\u0947";break;case"y":n="\u090f\u0915 \u0935\u0930\u094d\u0937";break;case"yy":n="%d \u0935\u0930\u094d\u0937\u0947";break}else switch(t){case"s":n="\u0915\u093e\u0939\u0940 \u0938\u0947\u0915\u0902\u0926\u093e\u0902";break;case"ss":n="%d \u0938\u0947\u0915\u0902\u0926\u093e\u0902";break;case"m":n="\u090f\u0915\u093e \u092e\u093f\u0928\u093f\u091f\u093e";break;case"mm":n="%d \u092e\u093f\u0928\u093f\u091f\u093e\u0902";break;case"h":n="\u090f\u0915\u093e \u0924\u093e\u0938\u093e";break;case"hh":n="%d \u0924\u093e\u0938\u093e\u0902";break;case"d":n="\u090f\u0915\u093e \u0926\u093f\u0935\u0938\u093e";break;case"dd":n="%d \u0926\u093f\u0935\u0938\u093e\u0902";break;case"M":n="\u090f\u0915\u093e \u092e\u0939\u093f\u0928\u094d\u092f\u093e";break;case"MM":n="%d \u092e\u0939\u093f\u0928\u094d\u092f\u093e\u0902";break;case"y":n="\u090f\u0915\u093e \u0935\u0930\u094d\u0937\u093e";break;case"yy":n="%d \u0935\u0930\u094d\u0937\u093e\u0902";break}return n.replace(/%d/i,e)}l.defineLocale("mr",{months:"\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u090f\u092a\u094d\u0930\u093f\u0932_\u092e\u0947_\u091c\u0942\u0928_\u091c\u0941\u0932\u0948_\u0911\u0917\u0938\u094d\u091f_\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930_\u0911\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930_\u0921\u093f\u0938\u0947\u0902\u092c\u0930".split("_"),monthsShort:"\u091c\u093e\u0928\u0947._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a._\u090f\u092a\u094d\u0930\u093f._\u092e\u0947._\u091c\u0942\u0928._\u091c\u0941\u0932\u0948._\u0911\u0917._\u0938\u092a\u094d\u091f\u0947\u0902._\u0911\u0915\u094d\u091f\u094b._\u0928\u094b\u0935\u094d\u0939\u0947\u0902._\u0921\u093f\u0938\u0947\u0902.".split("_"),monthsParseExact:!0,weekdays:"\u0930\u0935\u093f\u0935\u093e\u0930_\u0938\u094b\u092e\u0935\u093e\u0930_\u092e\u0902\u0917\u0933\u0935\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u0917\u0941\u0930\u0942\u0935\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930_\u0936\u0928\u093f\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0930\u0935\u093f_\u0938\u094b\u092e_\u092e\u0902\u0917\u0933_\u092c\u0941\u0927_\u0917\u0941\u0930\u0942_\u0936\u0941\u0915\u094d\u0930_\u0936\u0928\u093f".split("_"),weekdaysMin:"\u0930_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u0917\u0941_\u0936\u0941_\u0936".split("_"),longDateFormat:{LT:"A h:mm \u0935\u093e\u091c\u0924\u093e",LTS:"A h:mm:ss \u0935\u093e\u091c\u0924\u093e",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0935\u093e\u091c\u0924\u093e",LLLL:"dddd, D MMMM YYYY, A h:mm \u0935\u093e\u091c\u0924\u093e"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u0909\u0926\u094d\u092f\u093e] LT",nextWeek:"dddd, LT",lastDay:"[\u0915\u093e\u0932] LT",lastWeek:"[\u092e\u093e\u0917\u0940\u0932] dddd, LT",sameElse:"L"},relativeTime:{future:"%s\u092e\u0927\u094d\u092f\u0947",past:"%s\u092a\u0942\u0930\u094d\u0935\u0940",s:Ln,ss:Ln,m:Ln,mm:Ln,h:Ln,hh:Ln,d:Ln,dd:Ln,M:Ln,MM:Ln,y:Ln,yy:Ln},preparse:function(e){return e.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(e){return hn[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return Mn[e]})},meridiemParse:/\u0930\u093e\u0924\u094d\u0930\u0940|\u0938\u0915\u093e\u0933\u0940|\u0926\u0941\u092a\u093e\u0930\u0940|\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0930\u093e\u0924\u094d\u0930\u0940"===a?e<4?e:e+12:"\u0938\u0915\u093e\u0933\u0940"===a?e:"\u0926\u0941\u092a\u093e\u0930\u0940"===a?10<=e?e:e+12:"\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"\u0930\u093e\u0924\u094d\u0930\u0940":e<10?"\u0938\u0915\u093e\u0933\u0940":e<17?"\u0926\u0941\u092a\u093e\u0930\u0940":e<20?"\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940":"\u0930\u093e\u0924\u094d\u0930\u0940"},week:{dow:0,doy:6}}),l.defineLocale("ms-my",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(e,a){return 12===e&&(e=0),"pagi"===a?e:"tengahari"===a?11<=e?e:e+12:"petang"===a||"malam"===a?e+12:void 0},meridiem:function(e,a,t){return e<11?"pagi":e<15?"tengahari":e<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}}),l.defineLocale("ms",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(e,a){return 12===e&&(e=0),"pagi"===a?e:"tengahari"===a?11<=e?e:e+12:"petang"===a||"malam"===a?e+12:void 0},meridiem:function(e,a,t){return e<11?"pagi":e<15?"tengahari":e<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}}),l.defineLocale("mt",{months:"Jannar_Frar_Marzu_April_Mejju_\u0120unju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Di\u010bembru".split("_"),monthsShort:"Jan_Fra_Mar_Apr_Mej_\u0120un_Lul_Aww_Set_Ott_Nov_Di\u010b".split("_"),weekdays:"Il-\u0126add_It-Tnejn_It-Tlieta_L-Erbg\u0127a_Il-\u0126amis_Il-\u0120img\u0127a_Is-Sibt".split("_"),weekdaysShort:"\u0126ad_Tne_Tli_Erb_\u0126am_\u0120im_Sib".split("_"),weekdaysMin:"\u0126a_Tn_Tl_Er_\u0126a_\u0120i_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Illum fil-]LT",nextDay:"[G\u0127ada fil-]LT",nextWeek:"dddd [fil-]LT",lastDay:"[Il-biera\u0127 fil-]LT",lastWeek:"dddd [li g\u0127adda] [fil-]LT",sameElse:"L"},relativeTime:{future:"f\u2019 %s",past:"%s ilu",s:"ftit sekondi",ss:"%d sekondi",m:"minuta",mm:"%d minuti",h:"sieg\u0127a",hh:"%d sieg\u0127at",d:"\u0121urnata",dd:"%d \u0121ranet",M:"xahar",MM:"%d xhur",y:"sena",yy:"%d sni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}});var cn={1:"\u1041",2:"\u1042",3:"\u1043",4:"\u1044",5:"\u1045",6:"\u1046",7:"\u1047",8:"\u1048",9:"\u1049",0:"\u1040"},Yn={"\u1041":"1","\u1042":"2","\u1043":"3","\u1044":"4","\u1045":"5","\u1046":"6","\u1047":"7","\u1048":"8","\u1049":"9","\u1040":"0"};l.defineLocale("my",{months:"\u1007\u1014\u103a\u1014\u101d\u102b\u101b\u102e_\u1016\u1031\u1016\u1031\u102c\u103a\u101d\u102b\u101b\u102e_\u1019\u1010\u103a_\u1027\u1015\u103c\u102e_\u1019\u1031_\u1007\u103d\u1014\u103a_\u1007\u1030\u101c\u102d\u102f\u1004\u103a_\u101e\u103c\u1002\u102f\u1010\u103a_\u1005\u1000\u103a\u1010\u1004\u103a\u1018\u102c_\u1021\u1031\u102c\u1000\u103a\u1010\u102d\u102f\u1018\u102c_\u1014\u102d\u102f\u101d\u1004\u103a\u1018\u102c_\u1012\u102e\u1007\u1004\u103a\u1018\u102c".split("_"),monthsShort:"\u1007\u1014\u103a_\u1016\u1031_\u1019\u1010\u103a_\u1015\u103c\u102e_\u1019\u1031_\u1007\u103d\u1014\u103a_\u101c\u102d\u102f\u1004\u103a_\u101e\u103c_\u1005\u1000\u103a_\u1021\u1031\u102c\u1000\u103a_\u1014\u102d\u102f_\u1012\u102e".split("_"),weekdays:"\u
511491010\u1014\u1004\u103a\u1039\u1002\u1014\u103d\u1031_\u1010\u1014\u1004\u103a\u1039\u101c\u102c_\u1021\u1004\u103a\u1039\u1002\u102b_\u1017\u102f\u1012\u1039\u1013\u101f\u1030\u1038_\u1000\u103c\u102c\u101e\u1015\u1010\u1031\u1038_\u101e\u1031\u102c\u1000\u103c\u102c_\u1005\u1014\u1031".split("_"),weekdaysShort:"\u1014\u103d\u1031_\u101c\u102c_\u1002\u102b_\u101f\u1030\u1038_\u1000\u103c\u102c_\u101e\u1031\u102c_\u1014\u1031".split("_"),weekdaysMin:"\u1014\u103d\u1031_\u101c\u102c_\u1002\u102b_\u101f\u1030\u1038_\u1000\u103c\u102c_\u101e\u1031\u102c_\u1014\u1031".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u101a\u1014\u1031.] LT [\u1019\u103e\u102c]",nextDay:"[\u1019\u1014\u1000\u103a\u1016\u103c\u1014\u103a] LT [\u1019\u103e\u102c]",nextWeek:"dddd LT [\u1019\u103e\u102c]",lastDay:"[\u1019\u1014\u1031.\u1000] LT [\u1019\u103e\u102c]",lastWeek:"[\u1015\u103c\u102e\u1038\u1001\u1032\u1037\u101e\u1031\u102c] dddd LT [\u1019\u103e\u102c]",sameElse:"L"},relativeTime:{future:"\u101c\u102c\u1019\u100a\u103a\u1037 %s \u1019\u103e\u102c",past:"\u101c\u103d\u1014\u103a\u1001\u1032\u1037\u101e\u1031\u102c %s \u1000",s:"\u1005\u1000\u1039\u1000\u1014\u103a.\u1021\u1014\u100a\u103a\u1038\u1004\u101a\u103a",ss:"%d \u1005\u1000\u1039\u1000\u1014\u1037\u103a",m:"\u1010\u1005\u103a\u1019\u102d\u1014\u1005\u103a",mm:"%d \u1019\u102d\u1014\u1005\u103a",h:"\u1010\u1005\u103a\u1014\u102c\u101b\u102e",hh:"%d \u1014\u102c\u101b\u102e",d:"\u1010\u1005\u103a\u101b\u1000\u103a",dd:"%d \u101b\u1000\u103a",M:"\u1010\u1005\u103a\u101c",MM:"%d \u101c",y:"\u1010\u1005\u103a\u1014\u103e\u1005\u103a",yy:"%d \u1014\u103e\u1005\u103a"},preparse:function(e){return e.replace(/[\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1040]/g,function(e){return Yn[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return cn[e]})},week:{dow:1,doy:4}}),l.defineLocale("nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"s\xf8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\xf8rdag".split("_"),weekdaysShort:"s\xf8._ma._ti._on._to._fr._l\xf8.".split("_"),weekdaysMin:"s\xf8_ma_ti_on_to_fr_l\xf8".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i g\xe5r kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",ss:"%d sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en m\xe5ned",MM:"%d m\xe5neder",y:"ett \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});var yn={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},fn={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};l.defineLocale("ne",{months:"\u091c\u0928\u0935\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u093f\u0932_\u092e\u0908_\u091c\u0941\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0937\u094d\u091f_\u0938\u0947\u092a\u094d\u091f\u0947\u092e\u094d\u092c\u0930_\u0905\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u092d\u0947\u092e\u094d\u092c\u0930_\u0921\u093f\u0938\u0947\u092e\u094d\u092c\u0930".split("_"),monthsShort:"\u091c\u0928._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u093f._\u092e\u0908_\u091c\u0941\u0928_\u091c\u0941\u0932\u093e\u0908._\u0905\u0917._\u0938\u0947\u092a\u094d\u091f._\u0905\u0915\u094d\u091f\u094b._\u0928\u094b\u092d\u0947._\u0921\u093f\u0938\u0947.".split("_"),monthsParseExact:!0,weekdays:"\u0906\u0907\u0924\u092c\u093e\u0930_\u0938\u094b\u092e\u092c\u093e\u0930_\u092e\u0919\u094d\u0917\u0932\u092c\u093e\u0930_\u092c\u0941\u0927\u092c\u093e\u0930_\u092c\u093f\u0939\u093f\u092c\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u092c\u093e\u0930_\u0936\u0928\u093f\u092c\u093e\u0930".split("_"),weekdaysShort:"\u0906\u0907\u0924._\u0938\u094b\u092e._\u092e\u0919\u094d\u0917\u0932._\u092c\u0941\u0927._\u092c\u093f\u0939\u093f._\u0936\u0941\u0915\u094d\u0930._\u0936\u0928\u093f.".split("_"),weekdaysMin:"\u0906._\u0938\u094b._\u092e\u0902._\u092c\u0941._\u092c\u093f._\u0936\u0941._\u0936.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A\u0915\u094b h:mm \u092c\u091c\u0947",LTS:"A\u0915\u094b h:mm:ss \u092c\u091c\u0947",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A\u0915\u094b h:mm \u092c\u091c\u0947",LLLL:"dddd, D MMMM YYYY, A\u0915\u094b h:mm \u092c\u091c\u0947"},preparse:function(e){return e.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(e){return fn[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return yn[e]})},meridiemParse:/\u0930\u093e\u0924\u093f|\u092c\u093f\u0939\u093e\u0928|\u0926\u093f\u0909\u0901\u0938\u094b|\u0938\u093e\u0901\u091d/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0930\u093e\u0924\u093f"===a?e<4?e:e+12:"\u092c\u093f\u0939\u093e\u0928"===a?e:"\u0926\u093f\u0909\u0901\u0938\u094b"===a?10<=e?e:e+12:"\u0938\u093e\u0901\u091d"===a?e+12:void 0},meridiem:function(e,a,t){return e<3?"\u0930\u093e\u0924\u093f":e<12?"\u092c\u093f\u0939\u093e\u0928":e<16?"\u0926\u093f\u0909\u0901\u0938\u094b":e<20?"\u0938\u093e\u0901\u091d":"\u0930\u093e\u0924\u093f"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u092d\u094b\u0932\u093f] LT",nextWeek:"[\u0906\u0909\u0901\u0926\u094b] dddd[,] LT",lastDay:"[\u0939\u093f\u091c\u094b] LT",lastWeek:"[\u0917\u090f\u0915\u094b] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s\u092e\u093e",past:"%s \u0905\u0917\u093e\u0921\u093f",s:"\u0915\u0947\u0939\u0940 \u0915\u094d\u0937\u0923",ss:"%d \u0938\u0947\u0915\u0947\u0923\u094d\u0921",m:"\u090f\u0915 \u092e\u093f\u0928\u0947\u091f",mm:"%d \u092e\u093f\u0928\u0947\u091f",h:"\u090f\u0915 \u0918\u0923\u094d\u091f\u093e",hh:"%d \u0918\u0923\u094d\u091f\u093e",d:"\u090f\u0915 \u0926\u093f\u0928",dd:"%d \u0926\u093f\u0928",M:"\u090f\u0915 \u092e\u0939\u093f\u0928\u093e",MM:"%d \u092e\u0939\u093f\u0928\u093e",y:"\u090f\u0915 \u092c\u0930\u094d\u0937",yy:"%d \u092c\u0930\u094d\u0937"},week:{dow:0,doy:6}});var kn="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),pn="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),Dn=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],Tn=/^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;l.defineLocale("nl-be",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(e,a){return e?/-MMM-/.test(a)?pn[e.month()]:kn[e.month()]:kn},monthsRegex:Tn,monthsShortRegex:Tn,monthsStrictRegex:/^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:Dn,longMonthsParse:Dn,shortMonthsParse:Dn,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"\xe9\xe9n minuut",mm:"%d minuten",h:"\xe9\xe9n uur",hh:"%d uur",d:"\xe9\xe9n dag",dd:"%d dagen",M:"\xe9\xe9n maand",MM:"%d maanden",y:"\xe9\xe9n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||20<=e?"ste":"de")},week:{dow:1,doy:4}});var gn="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),wn="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),vn=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],Sn=/^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;l.defineLocale("nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(e,a){return e?/-MMM-/.test(a)?wn[e.month()]:gn[e.month()]:gn},monthsRegex:Sn,monthsShortRegex:Sn,monthsStrictRegex:/^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:vn,longMonthsParse:vn,shortMonthsParse:vn,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"\xe9\xe9n minuut",mm:"%d minuten",h:"\xe9\xe9n uur",hh:"%d uur",d:"\xe9\xe9n dag",dd:"%d dagen",M:"\xe9\xe9n maand",MM:"%d maanden",y:"\xe9\xe9n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||20<=e?"ste":"de")},week:{dow:1,doy:4}}),l.defineLocale("nn",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sundag_m\xe5ndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),weekdaysShort:"sun_m\xe5n_tys_ons_tor_fre_lau".split("_"),weekdaysMin:"su_m\xe5_ty_on_to_fr_l\xf8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[I dag klokka] LT",nextDay:"[I morgon klokka] LT",nextWeek:"dddd [klokka] LT",lastDay:"[I g\xe5r klokka] LT",lastWeek:"[F\xf8reg\xe5ande] dddd [klokka] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s sidan",s:"nokre sekund",ss:"%d sekund",m:"eit minutt",mm:"%d minutt",h:"ein time",hh:"%d timar",d:"ein dag",dd:"%d dagar",M:"ein m\xe5nad",MM:"%d m\xe5nader",y:"eit \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});var Hn={1:"\u0a67",2:"\u0a68",3:"\u0a69",4:"\u0a6a",5:"\u0a6b",6:"\u0a6c",7:"\u0a6d",8:"\u0a6e",9:"\u0a6f",0:"\u0a66"},bn={"\u0a67":"1","\u0a68":"2","\u0a69":"3","\u0a6a":"4","\u0a6b":"5","\u0a6c":"6","\u0a6d":"7","\u0a6e":"8","\u0a6f":"9","\u0a66":"0"};l.defineLocale("pa-in",{months:"\u0a1c\u0a28\u0a35\u0a30\u0a40_\u0a2b\u0a3c\u0a30\u0a35\u0a30\u0a40_\u0a2e\u0a3e\u0a30\u0a1a_\u0a05\u0a2a\u0a4d\u0a30\u0a48\u0a32_\u0a2e\u0a08_\u0a1c\u0a42\u0a28_\u0a1c\u0a41\u0a32\u0a3e\u0a08_\u0a05\u0a17\u0a38\u0a24_\u0a38\u0a24\u0a70\u0a2c\u0a30_\u0a05\u0a15\u0a24\u0a42\u0a2c\u0a30_\u0a28\u0a35\u0a70\u0a2c\u0a30_\u0a26\u0a38\u0a70\u0a2c\u0a30".split("_"),monthsShort:"\u0a1c\u0a28\u0a35\u0a30\u0a40_\u0a2b\u0a3c\u0a30\u0a35\u0a30\u0a40_\u0a2e\u0a3e\u0a30\u0a1a_\u0a05\u0a2a\u0a4d\u0a30\u0a48\u0a32_\u0a2e\u0a08_\u0a1c\u0a42\u0a28_\u0a1c\u0a41\u0a32\u0a3e\u0a08_\u0a05\u0a17\u0a38\u0a24_\u0a38\u0a24\u0a70\u0a2c\u0a30_\u0a05\u0a15\u0a24\u0a42\u0a2c\u0a30_\u0a28\u0a35\u0a70\u0a2c\u0a30_\u0a26\u0a38\u0a70\u0a2c\u0a30".split("_"),weekdays:"\u0a10\u0a24\u0a35\u0a3e\u0a30_\u0a38\u0a4b\u0a2e\u0a35\u0a3e\u0a30_\u0a2e\u0a70\u0a17\u0a32\u0a35\u0a3e\u0a30_\u0a2c\u0a41\u0a27\u0
51149a35\u0a3e\u0a30_\u0a35\u0a40\u0a30\u0a35\u0a3e\u0a30_\u0a38\u0a3c\u0a41\u0a71\u0a15\u0a30\u0a35\u0a3e\u0a30_\u0a38\u0a3c\u0a28\u0a40\u0a1a\u0a30\u0a35\u0a3e\u0a30".split("_"),weekdaysShort:"\u0a10\u0a24_\u0a38\u0a4b\u0a2e_\u0a2e\u0a70\u0a17\u0a32_\u0a2c\u0a41\u0a27_\u0a35\u0a40\u0a30_\u0a38\u0a3c\u0a41\u0a15\u0a30_\u0a38\u0a3c\u0a28\u0a40".split("_"),weekdaysMin:"\u0a10\u0a24_\u0a38\u0a4b\u0a2e_\u0a2e\u0a70\u0a17\u0a32_\u0a2c\u0a41\u0a27_\u0a35\u0a40\u0a30_\u0a38\u0a3c\u0a41\u0a15\u0a30_\u0a38\u0a3c\u0a28\u0a40".split("_"),longDateFormat:{LT:"A h:mm \u0a35\u0a1c\u0a47",LTS:"A h:mm:ss \u0a35\u0a1c\u0a47",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0a35\u0a1c\u0a47",LLLL:"dddd, D MMMM YYYY, A h:mm \u0a35\u0a1c\u0a47"},calendar:{sameDay:"[\u0a05\u0a1c] LT",nextDay:"[\u0a15\u0a32] LT",nextWeek:"dddd, LT",lastDay:"[\u0a15\u0a32] LT",lastWeek:"[\u0a2a\u0a3f\u0a1b\u0a32\u0a47] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0a35\u0a3f\u0a71\u0a1a",past:"%s \u0a2a\u0a3f\u0a1b\u0a32\u0a47",s:"\u0a15\u0a41\u0a1d \u0a38\u0a15\u0a3f\u0a70\u0a1f",ss:"%d \u0a38\u0a15\u0a3f\u0a70\u0a1f",m:"\u0a07\u0a15 \u0a2e\u0a3f\u0a70\u0a1f",mm:"%d \u0a2e\u0a3f\u0a70\u0a1f",h:"\u0a07\u0a71\u0a15 \u0a18\u0a70\u0a1f\u0a3e",hh:"%d \u0a18\u0a70\u0a1f\u0a47",d:"\u0a07\u0a71\u0a15 \u0a26\u0a3f\u0a28",dd:"%d \u0a26\u0a3f\u0a28",M:"\u0a07\u0a71\u0a15 \u0a2e\u0a39\u0a40\u0a28\u0a3e",MM:"%d \u0a2e\u0a39\u0a40\u0a28\u0a47",y:"\u0a07\u0a71\u0a15 \u0a38\u0a3e\u0a32",yy:"%d \u0a38\u0a3e\u0a32"},preparse:function(e){return e.replace(/[\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0a66]/g,function(e){return bn[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return Hn[e]})},meridiemParse:/\u0a30\u0a3e\u0a24|\u0a38\u0a35\u0a47\u0a30|\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30|\u0a38\u0a3c\u0a3e\u0a2e/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0a30\u0a3e\u0a24"===a?e<4?e:e+12:"\u0a38\u0a35\u0a47\u0a30"===a?e:"\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30"===a?10<=e?e:e+12:"\u0a38\u0a3c\u0a3e\u0a2e"===a?e+12:void 0}
51149,meridiem:function(e,a,t){return e<4?"\u0a30\u0a3e\u0a24":e<10?"\u0a38\u0a35\u0a47\u0a30":e<17?"\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30":e<20?"\u0a38\u0a3c\u0a3e\u0a2e":"\u0a30\u0a3e\u0a24"},week:{dow:0,doy:6}});var jn="stycze\u0144_luty_marzec_kwiecie\u0144_maj_czerwiec_lipiec_sierpie\u0144_wrzesie\u0144_pa\u017adziernik_listopad_grudzie\u0144".split("_"),xn="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_wrze\u015bnia_pa\u017adziernika_listopada_grudnia".split("_");function Pn(e){return e%10<5&&1<e%10&&~~(e/10)%10!=1}function On(e,a,t){var s=e+" ";switch(t){case"ss":return s+(Pn(e)?"sekundy":"sekund");case"m":return a?"minuta":"minut\u0119";case"mm":return s+(Pn(e)?"minuty":"minut");case"h":return a?"godzina":"godzin\u0119";case"hh":return s+(Pn(e)?"godziny":"godzin");case"MM":return s+(Pn(e)?"miesi\u0105ce":"miesi\u0119cy");case"yy":return s+(Pn(e)?"lata":"lat")}}function Wn(e,a,t){var s=" ";return(20<=e%100||100<=e&&e%100==0)&&(s=" de "),e+s+{ss:"secunde",mm:"minute",hh:"ore",dd:"zile",MM:"luni",yy:"ani"}[t]}function En(e,a,t){var s,n;return"m"===t?a?"\u043c\u0438\u043d\u0443\u0442\u0430":"\u043c\u0438\u043d\u0443\u0442\u0443":e+" "+(s=+e,n={ss:a?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434",mm:a?"\u043c\u0438\u043d\u0443\u0442\u0430_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442":"\u043c\u0438\u043d\u0443\u0442\u0443_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442",hh:"\u0447\u0430\u0441_\u0447\u0430\u0441\u0430_\u0447\u0430\u0441\u043e\u0432",dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u044f_\u0434\u043d\u0435\u0439",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u0430_\u043c\u0435\u0441\u044f\u0446\u0435\u0432",yy:"\u0433\u043e\u0434_\u0433\u043e\u0434\u0430_\u043b\u0435\u0442"}[t].split("_"),s%10==1&&s%100!=11?n[0]:2<=s%10&&s%10<=4&&(s%100<10||20<=s%100)?n[1]:n[2])}l.defineLocale("pl",{months:function(e,a){return e?""===a?"("+xn[e.month()]+"|"+jn[e.month()]+")":/D MMMM/.test(a)?xn[e.month()]:jn[e.month()]:jn},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_pa\u017a_lis_gru".split("_"),weekdays:"niedziela_poniedzia\u0142ek_wtorek_\u015broda_czwartek_pi\u0105tek_sobota".split("_"),weekdaysShort:"ndz_pon_wt_\u015br_czw_pt_sob".split("_"),weekdaysMin:"Nd_Pn_Wt_\u015ar_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dzi\u015b o] LT",nextDay:"[Jutro o] LT",nextWeek:function(){switch(this.day()){case 0:return"[W niedziel\u0119 o] LT";case 2:return"[We wtorek o] LT";case 3:return"[W \u015brod\u0119 o] LT";case 6:return"[W sobot\u0119 o] LT";default:return"[W] dddd [o] LT"}},lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zesz\u0142\u0105 niedziel\u0119 o] LT";case 3:return"[W zesz\u0142\u0105 \u015brod\u0119 o] LT";case 6:return"[W zesz\u0142\u0105 sobot\u0119 o] LT";default:return"[W zesz\u0142y] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",ss:On,m:On,mm:On,h:On,hh:On,d:"1 dzie\u0144",dd:"%d dni",M:"miesi\u0105c",MM:On,y:"rok",yy:On},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("pt-br",{months:"janeiro_fevereiro_mar\xe7o_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\xe7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\xe1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\xe1b".split("_"),weekdaysMin:"Do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [\xe0s] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [\xe0s] HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"h\xe1 %s",s:"poucos segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%
51149d horas",d:"um dia",dd:"%d dias",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba"}),l.defineLocale("pt",{months:"janeiro_fevereiro_mar\xe7o_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\xe7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\xe1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\xe1b".split("_"),weekdaysMin:"Do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"h\xe1 %s",s:"segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}}),l.defineLocale("ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"duminic\u0103_luni_mar\u021bi_miercuri_joi_vineri_s\xe2mb\u0103t\u0103".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_S\xe2m".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_S\xe2".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[m\xe2ine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s \xeen urm\u0103",s:"c\xe2teva secunde",ss:Wn,m:"un minut",mm:Wn,h:"o or\u0103",hh:Wn,d:"o zi",dd:Wn,M:"o lun\u0103",MM:Wn,y:"un an",yy:Wn},week:{dow:1,doy:7}});var An=[/^\u044f\u043d\u0432/i,/^\u0444\u0435\u0432/i,/^\u043c\u0430\u0440/i,/^\u0430\u043f\u0440/i,/^\u043c\u0430[\u0439\u044f]/i,/^\u0438\u044e\u043d/i,/^\u0438\u044e\u043b/i,/^\u0430\u0432\u0433/i,/^\u0441\u0435\u043d/i,/^\u043e\u043a\u0442/i,/^\u043d\u043e\u044f/i,/^\u0434\u0435\u043a/i];l.defineLocale("ru",{months:{format:"\u044f\u043d\u0432\u0430\u0440\u044f_\u0444\u0435\u0432\u0440\u0430\u043b\u044f_\u043c\u0430\u0440\u0442\u0430_\u0430\u043f\u0440\u0435\u043b\u044f_\u043c\u0430\u044f_\u0438\u044e\u043d\u044f_\u0438\u044e\u043b\u044f_\u0430\u0432\u0433\u0443\u0441\u0442\u0430_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f_\u043e\u043a\u0442\u044f\u0431\u0440\u044f_\u043d\u043e\u044f\u0431\u0440\u044f_\u0434\u0435\u043a\u0430\u0431\u0440\u044f".split("_"),standalone:"\u044f\u043d\u0432\u0430\u0440\u044c_\u0444\u0435\u0432\u0440\u0430\u043b\u044c_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b\u044c_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c_\u043e\u043a\u0442\u044f\u0431\u0440\u044c_\u043d\u043e\u044f\u0431\u0440\u044c_\u0434\u0435\u043a\u0430\u0431\u0440\u044c".split("_")},monthsShort:{format:"\u044f\u043d\u0432._\u0444\u0435\u0432\u0440._\u043c\u0430\u0440._\u0430\u043f\u0440._\u043c\u0430\u044f_\u0438\u044e\u043d\u044f_\u0438\u044e\u043b\u044f_\u0430\u0432\u0433._\u0441\u0435\u043d\u0442._\u043e\u043a\u0442._\u043d\u043e\u044f\u0431._\u0434\u0435\u043a.".split("_"),standalone:"\u044f\u043d\u0432._\u0444\u0435\u0432\u0440._\u043c\u0430\u0440\u0442_\u0430\u043f\u0440._\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433._\u0441\u0435\u043d\u0442._\u043e\u043a\u0442._\u043d\u043e\u044f\u0431._\u0434\u0435\u043a.".split("_")},weekdays:{standalone:"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0435\u0440\u0433_\u043f\u044f\u0442\u043d\u0438\u0446\u0430_\u0441\u0443\u0431\u0431\u043e\u0442\u0430".split("_"),format:"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0443_\u0447\u0435\u0442\u0432\u0435\u0440\u0433_\u043f\u044f\u0442\u043d\u0438\u0446\u0443_\u0441\u0443\u0431\u0431\u043e\u0442\u0443".split("_"),isFormat:/\[ ?[\u0412\u0432] ?(?:\u043f\u0440\u043e\u0448\u043b\u0443\u044e|\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e|\u044d\u0442\u0443)? ?\] ?dddd/},weekdaysShort:"\u0432\u0441_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u0432\u0441_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),monthsParse:An,longMonthsParse:An,shortMonthsParse:An,monthsRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044c\u044f]|\u044f\u043d\u0432\.?|\u0444\u0435\u0432\u0440\u0430\u043b[\u044c\u044f]|\u0444\u0435\u0432\u0440?\.?|\u043c\u0430\u0440\u0442\u0430?|\u043c\u0430\u0440\.?|\u0430\u043f\u0440\u0435\u043b[\u044c\u044f]|\u0430\u043f\u0440\.?|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d[\u044c\u044f]|\u0438\u044e\u043d\.?|\u0438\u044e\u043b[\u044c\u044f]|\u0438\u044e\u043b\.?|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0430\u0432\u0433\.?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044c\u044f]|\u0441\u0435\u043d\u0442?\.?|\u043e\u043a\u0442\u044f\u0431\u0440[\u044c\u044f]|\u043e\u043a\u0442\.?|\u043d\u043e\u044f\u0431\u0440[\u044c\u044f]|\u043d\u043e\u044f\u0431?\.?|\u0434\u0435\u043a\u0430\u0431\u0440[\u044c\u044f]|\u0434\u0435\u043a\.?)/i,monthsShortRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044c\u044f]|\u044f\u043d\u0432\.?|\u0444\u0435\u0432\u0440\u0430\u043b[\u044c\u044f]|\u0444\u0435\u0432\u0440?\.?|\u043c\u0430\u0440\u0442\u0430?|\u043c\u0430\u0440\.?|\u0430\u043f\u0440\u0435\u043b[\u044c\u044f]|\u0430\u043f\u0440\.?|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d[\u044c\u044f]|\u0438\u044e\u043d\.?|\u0438\u044e\u043b[\u044c\u044f]|\u0438\u044e\u043b\.?|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0430\u0432\u0433\.?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044c\u044f]|\u0441\u0435\u043d\u0442?\.?|\u043e\u043a\u0442\u044f\u0431\u0440[\u044c\u044f]|\u043e\u043a\u0442\.?|\u043d\u043e\u044f\u0431\u0440[\u044c\u044f]|\u043d\u043e\u044f\u0431?\.?|\u0434\u0435\u043a\u0430\u0431\u0440[\u044c\u044f]|\u0434\u0435\u043a\.?)/i,monthsStrictRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044f\u044c]|\u0444\u0435\u0432\u0440\u0430\u043b[\u044f\u044c]|\u043c\u0430\u0440\u0442\u0430?|\u0430\u043f\u0440\u0435\u043b[\u044f\u044c]|\u043c\u0430[\u044f\u0439]|\u0438\u044e\u043d[\u044f\u044c]|\u0438\u044e\u043b[\u044f\u044c]|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044f\u044c]|\u043e\u043a\u0442\u044f\u0431\u0440[\u044f\u044c]|\u043d\u043e\u044f\u0431\u0440[\u044f\u044c]|\u0434\u0435\u043a\u0430\u0431\u0440[\u044f\u044c])/i,monthsShortStrictRegex:/^(\u044f\u043d\u0432\.|\u0444\u0435\u0432\u0440?\.|\u
vendor: 40,120 bytes, line 51149
51149043c\u0430\u0440[\u0442.]|\u0430\u043f\u0440\.|\u043c\u0430[\u044f\u0439]|\u0438\u044e\u043d[\u044c\u044f.]|\u0438\u044e\u043b[\u044c\u044f.]|\u0430\u0432\u0433\.|\u0441\u0435\u043d\u0442?\.|\u043e\u043a\u0442\.|\u043d\u043e\u044f\u0431?\.|\u0434\u0435\u043a\.)/i,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0433.",LLL:"D MMMM YYYY \u0433., H:mm",LLLL:"dddd, D MMMM YYYY \u0433., H:mm"},calendar:{sameDay:"[\u0421\u0435\u0433\u043e\u0434\u043d\u044f, \u0432] LT",nextDay:"[\u0417\u0430\u0432\u0442\u0440\u0430, \u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430, \u0432] LT",nextWeek:function(e){if(e.week()===this.week())return 2===this.day()?"[\u0412\u043e] dddd, [\u0432] LT":"[\u0412] dddd, [\u0432] LT";switch(this.day()){case 0:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435] dddd, [\u0432] LT";case 1:case 2:case 4:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439] dddd, [\u0432] LT";case 3:case 5:case 6:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e] dddd, [\u0432] LT"}},lastWeek:function(e){if(e.week()===this.week())return 2===this.day()?"[\u0412\u043e] dddd, [\u0432] LT":"[\u0412] dddd, [\u0432] LT";switch(this.day()){case 0:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0435] dddd, [\u0432] LT";case 1:case 2:case 4:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0439] dddd, [\u0432] LT";case 3:case 5:case 6:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u0443\u044e] dddd, [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0447\u0435\u0440\u0435\u0437 %s",past:"%s \u043d\u0430\u0437\u0430\u0434",s:"\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434",ss:En,m:En,mm:En,h:"\u0447\u0430\u0441",hh:En,d:"\u0434\u0435\u043d\u044c",dd:En,M:"\u043c\u0435\u0441\u044f\u0446",MM:En,y:"\u0433\u043e\u0434",yy:En},meridiemParse:/\u043d\u043e\u0447\u0438|\u0443\u0442\u0440\u0430|\u0434\u043d\u044f|\u0432\u0435\u0447\u0435\u0440\u0430/i,isPM:function(e){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u0435\u0440\u0430)$/.test(e)},meridiem:function(e,a,t){return e<4?"\u043d\u043e\u0447\u0438":e<12?"\u0443\u0442\u0440\u0430":e<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u0435\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0439|\u0433\u043e|\u044f)/,ordinal:function(e,a){switch(a){case"M":case"d":case"DDD":return e+"-\u0439";case"D":return e+"-\u0433\u043e";case"w":case"W":return e+"-\u044f";default:return e}},week:{dow:1,doy:4}});var Fn=["\u062c\u0646\u0648\u0631\u064a","\u0641\u064a\u0628\u0631\u0648\u0631\u064a","\u0645\u0627\u0631\u0686","\u0627\u067e\u0631\u064a\u0644","\u0645\u0626\u064a","\u062c\u0648\u0646","\u062c\u0648\u0644\u0627\u0621\u0650","\u0622\u06af\u0633\u067d","\u0633\u064a\u067e\u067d\u0645\u0628\u0631","\u0622\u06aa\u067d\u0648\u0628\u0631","\u0646\u0648\u0645\u0628\u0631","\u068a\u0633\u0645\u0628\u0631"],zn=["\u0622\u0686\u0631","\u0633\u0648\u0645\u0631","\u0627\u06b1\u0627\u0631\u0648","\u0627\u0631\u0628\u0639","\u062e\u0645\u064a\u0633","\u062c\u0645\u0639","\u0687\u0646\u0687\u0631"];l.defineLocale("sd",{months:Fn,monthsShort:Fn,weekdays:zn,weekdaysShort:zn,weekdaysMin:zn,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd\u060c D MMMM YYYY HH:mm"},meridiemParse:/\u0635\u0628\u062d|\u0634\u0627\u0645/,isPM:function(e){return"\u0634\u0627\u0645"===e},meridiem:function(e,a,t){return e<12?"\u0635\u0628\u062d":"\u0634\u0627\u0645"},calendar:{sameDay:"[\u0627\u0684] LT",nextDay:"[\u0633\u0680\u0627\u06bb\u064a] LT",nextWeek:"dddd [\u0627\u06b3\u064a\u0646 \u0647\u0641\u062a\u064a \u062a\u064a] LT",lastDay:"[\u06aa\u0627\u0644\u0647\u0647] LT",lastWeek:"[\u06af\u0632\u0631\u064a\u0644 \u0647\u0641\u062a\u064a] dddd [\u062a\u064a] LT",sameElse:"L"},relativeTime:{future:"%s \u067e\u0648\u0621",past:"%s \u0627\u06b3",s:"\u0686\u0646\u062f \u0633\u064a\u06aa\u0646\u068a",ss:"%d \u0633\u064a\u06aa\u0646\u068a",m:"\u0647\u06aa \u0645\u0646\u067d",mm:"%d \u0645\u0646\u067d",h:"\u0647\u06aa \u06aa\u0644\u0627\u06aa",hh:"%d \u06aa\u0644\u0627\u06aa",d:"\u0647\u06aa \u068f\u064a\u0646\u0647\u0646",dd:"%d \u068f\u064a\u0646\u0647\u0646",M:"\u0647\u06aa \u0645\u0647\u064a\u0646\u0648",MM:"%d \u0645\u0647\u064a\u0646\u0627",y:"\u0647\u06aa \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(e){return e.replace(/\u060c/g,",")},postformat:function(e){return e.replace(/,/g,"\u060c")},week:{dow:1,doy:4}}),l.defineLocale("se",{months:"o\u0111\u0111ajagem\xe1nnu_guovvam\xe1nnu_njuk\u010dam\xe1nnu_cuo\u014bom\xe1nnu_miessem\xe1nnu_geassem\xe1nnu_suoidnem\xe1nnu_borgem\xe1nnu_\u010dak\u010dam\xe1nnu_golggotm\xe1nnu_sk\xe1bmam\xe1nnu_juovlam\xe1nnu".split("_"),monthsShort:"o\u0111\u0111j_guov_njuk_cuo_mies_geas_suoi_borg_\u010dak\u010d_golg_sk\xe1b_juov".split("_"),weekdays:"sotnabeaivi_vuoss\xe1rga_ma\u014b\u014beb\xe1rga_gaskavahkku_duorastat_bearjadat_l\xe1vvardat".split("_"),weekdaysShort:"sotn_vuos_ma\u014b_gask_duor_bear_l\xe1v".split("_"),weekdaysMin:"s_v_m_g_d_b_L".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"MMMM D. [b.] YYYY",LLL:"MMMM D. [b.] YYYY [ti.] HH:mm",LLLL:"dddd, MMMM D. [b.] YYYY [ti.] HH:mm"},calendar:{sameDay:"[otne ti] LT",nextDay:"[ihttin ti] LT",nextWeek:"dddd [ti] LT",lastDay:"[ikte ti] LT",lastWeek:"[ovddit] dddd [ti] LT",sameElse:"L"},relativeTime:{future:"%s gea\u017ees",past:"ma\u014bit %s",s:"moadde sekunddat",ss:"%d sekunddat",m:"okta minuhta",mm:"%d minuhtat",h:"okta diimmu",hh:"%d diimmut",d:"okta beaivi",dd:"%d beaivvit",M:"okta m\xe1nnu",MM:"%d m\xe1nut",y:"okta jahki",yy:"%d jagit"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("si",{months:"\u0da2\u0db1\u0dc0\u0dcf\u0dbb\u0dd2_\u0db4\u0dd9\u0db6\u0dbb\u0dc0\u0dcf\u0dbb\u0dd2_\u0db8\u0dcf\u0dbb\u0dca\u0dad\u0dd4_\u0d85\u0db4\u0dca\u200d\u0dbb\u0dda\u0dbd\u0dca_\u0db8\u0dd0\u0dba\u0dd2_\u0da2\u0dd6\u0db1\u0dd2_\u0da2\u0dd6\u0dbd\u0dd2_\u0d85\u0d9c\u0ddd\u0dc3\u0dca\u0dad\u0dd4_\u0dc3\u0dd0\u0db4\u0dca\u0dad\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca_\u0d94\u0d9a\u0dca\u0dad\u0ddd\u0db6\u0dbb\u0dca_\u0db1\u0ddc\u0dc0\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca_\u0daf\u0dd9\u0dc3\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca".split("_"),monthsShort:"\u0da2\u0db1_\u0db4\u0dd9\u0db6_\u0db8\u0dcf\u0dbb\u0dca_\u0d85\u0db4\u0dca_\u0db8\u0dd0\u0dba\u0dd2_\u0da2\u0dd6\u0db1\u0dd2_\u0da2\u0dd6\u0dbd\u0dd2_\u0d85\u0d9c\u0ddd_\u0dc3\u0dd0\u0db4\u0dca_\u0d94\u0d9a\u0dca_\u0db1\u0ddc\u0dc0\u0dd0_\u0daf\u0dd9\u0dc3\u0dd0".split("_"),weekdays:"\u0d89\u0dbb\u0dd2\u0daf\u0dcf_\u0dc3\u0db3\u0dd4\u0daf\u0dcf_\u0d85\u0d9f\u0dc4\u0dbb\u0dd4\u0dc0\u0dcf\u0daf\u0dcf_\u0db6\u0daf\u0dcf\u0daf\u0dcf_\u0db6\u0dca\u200d\u0dbb\u0dc4\u0dc3\u0dca\u0db4\u0dad\u0dd2\u0db1\u0dca\u0daf\u0dcf_\u0dc3\u0dd2\u0d9a\u0dd4\u0dbb\u0dcf\u0daf\u0dcf_\u0dc3\u0dd9\u0db1\u0dc3\u0dd4\u0dbb\u0dcf\u0daf\u0dcf".split("_"),weekdaysShort:"\u0d89\u0dbb\u0dd2_\u0dc3\u0db3\u0dd4_\u0d85\u0d9f_\u0db6\u0daf\u0dcf_\u0db6\u0dca\u200d\u0dbb\u0dc4_\u0dc3\u0dd2\u0d9a\u0dd4_\u0dc3\u0dd9\u0db1".split("_"),weekdaysMin:"\u0d89_\u0dc3_\u0d85_\u0db6_\u0db6\u0dca\u200d\u0dbb_\u0dc3\u0dd2_\u0dc3\u0dd9".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"a h:mm",LTS:"a h:mm:ss",L:"YYYY/MM/DD",LL:"YYYY MMMM D",LLL:"YYYY MMMM D, a h:mm",LLLL:"YYYY MMMM D [\u0dc0\u0dd0\u0db1\u0dd2] dddd, a h:mm:ss"},calendar:{sameDay:"[\u0d85\u0daf] LT[\u0da7]",nextDay:"[\u0dc4\u0dd9\u0da7] LT[\u0da7]",nextWeek:"dddd LT[\u0da7]",lastDay:"[\u0d8a\u0dba\u0dda] LT[\u0da7]",lastWeek:"[\u0db4\u0dc3\u0dd4\u0d9c\u0dd2\u0dba] dddd LT[\u0da7]",sameElse:"L"},relativeTime:{future:"%s\u0d9a\u0dd2\u0db1\u0dca",past:"%s\u0d9a\u0da7 \u0db4\u0dd9\u0dbb",s:"\u0dad\u0dad\u0dca\u0db4\u0dbb \u0d9a\u0dd2\u0dc4\u0dd2\u0db4\u0dba",ss:"\u0dad\u0dad\u0dca\u0db4\u0dbb %d",m:"\u0db8\u0dd2\u0db1\u0dd2\u0dad\u0dca\u0dad\u0dd4\u0dc0",mm:"\u0db8\u0dd2\u0db1\u0dd2\u0dad\u0dca\u0dad\u0dd4 %d",h:"\u0db4\u0dd0\u0dba",hh:"\u0db4\u0dd0\u0dba %d",d:"\u0daf\u0dd2\u0db1\u0dba",dd:"\u0daf\u0dd2\u0db1 %d",M:"\u0db8\u0dcf\u0dc3\u0dba",MM:"\u0db8\u0dcf\u0dc3 %d",y:"\u0dc0\u0dc3\u0dbb",yy:"\u0dc0\u0dc3\u0dbb %d"},dayOfMonthOrdinalParse:/\d{1,2} \u0dc0\u0dd0\u0db1\u0dd2/,ordinal:function(e){return e+" \u0dc0\u0dd0\u0db1\u0dd2"},meridiemParse:/\u0db4\u0dd9\u0dbb \u0dc0\u0dbb\u0dd4|\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4|\u0db4\u0dd9.\u0dc0|\u0db4.\u0dc0./,isPM:function(e){return"\u0db4.\u0dc0."===e||"\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4"===e},meridiem:function(e,a,t){return 11<e?t?"\u0db4.\u0dc0.":"\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4":t?"\u0db4\u0dd9.\u0dc0.":"\u0db4\u0dd9\u0dbb \u0dc0\u0dbb\u0dd4"}});var Jn="janu\xe1r_febru\xe1r_marec_apr\xedl_m\xe1j_j\xfan_j\xfal_august_september_okt\xf3ber_november_december".split("_"),Nn="jan_feb_mar_apr_m\xe1j_j\xfan_j\xfal_aug_sep_okt_nov_dec".split("_");function Rn(e){return 1<e&&e<5}function In(e,a,t,s){var n=e+" ";switch(t){case"s":return a||s?"p\xe1r sek\xfand":"p\xe1r sekundami";case"ss":return a||s?n+(Rn(e)?"sekundy":"sek\xfand"):n+"sekundami";break;case"m":return a?"min\xfata":s?"min\xfatu":"min\xfatou";case"mm":return a||s?n+(Rn(e)?"min\xfaty":"min\xfat"):n+"min\xfatami";break;case"h":return a?"hodina":s?"hodinu":"hodinou";case"hh":return a||s?n+(Rn(e)?"hodiny":"hod\xedn"):n+"hodinami";break;case"d":return a||s?"de\u0148":"d\u0148om";case"dd":return a||s?n+(Rn(e)?"dni":"dn\xed"):n+"d\u0148ami";break;case"M":return a||s?"mesiac":"mesiacom";case"MM":return a||s?n+(Rn(e)?"mesiace":"mesiacov"):n+"mesiacmi";break;case"y":return a||s?"rok":"rokom";case"yy":return a||s?n+(Rn(e)?"roky":"rokov"):n+"rokmi";break}}function Cn(e,a,t,s){var n=e+" ";switch(t){case"s":return a||s?"nekaj sekund":"nekaj sekundami";case"ss":return n+=1===e?a?"sekundo":"sekundi":2===e?a||s?"sekundi":"sekundah":e<5?a||s?"sekunde":"sekundah":"sekund";case"m":return a?"ena minuta":"eno minuto";case"mm":return n+=1===e?a?"minuta":"minuto":2===e?a||s?"minuti":"minutama":e<5?a||s?"minute":"minutami":a||s?"minut":"minutami";case"h":return a?"ena ura":"eno uro";case"hh":return n+=1===e?a?"ura":"uro":2===e?a||s?"uri":"urama":e<5?a||s?"ure":"urami":a||s?"ur":"urami";case"d":return a||s?"en dan":"enim dnem";case"dd":return n+=1===e?a||s?"dan":"dnem":2===e?a||s?"dni":"dnevoma":a||s?"dni":"dnevi";case"M":return a||s?"en mesec":"enim mesecem";case"MM":return n+=1===e?a||s?"mesec":"mesecem":2===e?a||s?"meseca":"mesecema":e<5?a||s?"mesece":"meseci":a||s?"mesecev":"meseci";case"y":return a||s?"eno leto":"enim letom";case"yy":return n+=1===e?a||s?"leto":"letom":2===e?a||s?"leti":"letoma":e<5?a||s?"leta":"leti":a||s?"let":"leti"}}l.defineLocale("sk",{months:Jn,monthsShort:Nn,weekdays:"nede\u013ea_pondelok_utorok_streda_\u0161tvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_\u0161t_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_\u0161t_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nede\u013eu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo \u0161tvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[v\u010dera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minul\xfa nede\u013eu o] LT";case 1:case 2:return"[minul\xfd] dddd [o] LT";case 3:return"[minul\xfa stredu o] LT";case 4:case 5:return"[minul\xfd] dddd [o] LT";case 6:return"[minul\xfa sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:In,ss:In,m:In,mm:In,h:In,hh:In,d:In,dd:In,M:In,MM:In,y:In,yy:In},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljek_torek_sreda_\u010detrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._\u010det._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_\u010de_pe_so".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[v\u010deraj ob] LT",lastWeek:function(){switch(this.day()){case 0:return"[prej\u0161njo] [nedeljo] [ob] LT";case 3:return"[prej\u0161njo] [sredo] [ob] LT";case 6:return"[prej\u0161njo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prej\u0161nji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"\u010dez %s",past:"pred %s",s:Cn,ss:Cn,m:Cn,mm:Cn,h:Cn,hh:Cn,d:Cn,dd:Cn,M:Cn,MM:Cn,y:Cn,yy:Cn},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}}),l.defineLocale("sq",{months:"Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_N\xebntor_Dhjetor".split("_"),monthsShort:"Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_N\xebn_Dhj".split("_"),weekdays:"E Diel_E H\xebn\xeb_E Mart\xeb_E M\xebrkur\xeb_E Enjte_E Premte_E Shtun\xeb".split("_"),weekdaysShort:"Die_H\xebn_Mar_M\xebr_Enj_Pre_Sht".split("_"),weekdaysMin:"D_H_Ma_M\xeb_E_P_Sh".split("_"),weekdaysParseExact:!0,meridiemParse:/PD|MD/,isPM:function(e){return"M"===e.charAt(0)},meridiem:function(e,a,t){return e<12?"PD":"MD"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Sot n\xeb] LT",nextDay:"[Nes\xebr n\xeb] LT",nextWeek:"dddd [n\xeb] LT",lastDay:"[Dje n\xeb] LT",lastWeek:"dddd [e kaluar n\xeb] LT",sameElse:"L"},relativeTime:{future:"n\xeb %s",past:"%s m\xeb par\xeb",s:"disa sekonda",ss:"%d sekonda",m:"nj\xeb minut\xeb",mm:"%d minuta",h:"nj\xeb or\xeb",hh:"%d or\xeb",d:"nj\xeb dit\xeb",dd:"%d dit\xeb",M:"nj\xeb muaj",MM:"%d muaj",y:"nj\xeb vit",yy:"%d vite"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});var Gn={words:{ss:["\u0441\u0435\u043a\u0443\u043d\u0434\u0430","\u0441\u0435\u043a\u0443\u043d\u0434\u0435","\u0441\u0435\u043a\u0443\u043d\u0434\u0438"],m:["\u0458\u0435\u0434\u0430\u043d \u043c\u0438\u043d\u0443\u0442","\u0458\u0435\u0434\u043d\u0435 \u043c\u0438\u043d\u0443\u0442\u0435"],mm:["\u043c\u0438\u043d\u0443\u0442","\u043c\u0438\u043d\u0443\u0442\u0435","\u043c\u0438\u043d\u0443\u0442\u0430"],h:["\u0458\u0435\u0434\u0430\u043d \u0441\u0430\u0442","\u0458\u0435\u0434\u043d\u043e\u0433 \u0441\u0430\u0442\u0430"],hh:["\u0441\u0430\u0442","\u0441\u0430\u0442\u0430","\u0441\u0430\u0442\u0438"],dd:["\u0434\u0430\u043d","\u0434\u0430\u043d\u0430","\u0434\u0430\u043d\u0430"],MM:["\u043c\u0435\u0441\u0435\u0446","\u043c\u0435\u0441\u0435\u0446\u0430","\u043c\u0435\u0441\u0435\u0446\u0438"],yy:["\u0433\u043e\u0434\u0438\u043d\u0430","\u0433\u043e\u0434\u0438\u043d\u0435","\u0433\u043e\u0434\u0438\u043d\u0430"]},correctGrammaticalCase:function(e,a){return 1===e?a[0]:2<=e&&e<=4?a[1]:a[2]},translate:function(e,a,t){var s=Gn.words[t];return 1===t.length?a?s[0]:s[1]:e+" "+Gn.correctGrammaticalCase(e,s)}};l.defineLocale("sr-cyrl",{months:"\u0458\u0430\u043d\u0443\u0430\u0440_\u0444\u0435\u0431\u0440\u0443\u0430\u0440_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440_\u043e\u043a\u0442\u043e\u0431\u0430\u0440_\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440_\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440".split("_"),monthsShort:"\u0458\u0430\u043d._\u0444\u0435\u0431._\u043c\u0430\u0440._\u0430\u043f\u0440._\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433._\u0441\u0435\u043f._\u043e\u043a\u0442._\u043d\u043e\u0432._\u0434\u0435\u0446.".split("_"),monthsParseExact:!0,weekdays:"\u043d\u0435\u0434\u0435\u0459\u0430_\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a_\u0443\u0442\u043e\u0440\u0430\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a_\u043f\u0435\u0442\u0430\u043a_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434._\u043f\u043e\u043d._\u0443\u0442\u043e._\u0441\u0440\u0435._\u0447\u0435\u0442._\u043f\u0435\u0442._\u0441\u0443\u0431.".split("_"),weekdaysMin:"\u043d\u0435_\u043f\u043e_\u0443\u0442_\u0441\u0440_\u0447\u0435_\u043f\u0435_\u0441\u0443".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[\u0434\u0430\u043d\u0430\u0441 \u0443] LT",nextDay:"[\u0441\u0443\u0442\u0440\u0430 \u0443] LT",nextWeek:function(){switch(this.day()){case 0:return"[\u0443] [\u043d\u0435\u0434\u0435\u0459\u0443] [\u0443] LT";case 3:return"[\u0443] [\u0441\u0440\u0435\u0434\u0443] [\u0443] LT";case 6:return"[\u0443] [\u0441\u0443\u0431\u043e\u0442\u0443] [\u0443] LT";case 1:case 2:case 4:case 5:return"[\u0443] dddd [\u0443] LT"}},lastDay:"[\u0458\u0443\u0447\u0435 \u0443] LT",lastWeek:function(){return["[\u043f\u0440\u043e\u0448\u043b\u0435] [\u043d\u0435\u0434\u0435\u0459\u0435] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u0443\u0442\u043e\u0440\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u0435] [\u0441\u0440\u0435\u0434\u0435] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u0447\u0435\u0442\u0432\u0440\u0442\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u043f\u0435\u0442\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u0435] [\u0441\u0443\u0431\u043e\u0442\u0435] [\u0443] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"\u043f\u0440\u0435 %s",s:"\u043d\u0435\u043a\u043e\u043b\u0438\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:Gn.translate,m:Gn.translate,mm:Gn.translate,h:Gn.translate,hh:Gn.translate,d:"\u0434\u0430\u043d",dd:Gn.translate,M:"\u043c\u0435\u0441\u0435\u0446",MM:Gn.translate,y:"\u0433\u043e\u0434\u0438\u043d\u0443",yy:Gn.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});var Un={words:{ss:["sekunda","sekunde","sekundi"],m:["jedan minut","jedne minute"],mm:["minut","minute","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mesec","meseca","meseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(e,a){return 1===e?a[0]:2<=e&&e<=4?a[1]:a[2]},translate:function(e,a,t){var s=Un.words[t];return 1===t.length?a?s[0]:s[1]:e+" "+Un.correctGrammaticalCase(e,s)}};l.defineLocale("sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljak_utorak_sreda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010de u] LT",lastWeek:function(){return["[pro\u0161le] [nedelje] [u] LT","[pro\u0161log] [ponedeljka] [u] LT","[pro\u0161log] [utorka] [u] LT","[pro\u0161le] [srede] [u] LT","[pro\u0161log] [\u010detvrtka] [u] LT","[pro\u0161log] [petka] [u] LT","[pro\u0161le] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",ss:Un.translate,m:Un.translate,mm:Un.translate,h:Un.translate,hh:Un.translate,d:"dan",dd:Un.translate,M:"mesec",MM:Un.translate,y:"godinu",yy:Un.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}}),l.defineLocale("ss",{months:"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split("_"),monthsShort:"Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo".split("_"),weekdays:"Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo".split("_"),weekdaysShort:"Lis_Umb_Lsb_Les_Lsi_Lsh_Umg".split("_"),weekdaysMin:"Li_Us_Lb_Lt_Ls_Lh_Ug".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Namuhla nga] LT",nextDay:"[Kusasa nga] LT",nextWeek:"dddd [nga] LT",lastDay:"[Itolo nga] LT",lastWeek:"dddd [leliphelile] [nga] LT",sameElse:"L"},relativeTime:{future:"nga %s",past:"wenteka nga %s",s:"emizuzwana lomcane",ss:"%d mzuzwana",m:"umzuzu",mm:"%d emizuzu",h:"lihora",hh:"%d emahora",d:"lilanga",dd:"%d emalanga",M:"inyanga",MM:"%d tinyanga",y:"umnyaka",yy:"%d iminyaka"},meridiemParse:/ekuseni|emini|entsambama|ebusuku/,meridiem:function(e,a,t){return e<11?"ekuseni":e<15?"emini":e<19?"entsambama":"ebusuku"},meridiemHour:function(e,a){return 12===e&&(e=0),"ekuseni"===a?e:"emini"===a?11<=e?e:e+12:"entsambama"===a||"ebusuku"===a?0===e?0:e+12:void 0},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:"%d",week:{dow:1,doy:4}}),l.defineLocale("sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"s\xf6ndag_m\xe5ndag_tisdag_onsdag_torsdag_fredag_l\xf6rdag".split("_"),weekdaysShort:"s\xf6n_m\xe5n_tis_ons_tor_fre_l\xf6r".split("_"),weekdaysMin:"s\xf6_m\xe5_ti_on_to_fr_l\xf6".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Ig\xe5r] LT",nextWeek:"[P\xe5] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"f\xf6r %s sedan",s:"n\xe5gra sekunder",ss:"%d sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en m\xe5nad",MM:"%d m\xe5nader",y:"ett \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}(e|a)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"e":1===a?"a":2===a?"a":"e")},week:{dow:1,doy:4}}),l.defineLocale("sw",{months:"Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des".split("_"),weekdays:"Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi".split("_"),weekdaysShort:"Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos".split("_"),weekdaysMin:"J2_J3_J4_J5_Al_Ij_J1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[leo saa] LT",nextDay:"[kesho saa] LT",nextWeek:"[wiki ijayo] dddd [saat] LT",lastDay:"[jana] LT",lastWeek:"[wiki iliyopita] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s baadaye",past:"tokea %s",s:"hivi punde",ss:"sekunde %d",m:"dakika moja",mm:"dakika %d",h:"saa limoja",hh:"masaa %d",d:"siku moja",dd:"masiku %d",M:"mwezi mmoja",MM:"miezi %d",y:"mwaka mmoja",yy:"miaka %d"},week:{dow:1,doy:7}});var Vn={1:"\u0be7",2:"\u0be8",3:"\u0be9",4:"\u0bea",5:"\u0beb",6:"\u0bec",7:"\u0bed",8:"\u0bee",9:"\u0bef",0:"\u0be6"},Kn={"\u0be7":"1","\u0be8":"2","\u0be9":"3","\u0bea":"4","\u0beb":"5","\u0bec":"6","\u0bed":"7","\u0bee":"8","\u0bef":"9","\u0be6":"0"};l.defineLocale("ta",{months:"\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf_\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf_\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd_\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd_\u0bae\u0bc7_\u0b9c\u0bc2\u0ba9\u0bcd_\u0b9c\u0bc2\u0bb2\u0bc8_\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd_\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bc6\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b85\u0b95\u0bcd\u0b9f\u0bc7\u0bbe\u0baa\u0bb0\u0bcd_\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd".split("_"),monthsShort:"\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf_\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf_\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd_\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd_\u0bae\u0bc7_\u0b9c\u0bc2\u0ba9\u0bcd_\u0b9c\u0bc2\u0bb2\u0bc8_\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd_\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bc6\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b85\u0b95\u0bcd\u0b9f\u0bc7\u0bbe\u0baa\u0bb0\u0bcd_\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd".split("_"),weekdays:"\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bcd\u0bb1\u0bc1\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0b9f\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0baa\u0bc1\u0ba4\u0ba9\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0b9a\u0ba9\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8".split("_"),weekdaysShort:"\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1_\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd_\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd_\u0baa\u0bc1\u0ba4\u0ba9\u0bcd_\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd_\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf_\u0b9a\u0ba9\u0bbf".split("_"),weekdaysMin:"\u0b9e\u0bbe_\u0ba4\u0bbf_\u0b9a\u0bc6_\u0baa\u0bc1_\u0bb5\u0bbf_\u0bb5\u0bc6_\u0b9a".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, HH:mm",LLLL:"dddd, D MMMM YYYY, HH:mm"},calendar:{sameDay:"[\u0b87\u0ba9\u0bcd\u0bb1\u0bc1] LT",nextDay:"[\u0ba8\u0bbe\u0bb3\u0bc8] LT",nextWeek:"dddd, LT",lastDay:"[\u0ba8\u0bc7\u0bb1\u0bcd\u0bb1\u0bc1] LT",lastWeek:"[\u0b95\u0b9f\u0ba8\u0bcd\u0ba4 \u0bb5\u0bbe\u0bb0\u0bae\u0bcd] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0b87\u0bb2\u0bcd",past:"%s \u0bae\u0bc1\u0ba9\u0bcd",s:"\u0b92\u0bb0\u0bc1 \u0b9a\u0bbf\u0bb2 \u0bb5\u0bbf\u0ba8\u0bbe\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",ss:"%d \u0bb5\u0bbf\u0ba8\u0bbe\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",m:"\u0b92\u0bb0\u0bc1 \u0ba8\u0bbf\u0bae\u0bbf\u0b9f\u0bae\u0bcd",mm:"%d \u0ba8\u0bbf\u0bae\u0bbf\u0b9f\u0b99\u0bcd\u0b95\u0bb3\u0bcd",h:"\u0b92\u0bb0\u0bc1 \u0bae\u0ba3\u0bbf \u0ba8\u0bc7\u0bb0\u0bae\u0bcd",hh:"%d \u0bae\u0ba3\u0bbf \u0ba8\u0bc7\u0bb0\u0bae\u0bcd",d:"\u0b92\u0bb0\u0bc1 \u0ba8\u0bbe\u0bb3\u0bcd",dd:"%d \u0ba8\u0bbe\u0b9f\u0bcd\u0b95\u0bb3\u0bcd",M:"\u0b92\u0bb0\u0bc1 \u0bae\u0bbe\u0ba4\u0bae\u0bcd",MM:"%d \u0bae\u0bbe\u0ba4\u0b99\u0bcd\u0b95\u0bb3\u0bcd",y:"\u0b92\u0bb0\u0bc1 \u0bb5\u0bb0\u0bc1\u0b9f\u0bae\u0bcd",yy:"%d \u0b86\u0ba3\u0bcd\u0b9f\u0bc1\u0b95\u0bb3\u0bcd"},dayOfMonthOrdinalParse:/\d{1,2}\u0bb5\u0ba4\u0bc1/,ordinal:function(e){return e+"\u0bb5\u0ba4\u0bc1"},preparse:function(e){return e.replace(/[\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0be6]/g,function(e){return Kn[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return Vn[e]})},meridiemParse:/\u0baf\u0bbe\u0bae\u0bae\u0bcd|\u0bb5\u0bc8\u0b95\u0bb1\u0bc8|\u0b95\u0bbe\u0bb2\u0bc8|\u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd|\u0b8e\u0bb1\u0bcd\u0baa\u0bbe\u0b9f\u0bc1|\u0bae\u0bbe\u0bb2\u0bc8/,meridiem:function(e,a,t){return e<2?" \u0baf\u0bbe\u0bae\u0bae\u0bcd":e<6?" \u0bb5\u0bc8\u0b95\u0bb1\u0bc8":e<10?" \u0b95\u0bbe\u0bb2\u0bc8":e<14?" \u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd":e<18?" \u0b8e\u0bb1\u0bcd\u0baa\u0bbe\u0b9f\u0bc1":e<22?" \u0bae\u0bbe\u0bb2\u0bc8":" \u0baf\u0bbe\u0bae\u0bae\u0bcd"},meridiemHour:function(e,a){return 12===e&&(e=0),"\u0baf\u0bbe\u0bae\u0bae\u0bcd"===a?e<2?e:e+12:"\u0bb5\u0bc8\u0b95\u0bb1\u0bc8"===a||"\u0b95\u0bbe\u0bb2\u0bc8"===a?e:"\u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd"===a&&10<=e?e:e+12},week:{dow:0,doy:6}}),l.defineLocale("te",{months:"\u0c1c\u0c28\u0c35\u0c30\u0c3f_\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f_\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f_\u0c0f\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d_\u0c2e\u0c47_\u0c1c\u0c42\u0c28\u0c4d_\u0c1c\u0c42\u0c32\u0c46\u0c56_\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41_\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d_\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d_\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d_\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d".split("_"),monthsShort:"\u0c1c\u0c28._\u0c2b\u0c3f\u0c2c\u0c4d\u0c30._\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f_\u0c0f\u0c2a\u0c4d\u0c30\u0c3f._\u0c2e\u0c47_\u0c1c\u0c42\u0c28\u0c4d_\u0c1c\u0c42\u0c32\u0c46\u0c56_\u0c06\u0c17._\u0c38\u0c46\u0c2a\u0c4d._\u0c05\u0c15\u0c4d\u0c1f\u0c4b._\u0c28\u0c35._\u0c21\u0c3f\u0c38\u0c46.".split("_"),monthsParseExact:!0,weekdays:"\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02_\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02_\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02_\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02_\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02_\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02_\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02".split("_"),weekdaysShort:"\u0c06\u0c26\u0c3f_\u0c38\u0c4b\u0c2e_\u0c2e\u0c02\u0c17\u0c33_\u0c2c\u0c41\u0c27_\u0c17\u0c41\u0c30\u0c41_\u0c36\u0c41\u0c15\u0c4d\u0c30_\u0c36\u0c28\u0c3f".split("_"),weekdaysMin:"\u0c06_\u0c38\u0c4b_\u0c2e\u0c02_\u0c2c\u0c41_\u0c17\u0c41_\u0c36\u0c41_\u0c36".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0c28\u0c47\u0c21\u0c41] LT",nextDay:"[\u0c30\u0c47\u0c2a\u0c41] LT",nextWeek:"dddd, LT",lastDay:"[\u0c28\u0c3f\u0c28\u0c4d\u0c28] LT",lastWeek:"[\u0c17\u0c24] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0c32\u0c4b",past:"%s \u0c15\u0c4d\u0c30\u0c3f\u0c24\u0c02",s:"\u0c15\u0c4a\u0c28\u0c4d\u0c28\u0c3f \u0c15\u0c4d\u0c37\u0c23\u0c3e\u0c32\u0c41",ss:"%d \u0c38\u0c46\u0c15\u0c28\u0c4d\u0c32\u0c41",m:"\u0c12\u0c15 \u0c28\u0c3f\u0c2e\u0c3f\u0c37\u0c02",mm:"%d \u0c28\u0c3f\u0c2e\u0c3f\u0c37\u0c3e\u0c32\u0c41",h:"\u0c12\u0c15 \u0c17\u0c02\u0c1f",hh:"%d \u0c17\u0c02\u0c1f\u0c32\u0c41",d:"\u0c12\u0c15 \u0c30\u0c4b\u0c1c\u0c41",dd:"%d \u0c30\u0c4b\u0c1c\u0c41\u0c32\u0c41",M:"\u0c12\u0c15 \u0c28\u0c46\u0c32",MM:"%d \u0c28\u0c46\u0c32\u0c32\u0c41",y:"\u0c12\u0c15 \u0c38\u0c02\u0c35\u0c24\u0c4d\u0c38\u0c30\u0c02",yy:"%d \u0c38\u0c02\u0c35\u0c24\u0c4d\u0c38\u0c30\u0c3e\u0c32\u0c41"},dayOfMonthOrdinalParse:/\d{1,2}\u0c35/,ordinal:"%d\u0c35",meridiemParse:/\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f|\u0c09\u0c26\u0c2f\u0c02|\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02|\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f"===a?e<4?e:e+12:"\u0c09\u0c26\u0c2f\u0c02"===a?e:"\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02"===a?10<=e?e:e+12:"\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f":e<10?"\u0c09\u0c26\u0c2f\u0c02":e<17?"\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02":e<20?"\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02":"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f"},week:{dow:0,doy:6}}),l.defineLocale("tet",{months:"Janeiru_Fevereiru_Marsu_Abril_Maiu_Ju\xf1u_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu".split("_"),weekdaysShort:"Dom_Seg_Ters_Kua_Kint_Sest_Sab".split("_"),weekdaysMin:"Do_Seg_Te_Ku_Ki_Ses_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Ohin iha] LT",nextDay:"[Aban iha] LT",nextWeek:"dddd [iha] LT",lastDay:"[Horiseik iha] LT",lastWeek:"dddd [semana kotuk] [iha] LT",sameElse:"L"},relativeTime:{future:"iha %s",past:"%s liuba",s:"minutu balun",ss:"minutu %d",m:"minutu ida",mm:"minutu %d",h:"oras ida",hh:"oras %d",d:"loron ida",dd:"loron %d",M:"fulan ida",MM:"fulan %d",y:"tinan ida",yy:"tinan %d"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")},week:{dow:1,doy:4}});var Zn={0:"-\u0443\u043c",1:"-\u0443\u043c",2:"-\u044e\u043c",3:"-\u044e\u043c",4:"-\u0443\u043c",5:"-\u0443\u043c",6:"-\u0443\u043c",7:"-\u0443\u043c",8:"-\u0443\u043c",9:"-\u0443\u043c",10:"-\u0443\u043c",12:"-\u0443\u043c",13:"-\u0443\u043c",20:"-\u0443\u043c",30:"-\u044e\u043c",40:"-\u0443\u043c",50:"-\u0443\u043c",60:"-\u0443\u043c",70:"-\u0443\u043c",80:"-\u0443\u043c",90:"-\u0443\u043c",100:"-\u0443\u043c"};l.defineLocale("tg",{months:"\u044f\u043d\u0432\u0430\u0440_\u0444\u0435\u0432\u0440\u0430\u043b_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440_\u043e\u043a\u0442\u044f\u0431\u0440_\u043d\u043e\u044f\u0431\u0440_\u0434\u0435\u043a\u0430\u0431\u0440".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u044f\u043a\u0448\u0430\u043d\u0431\u0435_\u0434\u0443\u0448\u0430\u043d\u0431\u0435_\u0441\u0435\u0448\u0430\u043d\u0431\u0435_\u0447\u043e\u0440\u0448\u0430\u043d\u0431\u0435_\u043f\u0430\u043d\u04b7\u0448\u0430\u043d\u0431\u0435_\u04b7\u0443\u043c\u044a\u0430_\u0448\u0430\u043d\u0431\u0435".split("_"),weekdaysShort:"\u044f\u0448\u0431_\u0434\u0448\u0431_\u0441\u0448\u0431_\u0447\u0448\u0431_\u043f\u0448\u0431_\u04b7\u0443\u043c_\u0448\u043d\u0431".split("_"),weekdaysMin:"\u044f\u0448_\u0434\u0448_\u0441\u0448_\u0447\u0448_\u043f\u0448_\u04b7\u043c_\u0448\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0418\u043c\u0440\u04ef\u0437 \u0441\u043e\u0430\u0442\u0438] LT",nextDay:"[\u041f\u0430\u0433\u043e\u04b3 \u0441\u043e\u0430\u0442\u0438] LT",lastDay:"[\u0414\u0438\u0440\u04ef\u0437 \u0441\u043e\u0430\u0442\u0438] LT",nextWeek:"dddd[\u0438] [\u04b3\u0430\u0444\u0442\u0430\u0438 \u043e\u044f\u043d\u0434\u0430 \u0441\u043e\u0430\u0442\u0438] LT",lastWeek:"dddd[\u0438] [\u04b3\u0430\u0444\u0442\u0430\u0438 \u0433\u0443\u0437\u0430\u0448\u0442\u0430 \u0441\u043e\u0430\u0442\u0438] LT",sameElse:"L"},relativeTime:{future:"\u0431\u0430\u044a\u0434\u0438 %s",past:"%s \u043f\u0435\u0448",s:"\u044f\u043a\u0447\u0430\u043d\u0434 \u0441\u043e\u043d\u0438\u044f",m:"\u044f\u043a \u0434\u0430\u049b\u0438\u049b\u0430",mm:"%d \u0434\u0430\u049b\u0438\u049b\u0430",h:"\u044f\u043a \u0441\u043e\u0430\u0442",hh:"%d \u0441\u043e\u0430\u0442",d:"\u044f\u043a \u0440\u04ef\u0437",dd:"%d \u0440\u04ef\u0437",M:"\u044f\u043a \u043c\u043e\u04b3",MM:"%d \u043c\u043e\u04b3",y:"\u044f\u043a \u0441\u043e\u043b",yy:"%d \u0441\u043e\u043b"},meridiemParse:/\u0448\u0430\u0431|\u0441\u0443\u0431\u04b3|\u0440\u04ef\u0437|\u0431\u0435\u0433\u043e\u04b3/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u0448\u0430\u0431"===a?e<4?e:e+12:"\u0441\u0443\u0431\u04b3"===a?e:"\u0440\u04ef\u0437"===a?11<=e?e:e+12:"\u0431\u0435\u0433\u043e\u04b3"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"\u0448\u0430\u0431":e<11?"\u0441\u0443\u0431\u04b3":e<16?"\u0440\u04ef\u0437":e<19?"\u0431\u0435\u0433\u043e\u04b3":"\u0448\u0430\u0431"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0443\u043c|\u044e\u043c)/,ordinal:function(e){return e+(Zn[e]||Zn[e%10]||Zn[100<=e?100:null])},week:{dow:1,doy:7}}),l.defineLocale("th",{months:"\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21_\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c_\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21_\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19_\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21_\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19_\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21_\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21_\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19_\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21_\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19_\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21".split("_"),monthsShort:"\u0e21.\u0e04._\u0e01.\u0e1e._\u0e21\u0e35.\u0e04._\u0e40\u0e21.\u0e22._\u0e1e.\u0e04._\u0e21\u0e34.\u0e22._\u0e01.\u0e04._\u0e2a.\u0e04._\u0e01.\u0e22._\u0e15.\u0e04._\u0e1e.\u0e22._\u0e18.\u0e04.".split("_"),monthsParseExact:!0,weekdays:"\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c_\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c_\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23_\u0e1e\u0e38\u0e18_\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35_\u0e28\u0e38\u0e01\u0e23\u0e4c_\u0e40\u0e2a\u0e32\u0e23\u0e4c".split("_"),weekdaysShort:"\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c_\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c_\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23_\u0e1e\u0e38\u0e18_\u0e1e\u0e24\u0e2b\u0e31\u0e2a_\u0e28\u0e38\u0e01\u0e23\u0e4c_\u0e40\u0e2a\u0e32\u0e23\u0e4c".split("_"),weekdaysMin:"\u0e2d\u0e32._\u0e08._\u0e2d._\u0e1e._\u0e1e\u0e24._\u0e28._\u0e2a.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY \u0e40\u0e27\u0e25\u0e32 H:mm",LLLL:"\u0e27\u0e31\u0e19dddd\u0e17\u0e35\u0e48 D MMMM YYYY \u0e40\u0e27\u0e25\u0e32 H:mm"},meridiemParse:/\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07|\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07/,isPM:function(e){return"\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"===e},meridiem:function(e,a,t){return e<12?"\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07":"\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"},calendar:{sameDay:"[\u0e27\u0e31\u0e19\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",nextDay:"[\u0e1e\u0e23\u0e38\u0e48\u0e07\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",nextWeek:"dddd[\u0e2b\u0e19\u0e49\u0e32 \u0e40\u0e27\u0e25\u0e32] LT",lastDay:"[\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e27\u0e32\u0e19\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",lastWeek:"[\u0e27\u0e31\u0e19]dddd[\u0e17\u0e35\u0e48\u0e41\u0e25\u0e49\u0e27 \u0e40\u0e27\u0e25\u0e32] LT",sameElse:"L"},relativeTime:{future:"\u0e2d\u0e35\u0e01 %s",past:"%s\u0e17\u0e35\u0e48\u0e41\u0e25\u0e49\u0e27",s:"\u0e44\u0e21\u0e48\u0e01\u0e35\u0e48\u0e27\u0e34\u0e19\u0e32\u0e17\u0e35",ss:"%d \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35",m:"1 \u0e19\u0e32\u0e17\u0e35",mm:"%d \u0e19\u0e32\u0e17\u0e35",h:"1 \u0e0a\u0e31\u0e48\u0e27\u0e42\u0e21\u0e07",hh:"%d \u0e0a\u0e31\u0e48\u0e27\u0e42\u0e21\u0e07",d:"1 \u0e27\u0e31\u0e19",dd:"%d \u0e27\u0e31\u0e19",M:"1 \u0e40\u0e14\u0e37\u0e2d\u0e19",MM:"%d \u0e40\u0e14\u0e37\u0e2d\u0e19",y:"1 \u0e1b\u0e35",yy:"%d \u0e1b\u0e35"}}),l.defineLocale("tl-ph",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%
51149d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}});var $n="pagh_wa\u2019_cha\u2019_wej_loS_vagh_jav_Soch_chorgh_Hut".split("_");function Bn(e,a,t,s){var n=function(e){var a=Math.floor(e%1e3/100),t=Math.floor(e%100/10),s=e%10,n="";0<a&&(n+=$n[a]+"vatlh");0<t&&(n+=(""!==n?" ":"")+$n[t]+"maH");0<s&&(n+=(""!==n?" ":"")+$n[s]);return""===n?"pagh":n}(e);switch(t){case"ss":return n+" lup";case"mm":return n+" tup";case"hh":return n+" rep";case"dd":return n+" jaj";case"MM":return n+" jar";case"yy":return n+" DIS"}}l.defineLocale("tlh",{months:"tera\u2019 jar wa\u2019_tera\u2019 jar cha\u2019_tera\u2019 jar wej_tera\u2019 jar loS_tera\u2019 jar vagh_tera\u2019 jar jav_tera\u2019 jar Soch_tera\u2019 jar chorgh_tera\u2019 jar Hut_tera\u2019 jar wa\u2019maH_tera\u2019 jar wa\u2019maH wa\u2019_tera\u2019 jar wa\u2019maH cha\u2019".split("_"),monthsShort:"jar wa\u2019_jar cha\u2019_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa\u2019maH_jar wa\u2019maH wa\u2019_jar wa\u2019maH cha\u2019".split("_"),monthsParseExact:!0,weekdays:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysShort:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysMin:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[DaHjaj] LT",nextDay:"[wa\u2019leS] LT",nextWeek:"LLL",lastDay:"[wa\u2019Hu\u2019] LT",lastWeek:"LLL",sameElse:"L"},relativeTime:{future:function(e){var a=e;return a=-1!==e.indexOf("jaj")?a.slice(0,-3)+"leS":-1!==e.indexOf("jar")?a.slice(0,-3)+"waQ":-1!==e.indexOf("DIS")?a.slice(0,-3)+"nem":a+" pIq"},past:function(e){var a=e;return a=-1!==e.indexOf("jaj")?a.slice(0,-3)+"Hu\u2019":-1!==e.indexOf("jar")?a.slice(0,-3)+"wen":-1!==e.indexOf("DIS")?a.slice(0,-3)+"ben":a+" ret"},s:"puS lup",ss:Bn,m:"wa\u2019 tup",mm:Bn,h:"wa\u2019 rep",hh:Bn,d:"wa\u2019 jaj",dd:Bn,M:"wa\u2019 jar",MM:Bn,y:"wa\u2019 DIS",yy:Bn},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});var qn={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'\xfcnc\xfc",4:"'\xfcnc\xfc",100:"'\xfcnc\xfc",6:"'nc\u0131",9:"'uncu",10:"'uncu",30:"'uncu",60:"'\u0131nc\u0131",90:"'\u0131nc\u0131"};function Qn(e,a,t,s){var n={s:["viensas secunds","'iensas secunds"],ss:[e+" secunds",e+" secunds"],m:["'n m\xedut","'iens m\xedut"],mm:[e+" m\xeduts",e+" m\xeduts"],h:["'n \xfeora","'iensa \xfeora"],hh:[e+" \xfeoras",e+" \xfeoras"],d:["'n ziua","'iensa ziua"],dd:[e+" ziuas",e+" ziuas"],M:["'n mes","'iens mes"],MM:[e+" mesen",e+" mesen"],y:["'n ar","'iens ar"],yy:[e+" ars",e+" ars"]};return s?n[t][0]:a?n[t][0]:n[t][1]}function Xn(e,a,t){var s,n;return"m"===t?a?"\u0445\u0432\u0438\u043b\u0438\u043d\u0430":"\u0445\u0432\u0438\u043b\u0438\u043d\u0443":"h"===t?a?"\u0433\u043e\u0434\u0438\u043d\u0430":"\u0433\u043e\u0434\u0438\u043d\u0443":e+" "+(s=+e,n={ss:a?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u0438_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u0438_\u0441\u0435\u043a\u0443\u043d\u0434",mm:a?"\u0445\u0432\u0438\u043b\u0438\u043d\u0430_\u0445\u0432\u0438\u043b\u0438\u043d\u0438_\u0445\u0432\u0438\u043b\u0438\u043d":"\u0445\u0432\u0438\u043b\u0438\u043d\u0443_\u0445\u0432\u0438\u043b\u0438\u043d\u0438_\u0445\u0432\u0438\u043b\u0438\u043d",hh:a?"\u0433\u043e\u0434\u0438\u043d\u0430_\u0433\u043e\u0434\u0438\u043d\u0438_\u0433\u043e\u0434\u0438\u043d":"\u0433\u043e\u0434\u0438\u043d\u0443_\u0433\u043e\u0434\u0438\u043d\u0438_\u0433\u043e\u0434\u0438\u043d",dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u0456_\u0434\u043d\u0456\u0432",MM:"\u043c\u0456\u0441\u044f\u0446\u044c_\u043c\u0456\u0441\u044f\u0446\u0456_\u043c\u0456\u0441\u044f\u0446\u0456\u0432",yy:"\u0440\u0456\u043a_\u0440\u043e\u043a\u0438_\u0440\u043e\u043a\u0456\u0432"}[t].split("_"),s%10==1&&s%100!=11?n[0]:2<=s%10&&s%10<=4&&(s%100<10||20<=s%100)?n[1]:n[2])}
vendor: 2,505 bytes, line 51149
51149function ed(e){return function(){return e+"\u043e"+(11===this.hours()?"\u0431":"")+"] LT"}}l.defineLocale("tr",{months:"Ocak_\u015eubat_Mart_Nisan_May\u0131s_Haziran_Temmuz_A\u011fustos_Eyl\xfcl_Ekim_Kas\u0131m_Aral\u0131k".split("_"),monthsShort:"Oca_\u015eub_Mar_Nis_May_Haz_Tem_A\u011fu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Sal\u0131_\xc7ar\u015famba_Per\u015fembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pts_Sal_\xc7ar_Per_Cum_Cts".split("_"),weekdaysMin:"Pz_Pt_Sa_\xc7a_Pe_Cu_Ct".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bug\xfcn saat] LT",nextDay:"[yar\u0131n saat] LT",nextWeek:"[gelecek] dddd [saat] LT",lastDay:"[d\xfcn] LT",lastWeek:"[ge\xe7en] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s \xf6nce",s:"birka\xe7 saniye",ss:"%d saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir g\xfcn",dd:"%d g\xfcn",M:"bir ay",MM:"%d ay",y:"bir y\u0131l",yy:"%d y\u0131l"},ordinal:function(e,a){switch(a){case"d":case"D":case"Do":case"DD":return e;default:if(0===e)return e+"'\u0131nc\u0131";var t=e%10;return e+(qn[t]||qn[e%100-t]||qn[100<=e?100:null])}},week:{dow:1,doy:7}}),l.defineLocale("tzl",{months:"Januar_Fevraglh_Mar\xe7_Avr\xefu_Mai_G\xfcn_Julia_Guscht_Setemvar_Listop\xe4ts_Noemvar_Zecemvar".split("_"),monthsShort:"Jan_Fev_Mar_Avr_Mai_G\xfcn_Jul_Gus_Set_Lis_Noe_Zec".split("_"),weekdays:"S\xfaladi_L\xfane\xe7i_Maitzi_M\xe1rcuri_Xh\xfaadi_Vi\xe9ner\xe7i_S\xe1turi".split("_"),weekdaysShort:"S\xfal_L\xfan_Mai_M\xe1r_Xh\xfa_Vi\xe9_S\xe1t".split("_"),weekdaysMin:"S\xfa_L\xfa_Ma_M\xe1_Xh_Vi_S\xe1".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"D. MMMM [dallas] YYYY",LLL:"D. MMMM [dallas] YYYY HH.mm",LLLL:"dddd, [li] D. MMMM [dallas] YYYY HH.mm"},meridiemParse:/d\'o|d\'a/i,isPM:function(e){return"d'o"===e.toLowerCase()},meridiem:function(e,a,t){return 11<e?t?"d'o":"D'O":t?"d'a":"D'A"},calendar:{sameDay:"[oxhi \xe0] LT",nextDay:"[dem\xe0 \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[ieiri \xe0] LT",lastWeek:"[s\xfcr el] dddd [lasteu \xe0] LT",sameElse:"L"},relativeTime:{future:"osprei %s",past:"ja%s",s:Qn,ss:Qn,m:Qn,mm:Qn,h:Qn,hh:Qn,d:Qn,dd:Qn,M:Qn,MM:Qn,y:Qn,yy:Qn},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),l.defineLocale("tzm-latn",{months:"innayr_br\u02e4ayr\u02e4_mar\u02e4s\u02e4_ibrir_mayyw_ywnyw_ywlywz_\u0263w\u0161t_\u0161wtanbir_kt\u02e4
51149wbr\u02e4_nwwanbir_dwjnbir".split("_"),monthsShort:"innayr_br\u02e4ayr\u02e4_mar\u02e4s\u02e4_ibrir_mayyw_ywnyw_ywlywz_\u0263w\u0161t_\u0161wtanbir_kt\u02e4wbr\u02e4_nwwanbir_dwjnbir".split("_"),weekdays:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),weekdaysShort:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),weekdaysMin:"asamas_aynas_asinas_akras_akwas_asimwas_asi\u1e0dyas".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[asdkh g] LT",nextDay:"[aska g] LT",nextWeek:"dddd [g] LT",lastDay:"[assant g] LT",lastWeek:"dddd [g] LT",sameElse:"L"},relativeTime:{future:"dadkh s yan %s",past:"yan %s",s:"imik",ss:"%d imik",m:"minu\u1e0d",mm:"%d minu\u1e0d",h:"sa\u025ba",hh:"%d tassa\u025bin",d:"ass",dd:"%d ossan",M:"ayowr",MM:"%d iyyirn",y:"asgas",yy:"%d isgasn"},week:{dow:6,doy:12}}),l.defineLocale("tzm",{months:"\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54_\u2d31\u2d55\u2d30\u2d62\u2d55_\u2d4e\u2d30\u2d55\u2d5a_\u2d49\u2d31\u2d54\u2d49\u2d54_\u2d4e\u2d30\u2d62\u2d62\u2d53_\u2d62\u2d53\u2d4f\u2d62\u2d53_\u2d62\u2d53\u2d4d\u2d62\u2d53\u2d63_\u2d56\u2d53\u2d5b\u2d5c_\u2d5b\u2d53\u2d5c\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d3d\u2d5f\u2d53\u2d31\u2d55_\u2d4f\u2d53\u2d61\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d37\u2d53\u2d4a\u2d4f\u2d31\u2d49\u2d54".split("_"),monthsShort:"\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54_\u2d31\u2d55\u2d30\u2d62\u2d55_\u2d4e\u2d30\u2d55\u2d5a_\u2d49\u2d31\u2d54\u2d49\u2d54_\u2d4e\u2d30\u2d62\u2d62\u2d53_\u2d62\u2d53\u2d4f\u2d62\u2d53_\u2d62\u2d53\u2d4d\u2d62\u2d53\u2d63_\u2d56\u2d53\u2d5b\u2d5c_\u2d5b\u2d53\u2d5c\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d3d\u2d5f\u2d53\u2d31\u2d55_\u2d4f\u2d53\u2d61\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d37\u2d53\u2d4a\u2d4f\u2d31\u2d49\u2d54".split("_"),weekdays:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),weekdaysShort:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),weekdaysMin:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u2d30\u2d59\u2d37\u2d45 \u2d34] LT",nextDay:"[\u2d30\u2d59\u2d3d\u2d30 \u2d34] LT",nextWeek:"dddd [\u2d34] LT",lastDay:"[\u2d30\u2d5a\u2d30\u2d4f\u2d5c \u2d34] LT",lastWeek:"dddd [\u2d34] LT",sameElse:"L"},relativeTime:{future:"\u2d37\u2d30\u2d37\u2d45 \u2d59 \u2d62\u2d30\u2d4f %s",past:"\u2d62\u2d30\u2d4f %s",s:"\u2d49\u2d4e\u2d49\u2d3d",ss:"%d \u2d49\u2d4e\u2d49\u2d3d",m:"\u2d4e\u2d49\u2d4f\u2d53\u2d3a",mm:"%d \u2d4e\u2d49\u2d4f\u2d53\u2d3a",h:"\u2d59\u2d30\u2d44\u2d30",hh:"%d \u2d5c\u2d30\u2d59\u2d59\u2d30\u2d44\u2d49\u2d4f",d:"\u2d30\u2d59\u2d59",dd:"%d o\u2d59\u2d59\u2d30\u2d4f",M:"\u2d30\u2d62o\u2d53\u2d54",MM:"%d \u2d49\u2d62\u2d62\u2d49\u2d54\u2d4f",y:"\u2d30\u2d59\u2d33\u2d30\u2d59",yy:"%d \u2d49\u2d59\u2d33\u2d30\u2d59\u2d4f"},week:{dow:6,doy:12}}),l.defineLocale("ug-cn",{months:"\u064a\u0627\u0646\u06cb\u0627\u0631_\u0641\u06d0\u06cb\u0631\u0627\u0644_\u0645\u0627\u0631\u062a_\u0626\u0627\u067e\u0631\u06d0\u0644_\u0645\u0627\u064a_\u0626\u0649\u064a\u06c7\u0646_\u0626\u0649\u064a\u06c7\u0644_\u0626\u0627\u06cb\u063a\u06c7\u0633\u062a_\u0633\u06d0\u0646\u062a\u06d5\u0628\u0649\u0631_\u0626\u06c6\u0643\u062a\u06d5\u0628\u0649\u0631_\u0646\u0648\u064a\u0627\u0628\u0649\u0631_\u062f\u06d0\u0643\u0627\u0628\u0649\u0631".split("_"),monthsShort:"\u064a\u0627\u0646\u06cb\u0627\u0631_\u0641\u06d0\u06cb\u0631\u0627\u0644_\u0645\u0627\u0631\u062a_\u0626\u0627\u067e\u0631\u06d0\u0644_\u0645\u0627\u064a_\u0626\u0649\u064a\u06c7\u0646_\u0626\u0649\u064a\u06c7\u0644_\u0626\u0627\u06cb\u063a\u06c7\u0633\u062a_\u0633\u06d0\u0646\u062a\u06d5\u0628\u0649\u0631_\u0626\u06c6\u0643\u062a\u06d5\u0628\u0649\u0631_\u0646\u0648\u064a\u0627\u0628\u0649\u0631_\u062f\u06d0\u0643\u0627\u0628\u0649\u0631".split("_"),weekdays:"\u064a\u06d5\u0643\u0634\u06d5\u0646\u0628\u06d5_\u062f\u06c8\u0634\u06d5\u0646\u0628\u06d5_\u0633\u06d5\u064a\u0634\u06d5\u0646\u0628\u06d5_\u0686\u0627\u0631\u0634\u06d5\u0646\u0628\u06d5_\u067e\u06d5\u064a\u0634\u06d5\u0646\u0628\u06d5_\u062c\u06c8\u0645\u06d5_\u0634\u06d5\u0646\u0628\u06d5".split("_"),weekdaysShort:"\u064a\u06d5_\u062f\u06c8_\u0633\u06d5_\u0686\u0627_\u067e\u06d5_\u062c\u06c8_\u0634\u06d5".split("_"),weekdaysMin:"\u064a\u06d5_\u062f\u06c8_\u0633\u06d5_\u0686\u0627_\u067e\u06d5_\u062c\u06c8_\u0634\u06d5".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649",LLL:"YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649\u060c HH:mm",LLLL:"dddd\u060c YYYY-\u064a\u0649\u0644\u0649M-\u0626\u0627\u064a\u0646\u0649\u06adD-\u0643\u06c8\u0646\u0649\u060c HH:mm"},meridiemParse:/\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5|\u0633\u06d5\u06be\u06d5\u0631|\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646|\u0686\u06c8\u0634|\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646|\u0643\u06d5\u0686/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5"===a||"\u0633\u06d5\u06be\u06d5\u0631"===a||"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646"===a?e:"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646"===a||"\u0643\u06d5\u0686"===a?e+12:11<=e?e:e+12},meridiem:function(e,a,t){var s=100*e+a;return s<600?"\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5":s<900?"\u0633\u06d5\u06be\u06d5\u0631":s<1130?"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646":s<1230?"\u0686\u06c8\u0634":s<1800?"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646":"\u0643\u06d5\u0686"},calendar:{sameDay:"[\u0628\u06c8\u06af\u06c8\u0646 \u0633\u0627\u0626\u06d5\u062a] LT",nextDay:"[\u0626\u06d5\u062a\u06d5 \u0633\u0627\u0626\u06d5\u062a] LT",nextWeek:"[\u0643\u06d0\u0644\u06d5\u0631\u0643\u0649] dddd [\u0633\u0627\u0626\u06d5\u062a] LT",lastDay:"[\u062a\u06c6\u0646\u06c8\u06af\u06c8\u0646] LT",lastWeek:"[\u0626\u0627\u0644\u062f\u0649\u0646\u0642\u0649] dddd [\u0633\u0627\u0626\u06d5\u062a] LT",sameElse:"L"},relativeTime:{future:"%s \u0643\u06d0\u064a\u0649\u0646",past:"%s \u0628\u06c7\u0631\u06c7\u0646",s:"\u0646\u06d5\u0686\u0686\u06d5 \u0633\u06d0\u0643\u0648\u0646\u062a",ss:"%d \u0633\u06d0\u0643\u0648\u0646\u062a",m:"\u0628\u0649\u0631 \u0645\u0649\u0646\u06c7\u062a",mm:"%d \u0645\u0649\u0646\u06c7\u062a",h:"\u0628\u0649\u0631 \u0633\u0627\u0626\u06d5\u062a",hh:"%
51149d \u0633\u0627\u0626\u06d5\u062a",d:"\u0628\u0649\u0631 \u0643\u06c8\u0646",dd:"%d \u0643\u06c8\u0646",M:"\u0628\u0649\u0631 \u0626\u0627\u064a",MM:"%d \u0626\u0627\u064a",y:"\u0628\u0649\u0631 \u064a\u0649\u0644",yy:"%d \u064a\u0649\u0644"},dayOfMonthOrdinalParse:/\d{1,2}(-\u0643\u06c8\u0646\u0649|-\u0626\u0627\u064a|-\u06be\u06d5\u067e\u062a\u06d5)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"-\u0643\u06c8\u0646\u0649";case"w":case"W":return e+"-\u06be\u06d5\u067e\u062a\u06d5";default:return e}},preparse:function(e){return e.replace(/\u060c/g,",")},postformat:function(e){return e.replace(/,/g,"\u060c")},week:{dow:1,doy:7}}),l.defineLocale("uk",{months:{format:"\u0441\u0456\u0447\u043d\u044f_\u043b\u044e\u0442\u043e\u0433\u043e_\u0431\u0435\u0440\u0435\u0437\u043d\u044f_\u043a\u0432\u0456\u0442\u043d\u044f_\u0442\u0440\u0430\u0432\u043d\u044f_\u0447\u0435\u0440\u0432\u043d\u044f_\u043b\u0438\u043f\u043d\u044f_\u0441\u0435\u0440\u043f\u043d\u044f_\u0432\u0435\u0440\u0435\u0441\u043d\u044f_\u0436\u043e\u0432\u0442\u043d\u044f_\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430_\u0433\u0440\u0443\u0434\u043d\u044f".split("_"),standalone:"\u0441\u0456\u0447\u0435\u043d\u044c_\u043b\u044e\u0442\u0438\u0439_\u0431\u0435\u0440\u0435\u0437\u0435\u043d\u044c_\u043a\u0432\u0456\u0442\u0435\u043d\u044c_\u0442\u0440\u0430\u0432\u0435\u043d\u044c_\u0447\u0435\u0440\u0432\u0435\u043d\u044c_\u043b\u0438\u043f\u0435\u043d\u044c_\u0441\u0435\u0440\u043f\u0435\u043d\u044c_\u0432\u0435\u0440\u0435\u0441\u0435\u043d\u044c_\u0436\u043e\u0432\u0442\u0435\u043d\u044c_\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434_\u0433\u0440\u0443\u0434\u0435\u043d\u044c".split("_")},monthsShort:"\u0441\u0456\u0447_\u043b\u044e\u0442_\u0431\u0435\u0440_\u043a\u0432\u0456\u0442_\u0442\u0440\u0430\u0432_\u0447\u0435\u0440\u0432_\u043b\u0438\u043f_\u0441\u0435\u0440\u043f_\u0432\u0435\u0440_\u0436\u043e\u0432\u0442_\u043b\u0438\u0441\u0442_\u0433\u0440\u0443\u0434".split("_"),weekdays:function(e,a){var t={nominative:"\u043d\u0435\u0434\u0456\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a_\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a_\u0441\u0435\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0435\u0440_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u044f_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),accusative:"\u043d\u0435\u0434\u0456\u043b\u044e_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a_\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a_\u0441\u0435\u0440\u0435\u0434\u0443_\u0447\u0435\u0442\u0432\u0435\u0440_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u044e_\u0441\u0443\u0431\u043e\u0442\u0443".split("_"),genitive:"\u043d\u0435\u0434\u0456\u043b\u0456_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043a\u0430_\u0432\u0456\u0432\u0442\u043e\u0440\u043a\u0430_\u0441\u0435\u0440\u0435\u0434\u0438_\u0447\u0435\u0442\u0432\u0435\u0440\u0433\u0430_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u0456_\u0441\u0443\u0431\u043e\u0442\u0438".split("_")};return e?t[/(\[[\u0412\u0432\u0423\u0443]\]) ?dddd/.test(a)?"accusative":/\[?(?:\u043c\u0438\u043d\u0443\u043b\u043e\u0457|\u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u0457)? ?\] ?dddd/.test(a)?"genitive":"nominative"][e.day()]:t.nominative},weekdaysShort:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0440.",LLL:"D MMMM YYYY \u0440., HH:mm",LLLL:"dddd, D MMMM YYYY \u0440., HH:mm"},calendar:{sameDay:ed("[\u0421\u044c\u043e\u0433\u043e\u0434\u043d\u0456 "),nextDay:ed("[\u0417\u0430\u0432\u0442\u0440\u0430 "),lastDay:ed("[\u0412\u0447\u043e\u0440\u0430 "),nextWeek:ed("[\u0423] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return ed("[\u041c\u0438\u043d\u0443\u043b\u043e\u0457] dddd [").call(this);case 1:case 2:case 4:return ed("[\u041c\u0438\u043d\u0443\u043b\u043e\u0433\u043e] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"%s \u0442\u043e\u043c\u0443",s:"\u0434\u0435\u043a\u0456\u043b\u044c\u043a\u0430 \u0441\u0435\u043a\u0443\u043d\u0434",ss:Xn,m:Xn,mm:Xn,h:"\u0433\u043e\u0434\u0438\u043d\u0443",hh:Xn,d:"\u0434\u0435\u043d\u044c",dd:Xn,M:"\u043c\u0456\u0441\u044f\u0446\u044c",MM:Xn,y:"\u0440\u0456\u043a",yy:Xn},meridiemParse:/\u043d\u043e\u0447\u0456|\u0440\u0430\u043d\u043a\u0443|\u0434\u043d\u044f|\u0432\u0435\u0447\u043e\u0440\u0430/,isPM:function(e){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u043e\u0440\u0430)$/.test(e)},meridiem:function(e,a,t){return e<4?"\u043d\u043e\u0447\u0456":e<12?"\u0440\u0430\u043d\u043a\u0443":e<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u043e\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0439|\u0433\u043e)/,ordinal:function(e,a){switch(a){case"M":case"d":case"DDD":case"w":case"W":return e+"-\u0439";case"D":return e+"-\u0433\u043e";default:return e}},week:{dow:1,doy:7}});var ad=["\u062c\u0646\u0648\u0631\u06cc","\u0641\u0631\u0648\u0631\u06cc","\u0645\u0627\u0631\u0686","\u0627\u067e\u0631\u06cc\u0644","\u0645\u0626\u06cc","\u062c\u0648\u0646","\u062c\u0648\u0644\u0627\u0626\u06cc","\u0627\u06af\u0633\u062a","\u0633\u062a\u0645\u0628\u0631","\u0627\u06a9\u062a\u0648\u0628\u0631","\u0646\u0648\u0645\u0628\u0631","\u062f\u0633\u0645\u0628\u0631"],td=["\u0627\u062a\u0648\u0627\u0631","\u067e\u06cc\u0631","\u0645\u0646\u06af\u0644","\u0628\u062f\u06be","\u062c\u0645\u0639\u0631\u0627\u062a","\u062c\u0645\u0639\u06c1","\u06c1\u064
511491\u062a\u06c1"];return l.defineLocale("ur",{months:ad,monthsShort:ad,weekdays:td,weekdaysShort:td,weekdaysMin:td,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd\u060c D MMMM YYYY HH:mm"},meridiemParse:/\u0635\u0628\u062d|\u0634\u0627\u0645/,isPM:function(e){return"\u0634\u0627\u0645"===e},meridiem:function(e,a,t){return e<12?"\u0635\u0628\u062d":"\u0634\u0627\u0645"},calendar:{sameDay:"[\u0622\u062c \u0628\u0648\u0642\u062a] LT",nextDay:"[\u06a9\u0644 \u0628\u0648\u0642\u062a] LT",nextWeek:"dddd [\u0628\u0648\u0642\u062a] LT",lastDay:"[\u06af\u0630\u0634\u062a\u06c1 \u0631\u0648\u0632 \u0628\u0648\u0642\u062a] LT",lastWeek:"[\u06af\u0630\u0634\u062a\u06c1] dddd [\u0628\u0648\u0642\u062a] LT",sameElse:"L"},relativeTime:{future:"%s \u0628\u0639\u062f",past:"%s \u0642\u0628\u0644",s:"\u0686\u0646\u062f \u0633\u06cc\u06a9\u0646\u0688",ss:"%d \u0633\u06cc\u06a9\u0646\u0688",m:"\u0627\u06cc\u06a9 \u0645\u0646\u0679",mm:"%d \u0645\u0646\u0679",h:"\u0627\u06cc\u06a9 \u06af\u06be\u0646\u0679\u06c1",hh:"%d \u06af\u06be\u0646\u0679\u06d2",d:"\u0627\u06cc\u06a9 \u062f\u0646",dd:"%d \u062f\u0646",M:"\u0627\u06cc\u06a9 \u0645\u0627\u06c1",MM:"%d \u0645\u0627\u06c1",y:"\u0627\u06cc\u06a9 \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(e){return e.replace(/\u060c/g,",")},postformat:function(e){return e.replace(/,/g,"\u060c")},week:{dow:1,doy:4}}),l.defineLocale("uz-latn",{months:"Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr".split("_"),monthsShort:"Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek".split("_"),weekdays:"Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba".split("_"),weekdaysShort:"Yak_Dush_Sesh_Chor_Pay_Jum_Shan".split("_"),weekdaysMin:"Ya_Du_Se_Cho_Pa_Ju_Sha".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Bugun soat] LT [da]",nextDay:"[Ertaga] LT [da]",nextWeek:"dddd [kuni soat] LT [da]",lastDay:"[Kecha soat] LT [da]",lastWeek:"[O'tgan] dddd [kuni soat] LT [da]",sameElse:"L"},relativeTime:{future:"Yaqin %s ichida",past:"Bir necha %s oldin",s:"soniya",ss:"%d soniya",m:"bir daqiqa",mm:"%d daqiqa",h:"bir soat",hh:"%d soat",d:"bir kun",dd:"%d kun",M:"bir oy",MM:"%d oy",y:"bir yil",yy:"%d yil"},week:{dow:1,doy:7}}),l.defineLocale("uz",{months:"\u044f\u043d\u0432\u0430\u0440_\u0444\u0435\u0432\u0440\u0430\u043b_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440_\u043e\u043a\u0442\u044f\u0431\u0440_\u043d\u043e\u044f\u0431\u0440_\u0434\u0435\u043a\u0430\u0431\u0440".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u042f\u043a\u0448\u0430\u043d\u0431\u0430_\u0414\u0443\u0448\u0430\u043d\u0431\u0430_\u0421\u0435\u0448\u0430\u043d\u0431\u0430_\u0427\u043e\u0440\u0448\u0430\u043d\u0431\u0430_\u041f\u0430\u0439\u0448\u0430\u043d\u0431\u0430_\u0416\u0443\u043c\u0430_\u0428\u0430\u043d\u0431\u0430".split("_"),weekdaysShort:"\u042f\u043a\u0448_\u0414\u0443\u0448_\u0421\u0435\u0448_\u0427\u043e\u0440_\u041f\u0430\u0439_\u0416\u0443\u043c_\u0428\u0430\u043d".split("_"),weekdaysMin:"\u042f\u043a_\u0414\u0443_\u0421\u0435_\u0427\u043e_\u041f\u0430_\u0416\u0443_\u0428\u0430".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[\u0411\u0443\u0433\u0443\u043d \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",nextDay:"[\u042d\u0440\u0442\u0430\u0433\u0430] LT [\u0434\u0430]",nextWeek:"dddd [\u043a\u0443\u043d\u0438 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",lastDay:"[\u041a\u0435\u0447\u0430 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",lastWeek:"[\u0423\u0442\u0433\u0430\u043d] dddd [\u043a\u0443\u043d\u0438 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",sameElse:"L"},relativeTime:{future:"\u042f\u043a\u0438\u043d %s \u0438\u0447\u0438\u0434\u0430",past:"\u0411\u0438\u0440 \u043d\u0435\u0447\u0430 %s \u043e\u043b\u0434\u0438\u043d",s:"\u0444\u0443\u0440\u0441\u0430\u0442",ss:"%d \u0444\u0443\u0440\u0441\u0430\u0442",m:"\u0431\u0438\u0440 \u0434\u0430\u043a\u0438\u043a\u0430",mm:"%d \u0434\u0430\u043a\u0438\u043a\u0430",h:"\u0431\u0438\u0440 \u0441\u043e\u0430\u0442",hh:"%d \u0441\u043e\u0430\u0442",d:"\u0431\u0438\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u0431\u0438\u0440 \u043e\u0439",MM:"%d \u043e\u0439",y:"\u0431\u0438\u0440 \u0439\u0438\u043b",yy:"%d \u0439\u0438\u043b"},week:{dow:1,doy:7}}),l.defineLocale("vi",{months:"th\xe1ng 1_th\xe1ng 2_th\xe1ng 3_th\xe1ng 4_th\xe1ng 5_th\xe1ng 6_th\xe1ng 7_th\xe1ng 8_th\xe1ng 9_th\xe1ng 10_th\xe1ng 11_th\xe1ng 12".split("_"),monthsShort:"Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),monthsParseExact:!0,weekdays:"ch\u1ee7 nh\u1eadt_th\u1ee9 hai_th\u1ee9 ba_th\u1ee9 t\u01b0_th\u1ee9 n\u0103m_th\u1ee9 s\xe1u_th\u1ee9 b\u1ea3y".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysParseExact:!0,meridiemParse:/sa|ch/i,isPM:function(e){return/^ch$/i.test(e)}
vendor: 4,189 bytes, line 51149
51149,meridiem:function(e,a,t){return e<12?t?"sa":"SA":t?"ch":"CH"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [n\u0103m] YYYY",LLL:"D MMMM [n\u0103m] YYYY HH:mm",LLLL:"dddd, D MMMM [n\u0103m] YYYY HH:mm",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[H\xf4m nay l\xfac] LT",nextDay:"[Ng\xe0y mai l\xfac] LT",nextWeek:"dddd [tu\u1ea7n t\u1edbi l\xfac] LT",lastDay:"[H\xf4m qua l\xfac] LT",lastWeek:"dddd [tu\u1ea7n r\u1ed3i l\xfac] LT",sameElse:"L"},relativeTime:{future:"%s t\u1edbi",past:"%s tr\u01b0\u1edbc",s:"v\xe0i gi\xe2y",ss:"%d gi\xe2y",m:"m\u1ed9t ph\xfat",mm:"%d ph\xfat",h:"m\u1ed9t gi\u1edd",hh:"%d gi\u1edd",d:"m\u1ed9t ng\xe0y",dd:"%d ng\xe0y",M:"m\u1ed9t th\xe1ng",MM:"%d th\xe1ng",y:"m\u1ed9t n\u0103m",yy:"%d n\u0103m"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}}),l.defineLocale("x-pseudo",{months:"J~\xe1\xf1\xfa\xe1~r\xfd_F~\xe9br\xfa~\xe1r\xfd_~M\xe1rc~h_\xc1p~r\xedl_~M\xe1\xfd_~J\xfa\xf1\xe9~_J\xfal~\xfd_\xc1\xfa~g\xfast~_S\xe9p~t\xe9mb~\xe9r_\xd3~ct\xf3b~\xe9r_\xd1~\xf3v\xe9m~b\xe9r_~D\xe9c\xe9~mb\xe9r".split("_"),monthsShort:"J~\xe1\xf1_~F\xe9b_~M\xe1r_~\xc1pr_~M\xe1\xfd_~J\xfa\xf1_~J\xfal_~\xc1\xfag_~S\xe9p_~\xd3ct_~\xd1\xf3v_~D\xe9c".split("_"),monthsParseExact:!0,weekdays:"S~\xfa\xf1d\xe1~\xfd_M\xf3~\xf1d\xe1\xfd~_T\xfa\xe9~sd\xe1\xfd~_W\xe9d~\xf1\xe9sd~\xe1\xfd_T~h\xfars~d\xe1\xfd_~Fr\xedd~\xe1\xfd_S~\xe1t\xfar~d\xe1\xfd".split("_"),weekdaysShort:"S~\xfa\xf1_~M\xf3\xf1_~T\xfa\xe9_~W\xe9d_~Th\xfa_~Fr\xed_~S\xe1t".split("_"),weekdaysMin:"S~\xfa_M\xf3~_T\xfa_~W\xe9_T~h_Fr~_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[T~\xf3d\xe1~\xfd \xe1t] LT",nextDay:"[T~\xf3m\xf3~rr\xf3~w \xe1t] LT",nextWeek:"dddd [\xe1t] LT",lastDay:"[\xdd~\xe9st~\xe9rd\xe1~\xfd \xe1t] LT",lastWeek:"[L~\xe1st] dddd [\xe1t] LT",sameElse:"L"},relativeTime:{future:"\xed~\xf1 %s",past:"%s \xe1~g\xf3",s:"\xe1 ~f\xe9w ~s\xe9c\xf3~\xf1ds",ss:"%d s~\xe9c\xf3\xf1~ds",m:"\xe1 ~m\xed\xf1~\xfat\xe9",mm:"%d m~\xed\xf1\xfa~t\xe9s",h:"\xe1~\xf1 h\xf3~\xfar",hh:"%d h~\xf3\xfars",d:"\xe1 ~d\xe1\xfd",dd:"%d d~\xe1\xfds",M:"\xe1 ~m\xf3\xf1~th",MM:"%d m~\xf3\xf1t~hs",y:"\xe1 ~\xfd\xe9\xe1r",yy:"%d \xfd~\xe9\xe1rs"},dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var a=e%10;return e+(1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th")},week:{dow:1,doy:4}}),l.defineLocale("yo",{months:"S\u1eb9\u0301r\u1eb9\u0301_E\u0300re\u0300le\u0300_\u1eb8r\u1eb9\u0300na\u0300_I\u0300gbe\u0301_E\u0300bibi_O\u0300ku\u0300du_Ag\u1eb9mo_O\u0300gu\u0301n_Owewe_\u1ecc\u0300wa\u0300ra\u0300_Be\u0301lu\u0301_\u1ecc\u0300p\u1eb9\u0300\u0300".split("_"),monthsShort:"S\u1eb9\u0301r_E\u0300rl_\u1eb8rn_I\u0300gb_E\u0300bi_O\u0300ku\u0300_Ag\u1eb9_O\u0300gu\u0301_Owe_\u1ecc\u0300wa\u0300_Be\u0301l_\u1ecc\u0300p\u1eb9\u0300\u0300".split("_"),weekdays:"A\u0300i\u0300ku\u0301_Aje\u0301_I\u0300s\u1eb9\u0301gun_\u1eccj\u1ecd\u0301ru\u0301_\u1eccj\u1ecd\u0301b\u1ecd_\u1eb8ti\u0300_A\u0300ba\u0301m\u1eb9\u0301ta".split("_"),weekdaysShort:"A\u0300i\u0300k_Aje\u0301_I\u0300s\u1eb9\u0301_\u1eccjr_\u1eccjb_\u1eb8ti\u0300_A\u0300ba\u0301".split("_"),weekdaysMin:"A\u0300i\u0300_Aj_I\u0300s_\u1eccr_\u1eccb_\u1eb8t_A\u0300b".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[O\u0300ni\u0300 ni] LT",nextDay:"[\u1ecc\u0300la ni] LT",nextWeek:"dddd [\u1eccs\u1eb9\u0300 to\u0301n'b\u1ecd] [ni] LT",lastDay:"[A\u0300na ni] LT",lastWeek:"dddd [\u1eccs\u1eb9\u0300 to\u0301l\u1ecd\u0301] [ni] LT",sameElse:"L"},relativeTime:{future:"ni\u0301 %s",past:"%s k\u1ecdja\u0301",s:"i\u0300s\u1eb9ju\u0301 aaya\u0301 die",ss:"aaya\u0301 %d",m:"i\u0300s\u1eb9ju\u0301 kan",mm:"i\u0300s\u1eb9ju\u0301 %d",h:"wa\u0301kati kan",hh:"wa\u0301kati %d",d:"\u1ecdj\u1ecd\u0301 kan",dd:"\u1ecdj\u1ecd\u0301 %d",M:"osu\u0300 kan",MM:"osu\u0300 %d",y:"\u1ecddu\u0301n kan",yy:"\u1ecddu\u0301n %d"},dayOfMonthOrdinalParse:/\u1ecdj\u1ecd\u0301\s\d{1,2}
51149/,ordinal:"\u1ecdj\u1ecd\u0301 %d",week:{dow:1,doy:4}}),l.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u5468\u65e5_\u5468\u4e00_\u5468\u4e8c_\u5468\u4e09_\u5468\u56db_\u5468\u4e94_\u5468\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5Ah\u70b9mm\u5206",LLLL:"YYYY\u5e74M\u6708D\u65e5ddddAh\u70b9mm\u5206",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u51cc\u6668"===a||"\u65e9\u4e0a"===a||"\u4e0a\u5348"===a?e:"\u4e0b\u5348"===a||"\u665a\u4e0a"===a?e+12:11<=e?e:e+12},meridiem:function(e,a,t){var s=100*e+a;return s<600?"\u51cc\u6668":s<900?"\u65e9\u4e0a":s<1130?"\u4e0a\u5348":s<1230?"\u4e2d\u5348":s<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u5468)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"\u65e5";case"M":return e+"\u6708";case"w":case"W":return e+"\u5468";default:return e}},relativeTime:{future:"%s\u5185",past:"%s\u524d",s:"\u51e0\u79d2",ss:"%d \u79d2",m:"1 \u5206\u949f",mm:"%d \u5206\u949f",h:"1 \u5c0f\u65f6",hh:"%d \u5c0f\u65f6",d:"1 \u5929",dd:"%d \u5929",M:"1 \u4e2a\u6708",MM:"%d \u4e2a\u6708",y:"1 \u5e74",yy:"%d \u5e74"},week:{dow:1,doy:4}}),l.defineLocale("zh-hk",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u51cc\u6668"===a||"\u65e9\u4e0a"===a||"\u4e0a\u5348"===a?e:"\u4e2d\u5348"===a?11<=e?e:e+12:"\u4e0b\u5348"===a||"\u665a\u4e0a"===a?e+12:void 0},meridiem:function(e,a,t){var s=100*e+a;return s<600?"\u51cc\u6668":s<900?"\u65e9\u4e0a":s<1130?"\u4e0a\u5348":s<1230?"\u4e2d\u5348":s<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"\u65e5";case"M":return e+"\u6708";case"w":case"W":return e+"\u9031";default:return e}},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}}),l.defineLocale("zh-tw",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(e,a){return 12===e&&(e=0),"\u51cc\u6668"===a||"\u65e9\u4e0a"===a||"\u4e0a\u5348"===a?e:"\u4e2d\u5348"===a?11<=e?e:e+12:"\u4e0b\u5348"===a||"\u665a\u4e0a"===a?e+12:void 0},meridiem:function(e,a,t){var s=100*e+a;return s<600?"\u51cc\u6668":s<900?"\u65e9\u4e0a":s<1130?"\u4e0a\u5348":s<1230?"\u4e2d\u5348":s<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929] LT",nextDay:"[\u660e\u5929] LT",nextWeek:"[\u4e0b]dddd LT",lastDay:"[\u6628\u5929] LT",lastWeek:"[\u4e0a]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"\u65e5";case"M":return e+"\u6708";case"w":case"W":return e+"\u9031";default:return e}},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}}),l.locale("en"),l}); 51150;/*! 51151 * FullCalendar v3.9.0 51152 * Docs & License: https://fullcalendar.io/ 51153 * (c) 2018 Adam Shaw 51154 */ 51155(function webpackUniversalModuleDefinition(root, factory) { 51156 if(typeof exports === 'object' && typeof module === 'object') 51157 module.exports = factory(require("moment"), require("jquery")); 51158 else if(typeof define === 'function' && define.amd) 51159 define(["moment", "jquery"], factory); 51160 else if(typeof exports === 'object') 51161 exports["FullCalendar"] = factory(require("moment"), require("jquery")); 51162 else 51163 root["FullCalendar"] = factory(root["moment"], root["jQuery"]); 51164})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_3__) { 51165return /******/ (function(modules) { // webpackBootstrap 51166/******/ // The module cache 51167/******/ var installedModules = {}; 51168/******/ 51169/******/ // The require function 51170/******/ function __webpack_require__(moduleId) { 51171/******/ 51172/******/ // Check if module is in cache 51173/******/ if(installedModules[moduleId]) { 51174/******/ return installedModules[moduleId].exports; 51175/******/ } 51176/******/ // Create a new module (and put it into the cache) 51177/******/ var module = installedModules[moduleId] = { 51178/******/ i: moduleId, 51179/******/ l: false, 51180/******/ exports: {} 51181/******/ }; 51182/******/ 51183/******/ // Execute the module function 51184/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 51185/******/ 51186/******/ // Flag the module as loaded
51187/******/ module.l = true; 51188/******/ 51189/******/ // Return the exports of the module 51190/******/ return module.exports; 51191/******/ } 51192/******/ 51193/******/ 51194/******/ // expose the modules object (__webpack_modules__) 51195/******/ __webpack_require__.m = modules; 51196/******/ 51197/******/ // expose the module cache 51198/******/ __webpack_require__.c = installedModules; 51199/******/ 51200/******/ // define getter function for harmony exports 51201/******/ __webpack_require__.d = function(exports, name, getter) { 51202/******/ if(!__webpack_require__.o(exports, name)) { 51203/******/ Object.defineProperty(exports, name, { 51204/******/ configurable: false, 51205/******/ enumerable: true, 51206/******/ get: getter 51207/******/ }); 51208/******/ } 51209/******/ }; 51210/******/ 51211/******/ // getDefaultExport function for compatibility with non-harmony modules 51212/******/ __webpack_require__.n = function(module) { 51213/******/ var getter = module && module.__esModule ? 51214/******/ function getDefault() { return module['default']; } : 51215/******/ function getModuleExports() { return module; }; 51216/******/ __webpack_require__.d(getter, 'a', getter); 51217/******/ return getter; 51218/******/ }; 51219/******/ 51220/******/ // Object.prototype.hasOwnProperty.call 51221/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 51222/******/ 51223/******/ // __webpack_public_path__ 51224/******/ __webpack_require__.p = ""; 51225/******/ 51226/******/ // Load entry module and return exports 51227/******/ return __webpack_require__(__webpack_require__.s = 236); 51228/******/ }) 51229/************************************************************************/ 51230/******/ ([ 51231/* 0 */ 51232/***/ (function(module, exports) { 51233 51234module.exports = __WEBPACK_EXTERNAL_MODULE_0__; 51235 51236/***/ }), 51237/* 1 */, 51238/* 2 */ 51239/***/ (function(module, exports) { 51240 51241/* 51242derived from: 51243https://github.com/Microsoft/tslib/blob/v1.6.0/tslib.js 51244 51245only include the helpers we need, to keep down filesize 51246*/ 51247var extendStatics = Object.setPrototypeOf || 51248 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 51249 function (d, b) { for (var p in b) 51250 if (b.hasOwnProperty(p)) 51251 d[p] = b[p]; }; 51252exports.__extends = function (d, b) { 51253 extendStatics(d, b); 51254 function __() { this.constructor = d; } 51255 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 51256}; 51257 51258 51259/***/ }), 51260/* 3 */ 51261/***/ (function(module, exports) { 51262 51263module.exports = __WEBPACK_EXTERNAL_MODULE_3__; 51264 51265/***/ }), 51266/* 4 */ 51267/***/ (function(module, exports, __webpack_require__) { 51268 51269Object.defineProperty(exports, "__esModule", { value: true }); 51270var moment = __webpack_require__(0); 51271var $ = __webpack_require__(3); 51272/* FullCalendar-specific DOM Utilities 51273----------------------------------------------------------------------------------------------------------------------*/ 51274// Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left 51275// and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that. 51276function compensateScroll(rowEls, scrollbarWidths) { 51277 if (scrollbarWidths.left) { 51278 rowEls.css({ 51279 'border-left-width': 1, 51280 'margin-left': scrollbarWidths.left - 1 51281 }); 51282 } 51283 if (scrollbarWidths.right) { 51284 rowEls.css({ 51285 'border-right-width': 1, 51286 'margin-right': scrollbarWidths.right - 1 51287 }); 51288 } 51289} 51290exports.compensateScroll = compensateScroll; 51291// Undoes compensateScroll and restores all borders/margins 51292function uncompensateScroll(rowEls) { 51293 rowEls.css({ 51294 'margin-left': '', 51295 'margin-right': '', 51296 'border-left-width': '', 51297 'border-right-width': '' 51298 }); 51299} 51300exports.uncompensateScroll = uncompensateScroll; 51301// Make the mouse cursor express that an event is not allowed in the current area 51302function disableCursor() { 51303 $('body').addClass('fc-not-allowed'); 51304} 51305exports.disableCursor = disableCursor; 51306// Returns the mouse cursor to its original look 51307function enableCursor() { 51308 $('body').removeClass('fc-not-allowed'); 51309} 51310exports.enableCursor = enableCursor; 51311// Given a total available height to fill, have `els` (essentially child rows) expand to accomodate. 51312// By default, all elements that are shorter than the recommended height are expanded uniformly, not considering 51313// any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and 51314// reduces the available height. 51315function distributeHeight(els, availableHeight, shouldRedistribute) { 51316 // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions, 51317 // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars. 51318 var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element 51319 var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE* 51320 var flexEls = []; // elements that are allowed to expand. array of DOM nodes 51321 var flexOffsets = []; // amount of vertical space it takes up 51322 var flexHeights = []; // actual css height 51323 var usedHeight = 0; 51324 undistributeHeight(els); // give all elements their natural height 51325 // find elements that are below the recommended height (expandable). 51326 // important to query for heights in a single first pass (to avoid reflow oscillation). 51327 els.each(function (i, el) { 51328 var minOffset = i === els.length - 1 ? minOffset2 : minOffset1; 51329 var naturalOffset = $(el).outerHeight(true); 51330 if (naturalOffset < minOffset) { 51331 flexEls.push(el); 51332 flexOffsets.push(naturalOffset); 51333 flexHeights.push($(el).height()); 51334 } 51335 else { 51336 // this element stretches past recommended height (non-expandable). mark the space as occupied. 51337 usedHeight += naturalOffset; 51338 } 51339 });
51340 // readjust the recommended height to only consider the height available to non-maxed-out rows. 51341 if (shouldRedistribute) { 51342 availableHeight -= usedHeight; 51343 minOffset1 = Math.floor(availableHeight / flexEls.length); 51344 minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE* 51345 } 51346 // assign heights to all expandable elements 51347 $(flexEls).each(function (i, el) { 51348 var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1; 51349 var naturalOffset = flexOffsets[i]; 51350 var naturalHeight = flexHeights[i]; 51351 var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding 51352 if (naturalOffset < minOffset) { 51353 $(el).height(newHeight); 51354 } 51355 }); 51356} 51357exports.distributeHeight = distributeHeight; 51358// Undoes distrubuteHeight, restoring all els to their natural height 51359function undistributeHeight(els) { 51360 els.height(''); 51361} 51362exports.undistributeHeight = undistributeHeight; 51363// Given `els`, a jQuery set of <td> cells, find the cell with the largest natural width and set the widths of all the 51364// cells to be that width. 51365// PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline 51366function matchCellWidths(els) { 51367 var maxInnerWidth = 0; 51368 els.find('> *').each(function (i, innerEl) { 51369 var innerWidth = $(innerEl).outerWidth(); 51370 if (innerWidth > maxInnerWidth) { 51371 maxInnerWidth = innerWidth; 51372 } 51373 }); 51374 maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance 51375 els.width(maxInnerWidth); 51376 return maxInnerWidth; 51377} 51378exports.matchCellWidths = matchCellWidths; 51379// Given one element that resides inside another, 51380// Subtracts the height of the inner element from the outer element. 51381function subtractInnerElHeight(outerEl, innerEl) { 51382 var both = outerEl.add(innerEl); 51383 var diff; 51384 // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked 51385 both.css({ 51386 position: 'relative', 51387 left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll 51388 }); 51389 diff = outerEl.outerHeight() - innerEl.outerHeight(); // grab the dimensions 51390 both.css({ position: '', left: '' }); // undo hack 51391 return diff; 51392} 51393exports.subtractInnerElHeight = subtractInnerElHeight; 51394/* Element Geom Utilities 51395----------------------------------------------------------------------------------------------------------------------*/ 51396// borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51 51397function getScrollParent(el) { 51398 var position = el.css('position'); 51399 var scrollParent = el.parents().filter(function () { 51400 var parent = $(this); 51401 return (/(auto|scroll)/).test(parent.css('overflow') + parent.css('overflow-y') + parent.css('overflow-x')); 51402 }).eq(0); 51403 return position === 'fixed' || !scrollParent.length ? $(el[0].ownerDocument || document) : scrollParent; 51404} 51405exports.getScrollParent = getScrollParent; 51406// Queries the outer bounding area of a jQuery element. 51407// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). 51408// Origin is optional. 51409function getOuterRect(el, origin) { 51410 var offset = el.offset(); 51411 var left = offset.left - (origin ? origin.left : 0); 51412 var top = offset.top - (origin ? origin.top : 0); 51413 return { 51414 left: left, 51415 right: left + el.outerWidth(), 51416 top: top, 51417 bottom: top + el.outerHeight() 51418 }; 51419} 51420exports.getOuterRect = getOuterRect; 51421// Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding. 51422// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). 51423// Origin is optional. 51424// WARNING: given element can't have borders 51425// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser. 51426function getClientRect(el, origin) { 51427 var offset = el.offset();
51428 var scrollbarWidths = getScrollbarWidths(el); 51429 var left = offset.left + getCssFloat(el, 'border-left-width') + scrollbarWidths.left - (origin ? origin.left : 0); 51430 var top = offset.top + getCssFloat(el, 'border-top-width') + scrollbarWidths.top - (origin ? origin.top : 0); 51431 return { 51432 left: left, 51433 right: left + el[0].clientWidth, 51434 top: top, 51435 bottom: top + el[0].clientHeight // clientHeight includes padding but NOT scrollbars 51436 }; 51437} 51438exports.getClientRect = getClientRect; 51439// Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars. 51440// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). 51441// Origin is optional. 51442function getContentRect(el, origin) { 51443 var offset = el.offset(); // just outside of border, margin not included 51444 var left = offset.left + getCssFloat(el, 'border-left-width') + getCssFloat(el, 'padding-left') - 51445 (origin ? origin.left : 0); 51446 var top = offset.top + getCssFloat(el, 'border-top-width') + getCssFloat(el, 'padding-top') - 51447 (origin ? origin.top : 0); 51448 return { 51449 left: left, 51450 right: left + el.width(), 51451 top: top, 51452 bottom: top + el.height() 51453 }; 51454} 51455exports.getContentRect = getContentRect; 51456// Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element. 51457// WARNING: given element can't have borders (which will cause offsetWidth/offsetHeight to be larger). 51458// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser. 51459function getScrollbarWidths(el) { 51460 var leftRightWidth = el[0].offsetWidth - el[0].clientWidth; 51461 var bottomWidth = el[0].offsetHeight - el[0].clientHeight; 51462 var widths; 51463 leftRightWidth = sanitizeScrollbarWidth(leftRightWidth); 51464 bottomWidth = sanitizeScrollbarWidth(bottomWidth); 51465 widths = { left: 0, right: 0, top: 0, bottom: bottomWidth }; 51466 if (getIsLeftRtlScrollbars() && el.css('direction') === 'rtl') { 51467 widths.left = leftRightWidth; 51468 } 51469 else { 51470 widths.right = leftRightWidth; 51471 } 51472 return widths; 51473} 51474exports.getScrollbarWidths = getScrollbarWidths; 51475// The scrollbar width computations in getScrollbarWidths are sometimes flawed when it comes to 51476// retina displays, rounding, and IE11. Massage them into a usable value. 51477function sanitizeScrollbarWidth(width) { 51478 width = Math.max(0, width); // no negatives 51479 width = Math.round(width); 51480 return width; 51481} 51482// Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side 51483var _isLeftRtlScrollbars = null; 51484function getIsLeftRtlScrollbars() { 51485 if (_isLeftRtlScrollbars === null) { 51486 _isLeftRtlScrollbars = computeIsLeftRtlScrollbars(); 51487 } 51488 return _isLeftRtlScrollbars; 51489} 51490function computeIsLeftRtlScrollbars() { 51491 var el = $('<div><div/></div>') 51492 .css({ 51493 position: 'absolute', 51494 top: -1000, 51495 left: 0, 51496 border: 0, 51497 padding: 0, 51498 overflow: 'scroll', 51499 direction: 'rtl' 51500 }) 51501 .appendTo('body'); 51502 var innerEl = el.children(); 51503 var res = innerEl.offset().left > el.offset().left; // is the inner div shifted to accommodate a left scrollbar? 51504 el.remove(); 51505 return res; 51506} 51507// Retrieves a jQuery element's computed CSS value as a floating-point number. 51508// If the queried value is non-numeric (ex: IE can return "medium" for border width), will just return zero. 51509function getCssFloat(el, prop) { 51510 return parseFloat(el.css(prop)) || 0; 51511} 51512/* Mouse / Touch Utilities 51513----------------------------------------------------------------------------------------------------------------------*/ 51514// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) 51515function isPrimaryMouseButton(ev) { 51516 return ev.which === 1 && !ev.ctrlKey; 51517} 51518exports.isPrimaryMouseButton = isPrimaryMouseButton; 51519function getEvX(ev) { 51520 var touches = ev.originalEvent.touches; 51521 // on mobile FF, pageX for touch events is present, but incorrect, 51522 // so, look at touch coordinates first. 51523 if (touches && touches.length) { 51524 return touches[0].pageX; 51525 } 51526 return ev.pageX; 51527} 51528exports.getEvX = getEvX; 51529function getEvY(ev) { 51530 var touches = ev.originalEvent.touches; 51531 // on mobile FF, pageX for touch events is present, but incorrect, 51532 // so, look at touch coordinates first. 51533 if (touches && touches.length) { 51534 return touches[0].pageY; 51535 } 51536 return ev.pageY; 51537} 51538exports.getEvY = getEvY; 51539function getEvIsTouch(ev) { 51540 return /^touch/.test(ev.type); 51541} 51542exports.getEvIsTouch = getEvIsTouch; 51543function preventSelection(el) { 51544 el.addClass('fc-unselectable') 51545 .on('selectstart', preventDefault); 51546} 51547exports.preventSelection = preventSelection; 51548function allowSelection(el) { 51549 el.removeClass('fc-unselectable') 51550 .off('selectstart', preventDefault); 51551} 51552exports.allowSelection = allowSelection; 51553// Stops a mouse/touch event from doing it's native browser action 51554function preventDefault(ev) { 51555 ev.preventDefault(); 51556} 51557exports.preventDefault = preventDefault; 51558/* General Geometry Utils 51559----------------------------------------------------------------------------------------------------------------------*/ 51560// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false 51561function intersectRects(rect1, rect2) { 51562 var res = { 51563 left: Math.max(rect1.left, rect2.left), 51564 right: Math.min(rect1.right, rect2.right), 51565 top: Math.max(rect1.top, rect2.top), 51566 bottom: Math.min(rect1.bottom, rect2.bottom) 51567 }; 51568 if (res.left < res.right && res.top < res.bottom) { 51569 return res; 51570 } 51571 return false; 51572} 51573exports.intersectRects = intersectRects; 51574// Returns a new point that will have been moved to reside within the given rectangle 51575function constrainPoint(point, rect) { 51576 return { 51577 left: Math.min(Math.max(point.left, rect.left), rect.right),
51578 top: Math.min(Math.max(point.top, rect.top), rect.bottom) 51579 }; 51580} 51581exports.constrainPoint = constrainPoint; 51582// Returns a point that is the center of the given rectangle 51583function getRectCenter(rect) { 51584 return { 51585 left: (rect.left + rect.right) / 2, 51586 top: (rect.top + rect.bottom) / 2 51587 }; 51588} 51589exports.getRectCenter = getRectCenter; 51590// Subtracts point2's coordinates from point1's coordinates, returning a delta 51591function diffPoints(point1, point2) { 51592 return { 51593 left: point1.left - point2.left, 51594 top: point1.top - point2.top 51595 }; 51596} 51597exports.diffPoints = diffPoints; 51598/* Object Ordering by Field 51599----------------------------------------------------------------------------------------------------------------------*/ 51600function parseFieldSpecs(input) { 51601 var specs = []; 51602 var tokens = []; 51603 var i; 51604 var token; 51605 if (typeof input === 'string') { 51606 tokens = input.split(/\s*,\s*/); 51607 } 51608 else if (typeof input === 'function') { 51609 tokens = [input]; 51610 } 51611 else if ($.isArray(input)) { 51612 tokens = input; 51613 } 51614 for (i = 0; i < tokens.length; i++) { 51615 token = tokens[i]; 51616 if (typeof token === 'string') { 51617 specs.push(token.charAt(0) === '-' ? 51618 { field: token.substring(1), order: -1 } : 51619 { field: token, order: 1 }); 51620 } 51621 else if (typeof token === 'function') { 51622 specs.push({ func: token }); 51623 } 51624 } 51625 return specs; 51626} 51627exports.parseFieldSpecs = parseFieldSpecs; 51628function compareByFieldSpecs(obj1, obj2, fieldSpecs, obj1fallback, obj2fallback) { 51629 var i; 51630 var cmp; 51631 for (i = 0; i < fieldSpecs.length; i++) { 51632 cmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i], obj1fallback, obj2fallback); 51633 if (cmp) { 51634 return cmp; 51635 } 51636 } 51637 return 0; 51638} 51639exports.compareByFieldSpecs = compareByFieldSpecs; 51640function compareByFieldSpec(obj1, obj2, fieldSpec, obj1fallback, obj2fallback) { 51641 if (fieldSpec.func) { 51642 return fieldSpec.func(obj1, obj2); 51643 } 51644 var val1 = obj1[fieldSpec.field]; 51645 var val2 = obj2[fieldSpec.field]; 51646 if (val1 == null && obj1fallback) { 51647 val1 = obj1fallback[fieldSpec.field]; 51648 } 51649 if (val2 == null && obj2fallback) { 51650 val2 = obj2fallback[fieldSpec.field]; 51651 } 51652 return flexibleCompare(val1, val2) * (fieldSpec.order || 1); 51653} 51654exports.compareByFieldSpec = compareByFieldSpec; 51655function flexibleCompare(a, b) { 51656 if (!a && !b) { 51657 return 0; 51658 } 51659 if (b == null) { 51660 return -1; 51661 } 51662 if (a == null) { 51663 return 1; 51664 } 51665 if ($.type(a) === 'string' || $.type(b) === 'string') { 51666 return String(a).localeCompare(String(b)); 51667 } 51668 return a - b; 51669} 51670exports.flexibleCompare = flexibleCompare; 51671/* Date Utilities 51672----------------------------------------------------------------------------------------------------------------------*/ 51673exports.dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; 51674exports.unitsDesc = ['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
51674 // descending 51675// Diffs the two moments into a Duration where full-days are recorded first, then the remaining time. 51676// Moments will have their timezones normalized. 51677function diffDayTime(a, b) { 51678 return moment.duration({ 51679 days: a.clone().stripTime().diff(b.clone().stripTime(), 'days'), 51680 ms: a.time() - b.time() // time-of-day from day start. disregards timezone 51681 }); 51682} 51683exports.diffDayTime = diffDayTime; 51684// Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations. 51685function diffDay(a, b) { 51686 return moment.duration({ 51687 days: a.clone().stripTime().diff(b.clone().stripTime(), 'days') 51688 }); 51689} 51690exports.diffDay = diffDay; 51691// Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding. 51692function diffByUnit(a, b, unit) { 51693 return moment.duration(Math.round(a.diff(b, unit, true)), // returnFloat=true 51694 unit); 51695} 51696exports.diffByUnit = diffByUnit; 51697// Computes the unit name of the largest whole-unit period of time. 51698// For example, 48 hours will be "days" whereas 49 hours will be "hours". 51699// Accepts start/end, a range object, or an original duration object. 51700function computeGreatestUnit(start, end) { 51701 var i; 51702 var unit; 51703 var val; 51704 for (i = 0; i < exports.unitsDesc.length; i++) { 51705 unit = exports.unitsDesc[i]; 51706 val = computeRangeAs(unit, start, end); 51707 if (val >= 1 && isInt(val)) { 51708 break; 51709 } 51710 } 51711 return unit; // will be "milliseconds" if nothing else matches 51712} 51713exports.computeGreatestUnit = computeGreatestUnit; 51714// like computeGreatestUnit, but has special abilities to interpret the source input for clues 51715function computeDurationGreatestUnit(duration, durationInput) { 51716 var unit = computeGreatestUnit(duration); 51717 // prevent days:7 from being interpreted as a week 51718 if (unit === 'week' && typeof durationInput === 'object' && durationInput.days) { 51719 unit = 'day'; 51720 } 51721 return unit; 51722} 51723exports.computeDurationGreatestUnit = computeDurationGreatestUnit; 51724// Computes the number of units (like "hours") in the given range. 51725// Range can be a {start,end} object, separate start/end args, or a Duration. 51726// Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling 51727// of month-diffing logic (which tends to vary from version to version). 51728function computeRangeAs(unit, start, end) { 51729 if (end != null) { 51730 return end.diff(start, unit, true); 51731 } 51732 else if (moment.isDuration(start)) { 51733 return start.as(unit); 51734 } 51735 else { 51736 return start.end.diff(start.start, unit, true); 51737 } 51738} 51739// Intelligently divides a range (specified by a start/end params) by a duration 51740function divideRangeByDuration(start, end, dur) { 51741 var months; 51742 if (durationHasTime(dur)) { 51743 return (end - start) / dur; 51744 } 51745 months = dur.asMonths(); 51746 if (Math.abs(months) >= 1 && isInt(months)) { 51747 return end.diff(start, 'months', true) / months; 51748 } 51749 return end.diff(start, 'days', true) / dur.asDays(); 51750} 51751exports.divideRangeByDuration = divideRangeByDuration; 51752// Intelligently divides one duration by another 51753function divideDurationByDuration(dur1, dur2) { 51754 var months1; 51755 var months2; 51756 if (durationHasTime(dur1) || durationHasTime(dur2)) { 51757 return dur1 / dur2; 51758 } 51759 months1 = dur1.asMonths(); 51760 months2 = dur2.asMonths(); 51761 if (Math.abs(months1) >= 1 && isInt(months1) && 51762 Math.abs(months2) >= 1 && isInt(months2)) { 51763 return months1 / months2; 51764 } 51765 return dur1.asDays() / dur2.asDays(); 51766} 51767exports.divideDurationByDuration = divideDurationByDuration; 51768// Intelligently multiplies a duration by a number 51769function multiplyDuration(dur, n) { 51770 var months; 51771 if (durationHasTime(dur)) { 51772 return moment.duration(dur * n); 51773 } 51774 months = dur.asMonths(); 51775 if (Math.abs(months) >= 1 && isInt(months)) { 51776 return moment.duration({ months: months * n }); 51777 } 51778 return moment.duration({ days: dur.asDays() * n }); 51779} 51780exports.multiplyDuration = multiplyDuration; 51781// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms) 51782function durationHasTime(dur) { 51783 return Boolean(dur.hours() || dur.minutes() || dur.seconds() || dur.milliseconds()); 51784} 51785exports.durationHasTime = durationHasTime; 51786function isNativeDate(input) { 51787 return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date; 51788} 51789exports.isNativeDate = isNativeDate; 51790// Returns a boolean about whether the given input is a time string, like "06:40:00" or "06:00"
51791function isTimeString(str) { 51792 return typeof str === 'string' && 51793 /^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(str); 51794} 51795exports.isTimeString = isTimeString; 51796/* Logging and Debug 51797----------------------------------------------------------------------------------------------------------------------*/ 51798function log() { 51799 var args = []; 51800 for (var _i = 0; _i < arguments.length; _i++) { 51801 args[_i] = arguments[_i]; 51802 } 51803 var console = window.console; 51804 if (console && console.log) { 51805 return console.log.apply(console, args); 51806 } 51807} 51808exports.log = log; 51809function warn() { 51810 var args = []; 51811 for (var _i = 0; _i < arguments.length; _i++) { 51812 args[_i] = arguments[_i]; 51813 } 51814 var console = window.console; 51815 if (console && console.warn) { 51816 return console.warn.apply(console, args); 51817 } 51818 else { 51819 return log.apply(null, args); 51820 } 51821} 51822exports.warn = warn; 51823/* General Utilities 51824----------------------------------------------------------------------------------------------------------------------*/ 51825var hasOwnPropMethod = {}.hasOwnProperty; 51826// Merges an array of objects into a single object. 51827// The second argument allows for an array of property names who's object values will be merged together. 51828function mergeProps(propObjs, complexProps) { 51829 var dest = {}; 51830 var i; 51831 var name; 51832 var complexObjs; 51833 var j; 51834 var val; 51835 var props; 51836 if (complexProps) { 51837 for (i = 0; i < complexProps.length; i++) { 51838 name = complexProps[i]; 51839 complexObjs = []; 51840 // collect the trailing object values, stopping when a non-object is discovered 51841 for (j = propObjs.length - 1; j >= 0; j--) { 51842 val = propObjs[j][name]; 51843 if (typeof val === 'object') { 51844 complexObjs.unshift(val); 51845 } 51846 else if (val !== undefined) { 51847 dest[name] = val; // if there were no objects, this value will be used 51848 break; 51849 } 51850 } 51851 // if the trailing values were objects, use the merged value 51852 if (complexObjs.length) { 51853 dest[name] = mergeProps(complexObjs); 51854 } 51855 } 51856 } 51857 // copy values into the destination, going from last to first 51858 for (i = propObjs.length - 1; i >= 0; i--) { 51859 props = propObjs[i]; 51860 for (name in props) { 51861 if (!(name in dest)) { 51862 dest[name] = props[name]; 51863 } 51864 } 51865 } 51866 return dest; 51867} 51868exports.mergeProps = mergeProps; 51869function copyOwnProps(src, dest) { 51870 for (var name_1 in src) { 51871 if (hasOwnProp(src, name_1)) { 51872 dest[name_1] = src[name_1]; 51873 } 51874 } 51875} 51876exports.copyOwnProps = copyOwnProps; 51877function hasOwnProp(obj, name) { 51878 return hasOwnPropMethod.call(obj, name); 51879} 51880exports.hasOwnProp = hasOwnProp; 51881function applyAll(functions, thisObj, args) { 51882 if ($.isFunction(functions)) { 51883 functions = [functions]; 51884 } 51885 if (functions) { 51886 var i = void 0; 51887 var ret = void 0; 51888 for (i = 0; i < functions.length; i++) { 51889 ret = functions[i].apply(thisObj, args) || ret; 51890 } 51891 return ret; 51892 } 51893} 51894exports.applyAll = applyAll; 51895function removeMatching(array, testFunc) { 51896 var removeCnt = 0; 51897 var i = 0; 51898 while (i < array.length) { 51899 if (testFunc(array[i])) { 51900 array.splice(i, 1); 51901 removeCnt++; 51902 } 51903 else { 51904 i++; 51905 } 51906 } 51907 return removeCnt; 51908} 51909exports.removeMatching = removeMatching; 51910function removeExact(array, exactVal) { 51911 var removeCnt = 0; 51912 var i = 0; 51913 while (i < array.length) { 51914 if (array[i] === exactVal) { 51915 array.splice(i, 1); 51916 removeCnt++; 51917 } 51918 else { 51919 i++; 51920 } 51921 } 51922 return removeCnt; 51923} 51924exports.removeExact = removeExact; 51925function isArraysEqual(a0, a1) { 51926 var len = a0.length; 51927 var i; 51928 if (len == null || len !== a1.length) { 51929 return false; 51930 } 51931 for (i = 0; i < len; i++) { 51932 if (a0[i] !== a1[i]) { 51933 return false; 51934 } 51935 } 51936 return true; 51937} 51938exports.isArraysEqual = isArraysEqual; 51939function firstDefined() { 51940 var args = []; 51941 for (var _i = 0; _i < arguments.length; _i++) { 51942 args[_i] = arguments[_i]; 51943 } 51944 for (var i = 0; i < args.length; i++) { 51945 if (args[i] !== undefined) { 51946 return args[i];
51947 } 51948 } 51949} 51950exports.firstDefined = firstDefined; 51951function htmlEscape(s) { 51952 return (s + '').replace(/&/g, '&') 51953 .replace(/</g, '<') 51954 .replace(/>/g, '>') 51955 .replace(/'/g, ''') 51956 .replace(/"/g, '"') 51957 .replace(/\n/g, '<br />'); 51958} 51959exports.htmlEscape = htmlEscape; 51960function stripHtmlEntities(text) { 51961 return text.replace(/&.*?;/g, ''); 51962} 51963exports.stripHtmlEntities = stripHtmlEntities; 51964// Given a hash of CSS properties, returns a string of CSS. 51965// Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values. 51966function cssToStr(cssProps) { 51967 var statements = []; 51968 $.each(cssProps, function (name, val) { 51969 if (val != null) { 51970 statements.push(name + ':' + val); 51971 } 51972 }); 51973 return statements.join(';'); 51974} 51975exports.cssToStr = cssToStr; 51976// Given an object hash of HTML attribute names to values, 51977// generates a string that can be injected between < > in HTML 51978function attrsToStr(attrs) { 51979 var parts = []; 51980 $.each(attrs, function (name, val) { 51981 if (val != null) { 51982 parts.push(name + '="' + htmlEscape(val) + '"'); 51983 } 51984 }); 51985 return parts.join(' '); 51986} 51987exports.attrsToStr = attrsToStr; 51988function capitaliseFirstLetter(str) { 51989 return str.charAt(0).toUpperCase() + str.slice(1); 51990} 51991exports.capitaliseFirstLetter = capitaliseFirstLetter; 51992function compareNumbers(a, b) { 51993 return a - b; 51994} 51995exports.compareNumbers = compareNumbers; 51996function isInt(n) { 51997 return n % 1 === 0; 51998} 51999exports.isInt = isInt; 52000// Returns a method bound to the given object context. 52001// Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with 52002// different contexts as identical when binding/unbinding events. 52003function proxy(obj, methodName) { 52004 var method = obj[methodName]; 52005 return function () { 52006 return method.apply(obj, arguments); 52007 }; 52008} 52009exports.proxy = proxy; 52010// Returns a function, that, as long as it continues to be invoked, will not 52011// be triggered. The function will be called after it stops being called for 52012// N milliseconds. If `immediate` is passed, trigger the function on the 52013// leading edge, instead of the trailing. 52014// https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714 52015function debounce(func, wait, immediate) { 52016 if (immediate === void 0) { immediate = false; } 52017 var timeout; 52018 var args; 52019 var context; 52020 var timestamp; 52021 var result; 52022 var later = function () { 52023 var last = +new Date() - timestamp; 52024 if (last < wait) { 52025 timeout = setTimeout(later, wait - last); 52026 } 52027 else { 52028 timeout = null; 52029 if (!immediate) { 52030 result = func.apply(context, args); 52031 context = args = null; 52032 } 52033 } 52034 }; 52035 return function () { 52036 context = this; 52037 args = arguments; 52038 timestamp = +new Date(); 52039 var callNow = immediate && !timeout; 52040 if (!timeout) { 52041 timeout = setTimeout(later, wait); 52042 } 52043 if (callNow) { 52044 result = func.apply(context, args); 52045 context = args = null; 52046 } 52047 return result; 52048 }; 52049} 52050exports.debounce = debounce; 52051 52052 52053/***/ }), 52054/* 5 */ 52055/***/ (function(module, exports, __webpack_require__) { 52056 52057Object.defineProperty(exports, "__esModule", { value: true }); 52058var moment = __webpack_require__(0); 52059var moment_ext_1 = __webpack_require__(10); 52060var UnzonedRange = /** @class */ (function () { 52061 function UnzonedRange(startInput, endInput) { 52062 // TODO: move these into footprint. 52063 // Especially, doesn't make sense for null startMs/endMs. 52064 this.isStart = true; 52065 this.isEnd = true; 52066 if (moment.isMoment(startInput)) { 52067 startInput = startInput.clone().stripZone(); 52068 } 52069 if (moment.isMoment(endInput)) { 52070 endInput = endInput.clone().stripZone(); 52071 } 52072 if (startInput) { 52073 this.startMs = startInput.valueOf(); 52074 } 52075 if (endInput) { 52076 this.endMs = endInput.valueOf(); 52077 } 52078 } 52079 /* 52080 SIDEEFFECT: will mutate eventRanges. 52081 Will return a new array result.
52082 Only works for non-open-ended ranges. 52083 */ 52084 UnzonedRange.invertRanges = function (ranges, constraintRange) { 52085 var invertedRanges = []; 52086 var startMs = constraintRange.startMs; // the end of the previous range. the start of the new range 52087 var i; 52088 var dateRange; 52089 // ranges need to be in order. required for our date-walking algorithm 52090 ranges.sort(compareUnzonedRanges); 52091 for (i = 0; i < ranges.length; i++) { 52092 dateRange = ranges[i]; 52093 // add the span of time before the event (if there is any) 52094 if (dateRange.startMs > startMs) { 52095 invertedRanges.push(new UnzonedRange(startMs, dateRange.startMs)); 52096 } 52097 if (dateRange.endMs > startMs) { 52098 startMs = dateRange.endMs; 52099 } 52100 } 52101 // add the span of time after the last event (if there is any) 52102 if (startMs < constraintRange.endMs) { 52103 invertedRanges.push(new UnzonedRange(startMs, constraintRange.endMs)); 52104 } 52105 return invertedRanges; 52106 }; 52107 UnzonedRange.prototype.intersect = function (otherRange) { 52108 var startMs = this.startMs; 52109 var endMs = this.endMs; 52110 var newRange = null; 52111 if (otherRange.startMs != null) { 52112 if (startMs == null) { 52113 startMs = otherRange.startMs; 52114 } 52115 else { 52116 startMs = Math.max(startMs, otherRange.startMs); 52117 } 52118 } 52119 if (otherRange.endMs != null) { 52120 if (endMs == null) { 52121 endMs = otherRange.endMs; 52122 } 52123 else { 52124 endMs = Math.min(endMs, otherRange.endMs); 52125 } 52126 } 52127 if (startMs == null || endMs == null || startMs < endMs) { 52128 newRange = new UnzonedRange(startMs, endMs); 52129 newRange.isStart = this.isStart && startMs === this.startMs; 52130 newRange.isEnd = this.isEnd && endMs === this.endMs; 52131 } 52132 return newRange; 52133 }; 52134 UnzonedRange.prototype.intersectsWith = function (otherRange) { 52135 return (this.endMs == null || otherRange.startMs == null || this.endMs > otherRange.startMs) && 52136 (this.startMs == null || otherRange.endMs == null || this.startMs < otherRange.endMs); 52137 }; 52138 UnzonedRange.prototype.containsRange = function (innerRange) { 52139 return (this.startMs == null || (innerRange.startMs != null && innerRange.startMs >= this.startMs)) && 52140 (this.endMs == null || (innerRange.endMs != null && innerRange.endMs <= this.endMs)); 52141 }; 52142 // `date` can be a moment, a Date, or a millisecond time. 52143 UnzonedRange.prototype.containsDate = function (date) { 52144 var ms = date.valueOf(); 52145 return (this.startMs == null || ms >= this.startMs) && 52146 (this.endMs == null || ms < this.endMs); 52147 }; 52148 // If the given date is not within the given range, move it inside. 52149 // (If it's past the end, make it one millisecond before the end). 52150 // `date` can be a moment, a Date, or a millisecond time. 52151 // Returns a MS-time. 52152 UnzonedRange.prototype.constrainDate = function (date) { 52153 var ms = date.valueOf(); 52154 if (this.startMs != null && ms < this.startMs) { 52155 ms = this.startMs; 52156 } 52157 if (this.endMs != null && ms >= this.endMs) { 52158 ms = this.endMs - 1; 52159 } 52160 return ms; 52161 }; 52162 UnzonedRange.prototype.equals = function (otherRange) { 52163 return this.startMs === otherRange.startMs && this.endMs === otherRange.endMs; 52164 }; 52165 UnzonedRange.prototype.clone = function () { 52166 var range = new UnzonedRange(this.startMs, this.endMs); 52167 range.isStart = this.isStart; 52168 range.isEnd = this.isEnd; 52169 return range; 52170 }; 52171 // Returns an ambig-zoned moment from startMs. 52172 // BEWARE: returned moment is not localized. 52173 // Formatting and start-of-week will be default. 52174 UnzonedRange.prototype.getStart = function () { 52175 if (this.startMs != null) { 52176 return moment_ext_1.default.utc(this.startMs).stripZone(); 52177 } 52178 return null; 52179 }; 52180 // Returns an ambig-zoned moment from startMs. 52181 // BEWARE: returned moment is not localized. 52182 // Formatting and start-of-week will be default. 52183 UnzonedRange.prototype.getEnd = function () { 52184 if (this.endMs != null) { 52185 return moment_ext_1.default.utc(this.endMs).stripZone(); 52186 } 52187 return null; 52188 }; 52189 UnzonedRange.prototype.as = function (unit) { 52190 return moment.utc(this.endMs).diff(moment.utc(this.startMs), unit, true); 52191 }; 52192 return UnzonedRange; 52193}()); 52194exports.default = UnzonedRange; 52195/* 52196Only works for non-open-ended ranges. 52197*/ 52198function compareUnzonedRanges(range1, range2) { 52199 return range1.startMs - range2.startMs; // earlier ranges go first 52200} 52201 52202 52203/***/ }), 52204/* 6 */ 52205/***/ (function(module, exports, __webpack_require__) { 52206 52207Object.defineProperty(exports, "__esModule", { value: true });
52208var tslib_1 = __webpack_require__(2); 52209var $ = __webpack_require__(3); 52210var ParsableModelMixin_1 = __webpack_require__(208); 52211var Class_1 = __webpack_require__(33); 52212var EventDefParser_1 = __webpack_require__(49); 52213var EventSource = /** @class */ (function (_super) { 52214 tslib_1.__extends(EventSource, _super); 52215 // can we do away with calendar? at least for the abstract? 52216 // useful for buildEventDef 52217 function EventSource(calendar) { 52218 var _this = _super.call(this) || this; 52219 _this.calendar = calendar; 52220 _this.className = []; 52221 _this.uid = String(EventSource.uuid++); 52222 return _this; 52223 } 52224 /* 52225 rawInput can be any data type! 52226 */ 52227 EventSource.parse = function (rawInput, calendar) { 52228 var source = new this(calendar); 52229 if (typeof rawInput === 'object') { 52230 if (source.applyProps(rawInput)) { 52231 return source; 52232 } 52233 } 52234 return false; 52235 }; 52236 EventSource.normalizeId = function (id) { 52237 if (id) { 52238 return String(id); 52239 } 52240 return null; 52241 }; 52242 EventSource.prototype.fetch = function (start, end, timezone) { 52243 // subclasses must implement. must return a promise. 52244 }; 52245 EventSource.prototype.removeEventDefsById = function (eventDefId) { 52246 // optional for subclasses to implement 52247 }; 52248 EventSource.prototype.removeAllEventDefs = function () { 52249 // optional for subclasses to implement 52250 }; 52251 /* 52252 For compairing/matching 52253 */ 52254 EventSource.prototype.getPrimitive = function (otherSource) { 52255 // subclasses must implement 52256 }; 52257 EventSource.prototype.parseEventDefs = function (rawEventDefs) { 52258 var i; 52259 var eventDef; 52260 var eventDefs = []; 52261 for (i = 0; i < rawEventDefs.length; i++) { 52262 eventDef = this.parseEventDef(rawEventDefs[i]); 52263 if (eventDef) { 52264 eventDefs.push(eventDef); 52265 } 52266 } 52267 return eventDefs; 52268 }; 52269 EventSource.prototype.parseEventDef = function (rawInput) { 52270 var calendarTransform = this.calendar.opt('eventDataTransform'); 52271 var sourceTransform = this.eventDataTransform; 52272 if (calendarTransform) { 52273 rawInput = calendarTransform(rawInput, this.calendar); 52274 } 52275 if (sourceTransform) { 52276 rawInput = sourceTransform(rawInput, this.calendar); 52277 } 52278 return EventDefParser_1.default.parse(rawInput, this); 52279 }; 52280 EventSource.prototype.applyManualStandardProps = function (rawProps) { 52281 if (rawProps.id != null) { 52282 this.id = EventSource.normalizeId(rawProps.id); 52283 } 52284 // TODO: converge with EventDef 52285 if ($.isArray(rawProps.className)) { 52286 this.className = rawProps.className; 52287 } 52288 else if (typeof rawProps.className === 'string') { 52289 this.className = rawProps.className.split(/\s+/); 52290 } 52291 return true; 52292 }; 52293 EventSource.uuid = 0; 52294 EventSource.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps; 52295 EventSource.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps; 52296 return EventSource; 52297}(Class_1.default)); 52298exports.default = EventSource; 52299ParsableModelMixin_1.default.mixInto(EventSource); 52300// Parsing 52301// --------------------------------------------------------------------------------------------------------------------- 52302EventSource.defineStandardProps({ 52303 // manually process... 52304 id: false, 52305 className: false, 52306 // automatically transfer... 52307 color: true, 52308 backgroundColor: true, 52309 borderColor: true, 52310 textColor: true, 52311 editable: true, 52312 startEditable: true, 52313 durationEditable: true, 52314 rendering: true, 52315 overlap: true, 52316 constraint: true, 52317 allDayDefault: true, 52318 eventDataTransform: true 52319}); 52320 52321 52322/***/ }), 52323/* 7 */ 52324/***/ (function(module, exports, __webpack_require__) { 52325 52326/* 52327Utility methods for easily listening to events on another object, 52328and more importantly, easily unlistening from them. 52329 52330USAGE: 52331 import { default as ListenerMixin, ListenerInterface } from './ListenerMixin' 52332in class: 52333 listenTo: ListenerInterface['listenTo'] 52334 stopListeningTo: ListenerInterface['stopListeningTo'] 52335after class: 52336 ListenerMixin.mixInto(TheClass) 52337*/ 52338Object.defineProperty(exports, "__esModule", { value: true });
52339var tslib_1 = __webpack_require__(2); 52340var $ = __webpack_require__(3); 52341var Mixin_1 = __webpack_require__(14); 52342var guid = 0; 52343var ListenerMixin = /** @class */ (function (_super) { 52344 tslib_1.__extends(ListenerMixin, _super); 52345 function ListenerMixin() { 52346 return _super !== null && _super.apply(this, arguments) || this; 52347 } 52348 /* 52349 Given an `other` object that has on/off methods, bind the given `callback` to an event by the given name. 52350 The `callback` will be called with the `this` context of the object that .listenTo is being called on. 52351 Can be called: 52352 .listenTo(other, eventName, callback) 52353 OR 52354 .listenTo(other, { 52355 eventName1: callback1, 52356 eventName2: callback2 52357 }) 52358 */ 52359 ListenerMixin.prototype.listenTo = function (other, arg, callback) { 52360 if (typeof arg === 'object') { 52361 for (var eventName in arg) { 52362 if (arg.hasOwnProperty(eventName)) { 52363 this.listenTo(other, eventName, arg[eventName]); 52364 } 52365 } 52366 } 52367 else if (typeof arg === 'string') { 52368 other.on(arg + '.' + this.getListenerNamespace(), // use event namespacing to identify this object 52369 $.proxy(callback, this) // always use `this` context 52370 // the usually-undesired jQuery guid behavior doesn't matter, 52371 // because we always unbind via namespace 52372 ); 52373 } 52374 }; 52375 /* 52376 Causes the current object to stop listening to events on the `other` object. 52377 `eventName` is optional. If omitted, will stop listening to ALL events on `other`. 52378 */ 52379 ListenerMixin.prototype.stopListeningTo = function (other, eventName) { 52380 other.off((eventName || '') + '.' + this.getListenerNamespace()); 52381 }; 52382 /* 52383 Returns a string, unique to this object, to be used for event namespacing 52384 */ 52385 ListenerMixin.prototype.getListenerNamespace = function () { 52386 if (this.listenerId == null) { 52387 this.listenerId = guid++; 52388 } 52389 return '_listener' + this.listenerId; 52390 }; 52391 return ListenerMixin; 52392}(Mixin_1.default)); 52393exports.default = ListenerMixin; 52394 52395 52396/***/ }), 52397/* 8 */, 52398/* 9 */, 52399/* 10 */ 52400/***/ (function(module, exports, __webpack_require__) { 52401 52402Object.defineProperty(exports, "__esModule", { value: true }); 52403var moment = __webpack_require__(0); 52404var $ = __webpack_require__(3); 52405var util_1 = __webpack_require__(4); 52406var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/; 52407var ambigTimeOrZoneRegex = /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/; 52408var newMomentProto = moment.fn; // where we will attach our new methods 52409exports.newMomentProto = newMomentProto; 52410var oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods 52411exports.oldMomentProto = oldMomentProto; 52412// tell momentjs to transfer these properties upon clone 52413var momentProperties = moment.momentProperties; 52414momentProperties.push('_fullCalendar'); 52415momentProperties.push('_ambigTime'); 52416momentProperties.push('_ambigZone'); 52417/* 52418Call this if you want Moment's original format method to be used 52419*/ 52420function oldMomentFormat(mom, formatStr) { 52421 return oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js 52422} 52423exports.oldMomentFormat = oldMomentFormat; 52424// Creating 52425// ------------------------------------------------------------------------------------------------- 52426// Creates a new moment, similar to the vanilla moment(...) constructor, but with 52427// extra features (ambiguous time, enhanced formatting). When given an existing moment, 52428// it will function as a clone (and retain the zone of the moment). Anything else will 52429// result in a moment in the local zone. 52430var momentExt = function () { 52431 return makeMoment(arguments); 52432}; 52433exports.default = momentExt; 52434// Sames as momentExt, but forces the resulting moment to be in the UTC timezone. 52435momentExt.utc = function () { 52436 var mom = makeMoment(arguments, true); 52437 // Force it into UTC because makeMoment doesn't guarantee it 52438 // (if given a pre-existing moment for example) 52439 if (mom.hasTime()) { 52440 mom.utc(); 52441 } 52442 return mom; 52443}; 52444// Same as momentExt, but when given an ISO8601 string, the timezone offset is preserved. 52445// ISO8601 strings with no timezone offset will become ambiguously zoned. 52446momentExt.parseZone = function () { 52447 return makeMoment(arguments, true, true); 52448}; 52449// Builds an enhanced moment from args. When given an existing moment, it clones. When given a 52450// native Date, or called with no arguments (the current time), the resulting moment will be local. 52451// Anything else needs to be "parsed" (a string or an array), and will be affected by: 52452// parseAsUTC - if there is no zone information, should we parse the input in UTC?
52453// parseZone - if there is zone information, should we force the zone of the moment? 52454function makeMoment(args, parseAsUTC, parseZone) { 52455 if (parseAsUTC === void 0) { parseAsUTC = false; } 52456 if (parseZone === void 0) { parseZone = false; } 52457 var input = args[0]; 52458 var isSingleString = args.length === 1 && typeof input === 'string'; 52459 var isAmbigTime; 52460 var isAmbigZone; 52461 var ambigMatch; 52462 var mom; 52463 if (moment.isMoment(input) || util_1.isNativeDate(input) || input === undefined) { 52464 mom = moment.apply(null, args); 52465 } 52466 else { 52467 isAmbigTime = false; 52468 isAmbigZone = false; 52469 if (isSingleString) { 52470 if (ambigDateOfMonthRegex.test(input)) { 52471 // accept strings like '2014-05', but convert to the first of the month 52472 input += '-01'; 52473 args = [input]; // for when we pass it on to moment's constructor 52474 isAmbigTime = true; 52475 isAmbigZone = true; 52476 } 52477 else if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) { 52478 isAmbigTime = !ambigMatch[5]; // no time part? 52479 isAmbigZone = true; 52480 } 52481 } 52482 else if ($.isArray(input)) { 52483 // arrays have no timezone information, so assume ambiguous zone 52484 isAmbigZone = true; 52485 } 52486 // otherwise, probably a string with a format 52487 if (parseAsUTC || isAmbigTime) { 52488 mom = moment.utc.apply(moment, args); 52489 } 52490 else { 52491 mom = moment.apply(null, args); 52492 } 52493 if (isAmbigTime) { 52494 mom._ambigTime = true; 52495 mom._ambigZone = true; // ambiguous time always means ambiguous zone 52496 } 52497 else if (parseZone) { 52498 if (isAmbigZone) { 52499 mom._ambigZone = true; 52500 } 52501 else if (isSingleString) { 52502 mom.utcOffset(input); // if not a valid zone, will assign UTC 52503 } 52504 } 52505 } 52506 mom._fullCalendar = true; // flag for extended functionality 52507 return mom; 52508} 52509// Week Number 52510// ------------------------------------------------------------------------------------------------- 52511// Returns the week number, considering the locale's custom week number calcuation 52512// `weeks` is an alias for `week` 52513newMomentProto.week = newMomentProto.weeks = function (input) { 52514 var weekCalc = this._locale._fullCalendar_weekCalc; 52515 if (input == null && typeof weekCalc === 'function') { 52516 return weekCalc(this); 52517 } 52518 else if (weekCalc === 'ISO') { 52519 return oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter 52520 } 52521 return oldMomentProto.week.apply(this, arguments); // local getter/setter 52522}; 52523// Time-of-day 52524// ------------------------------------------------------------------------------------------------- 52525// GETTER 52526// Returns a Duration with the hours/minutes/seconds/ms values of the moment. 52527// If the moment has an ambiguous time, a duration of 00:00 will be returned. 52528// 52529// SETTER 52530// You can supply a Duration, a Moment, or a Duration-like argument. 52531// When setting the time, and the moment has an ambiguous time, it then becomes unambiguous. 52532newMomentProto.time = function (time) { 52533 // Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar. 52534 // `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins. 52535 if (!this._fullCalendar) { 52536 return oldMomentProto.time.apply(this, arguments); 52537 } 52538 if (time == null) { 52539 return moment.duration({ 52540 hours: this.hours(), 52541 minutes: this.minutes(), 52542 seconds: this.seconds(), 52543 milliseconds: this.milliseconds() 52544 }); 52545 } 52546 else { 52547 this._ambigTime = false; // mark that the moment now has a time 52548 if (!moment.isDuration(time) && !moment.isMoment(time)) { 52549 time = moment.duration(time); 52550 } 52551 // The day value should cause overflow (so 24 hours becomes 00:00:00 of next day). 52552 // Only for Duration times, not Moment times. 52553 var dayHours = 0; 52554 if (moment.isDuration(time)) { 52555 dayHours = Math.floor(time.asDays()) * 24; 52556 } 52557 // We need to set the individual fields. 52558 // Can't use startOf('day') then add duration. In case of DST at start of day. 52559 return this.hours(dayHours + time.hours()) 52560 .minutes(time.minutes()) 52561 .seconds(time.seconds()) 52562 .milliseconds(time.milliseconds()); 52563 } 52564}; 52565// Converts the moment to UTC, stripping out its time-of-day and timezone offset, 52566// but preserving its YMD. A moment with a stripped time will display no time 52567// nor timezone offset when .format() is called. 52568newMomentProto.stripTime = function () { 52569 if (!this._ambigTime) { 52570 this.utc(true); // keepLocalTime=true (for keeping *date* value) 52571 // set time to zero 52572 this.set({ 52573 hours: 0, 52574 minutes: 0, 52575 seconds: 0, 52576 ms: 0 52577 }); 52578 // Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(), 52579 // which clears all ambig flags. 52580 this._ambigTime = true; 52581 this._ambigZone = true; // if ambiguous time, also ambiguous timezone offset 52582 } 52583 return this; // for chaining 52584};
52585// Returns if the moment has a non-ambiguous time (boolean) 52586newMomentProto.hasTime = function () { 52587 return !this._ambigTime; 52588}; 52589// Timezone 52590// ------------------------------------------------------------------------------------------------- 52591// Converts the moment to UTC, stripping out its timezone offset, but preserving its 52592// YMD and time-of-day. A moment with a stripped timezone offset will display no 52593// timezone offset when .format() is called. 52594newMomentProto.stripZone = function () { 52595 var wasAmbigTime; 52596 if (!this._ambigZone) { 52597 wasAmbigTime = this._ambigTime; 52598 this.utc(true); // keepLocalTime=true (for keeping date and time values) 52599 // the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore 52600 this._ambigTime = wasAmbigTime || false; 52601 // Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(), 52602 // which clears the ambig flags. 52603 this._ambigZone = true; 52604 } 52605 return this; // for chaining 52606}; 52607// Returns of the moment has a non-ambiguous timezone offset (boolean) 52608newMomentProto.hasZone = function () { 52609 return !this._ambigZone; 52610}; 52611// implicitly marks a zone 52612newMomentProto.local = function (keepLocalTime) { 52613 // for when converting from ambiguously-zoned to local, 52614 // keep the time values when converting from UTC -> local 52615 oldMomentProto.local.call(this, this._ambigZone || keepLocalTime); 52616 // ensure non-ambiguous 52617 // this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals 52618 this._ambigTime = false; 52619 this._ambigZone = false; 52620 return this; // for chaining 52621}; 52622// implicitly marks a zone 52623newMomentProto.utc = function (keepLocalTime) { 52624 oldMomentProto.utc.call(this, keepLocalTime); 52625 // ensure non-ambiguous 52626 // this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals 52627 this._ambigTime = false; 52628 this._ambigZone = false; 52629 return this; 52630}; 52631// implicitly marks a zone (will probably get called upon .utc() and .local()) 52632newMomentProto.utcOffset = function (tzo) { 52633 if (tzo != null) { 52634 // these assignments needs to happen before the original zone method is called. 52635 // I forget why, something to do with a browser crash. 52636 this._ambigTime = false; 52637 this._ambigZone = false; 52638 } 52639 return oldMomentProto.utcOffset.apply(this, arguments); 52640}; 52641 52642 52643/***/ }), 52644/* 11 */ 52645/***/ (function(module, exports, __webpack_require__) { 52646 52647/* 52648USAGE: 52649 import { default as EmitterMixin, EmitterInterface } from './EmitterMixin' 52650in class: 52651 on: EmitterInterface['on'] 52652 one: EmitterInterface['one'] 52653 off: EmitterInterface['off'] 52654 trigger: EmitterInterface['trigger'] 52655 triggerWith: EmitterInterface['triggerWith'] 52656 hasHandlers: EmitterInterface['hasHandlers'] 52657after class: 52658 EmitterMixin.mixInto(TheClass) 52659*/ 52660Object.defineProperty(exports, "__esModule", { value: true }); 52661var tslib_1 = __webpack_require__(2); 52662var $ = __webpack_require__(3); 52663var Mixin_1 = __webpack_require__(14); 52664var EmitterMixin = /** @class */ (function (_super) { 52665 tslib_1.__extends(EmitterMixin, _super); 52666 function EmitterMixin() { 52667 return _super !== null && _super.apply(this, arguments) || this; 52668 } 52669 // jQuery-ification via $(this) allows a non-DOM object to have 52670 // the same event handling capabilities (including namespaces). 52671 EmitterMixin.prototype.on = function (types, handler) { 52672 $(this).on(types, this._prepareIntercept(handler)); 52673 return this; // for chaining 52674 }; 52675 EmitterMixin.prototype.one = function (types, handler) { 52676 $(this).one(types, this._prepareIntercept(handler)); 52677 return this; // for chaining 52678 }; 52679 EmitterMixin.prototype._prepareIntercept = function (handler) { 52680 // handlers are always called with an "event" object as their first param. 52681 // sneak the `this` context and arguments into the extra parameter object 52682 // and forward them on to the original handler. 52683 var intercept = function (ev, extra) { 52684 return handler.apply(extra.context || this, extra.args || []); 52685 }; 52686 // mimick jQuery's internal "proxy" system (risky, I know) 52687 // causing all functions with the same .guid to appear to be the same. 52688 // https://github.com/jquery/jquery/blob/2.2.4/src/core.js#L448 52689 // this is needed for calling .off with the original non-intercept handler. 52690 if (!handler.guid) { 52691 handler.guid = $.guid++; 52692 } 52693 intercept.guid = handler.guid; 52694 return intercept; 52695 }; 52696 EmitterMixin.prototype.off = function (types, handler) { 52697 $(this).off(types, handler); 52698 return this; // for chaining 52699 }; 52700 EmitterMixin.prototype.trigger = function (types) { 52701 var args = []; 52702 for (var _i = 1; _i < arguments.length; _i++) { 52703 args[_i - 1] = arguments[_i]; 52704 } 52705 // pass in "extra" info to the intercept 52706 $(this).triggerHandler(types, { args: args }); 52707 return this; // for chaining 52708 }; 52709 EmitterMixin.prototype.triggerWith = function (types, context, args
52709) { 52710 // `triggerHandler` is less reliant on the DOM compared to `trigger`. 52711 // pass in "extra" info to the intercept. 52712 $(this).triggerHandler(types, { context: context, args: args }); 52713 return this; // for chaining 52714 }; 52715 EmitterMixin.prototype.hasHandlers = function (type) { 52716 var hash = $._data(this, 'events'); // http://blog.jquery.com/2012/08/09/jquery-1-8-released/ 52717 return hash && hash[type] && hash[type].length > 0; 52718 }; 52719 return EmitterMixin; 52720}(Mixin_1.default)); 52721exports.default = EmitterMixin; 52722 52723 52724/***/ }), 52725/* 12 */ 52726/***/ (function(module, exports) { 52727 52728Object.defineProperty(exports, "__esModule", { value: true }); 52729/* 52730Meant to be immutable 52731*/ 52732var ComponentFootprint = /** @class */ (function () { 52733 function ComponentFootprint(unzonedRange, isAllDay) { 52734 this.isAllDay = false; // component can choose to ignore this 52735 this.unzonedRange = unzonedRange; 52736 this.isAllDay = isAllDay; 52737 } 52738 /* 52739 Only works for non-open-ended ranges. 52740 */ 52741 ComponentFootprint.prototype.toLegacy = function (calendar) { 52742 return { 52743 start: calendar.msToMoment(this.unzonedRange.startMs, this.isAllDay), 52744 end: calendar.msToMoment(this.unzonedRange.endMs, this.isAllDay) 52745 }; 52746 }; 52747 return ComponentFootprint; 52748}()); 52749exports.default = ComponentFootprint; 52750 52751 52752/***/ }), 52753/* 13 */ 52754/***/ (function(module, exports, __webpack_require__) { 52755 52756Object.defineProperty(exports, "__esModule", { value: true }); 52757var tslib_1 = __webpack_require__(2); 52758var EventDef_1 = __webpack_require__(34); 52759var EventInstance_1 = __webpack_require__(209); 52760var EventDateProfile_1 = __webpack_require__(17); 52761var SingleEventDef = /** @class */ (function (_super) { 52762 tslib_1.__extends(SingleEventDef, _super); 52763 function SingleEventDef() { 52764 return _super !== null && _super.apply(this, arguments) || this; 52765 } 52766 /* 52767 Will receive start/end params, but will be ignored. 52768 */ 52769 SingleEventDef.prototype.buildInstances = function () { 52770 return [this.buildInstance()]; 52771 }; 52772 SingleEventDef.prototype.buildInstance = function () { 52773 return new EventInstance_1.default(this, // definition 52774 this.dateProfile); 52775 }; 52776 SingleEventDef.prototype.isAllDay = function () { 52777 return this.dateProfile.isAllDay(); 52778 }; 52779 SingleEventDef.prototype.clone = function () { 52780 var def = _super.prototype.clone.call(this); 52781 def.dateProfile = this.dateProfile; 52782 return def; 52783 }; 52784 SingleEventDef.prototype.rezone = function () { 52785 var calendar = this.source.calendar; 52786 var dateProfile = this.dateProfile; 52787 this.dateProfile = new EventDateProfile_1.default(calendar.moment(dateProfile.start), dateProfile.end ? calendar.moment(dateProfile.end) : null, calendar); 52788 }; 52789 /* 52790 NOTE: if super-method fails, should still attempt to apply 52791 */ 52792 SingleEventDef.prototype.applyManualStandardProps = function (rawProps) { 52793 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); 52794 var dateProfile = EventDateProfile_1.default.parse(rawProps, this.source); // returns null on failure 52795 if (dateProfile) { 52796 this.dateProfile = dateProfile; 52797 // make sure `date` shows up in the legacy event objects as-is 52798 if (rawProps.date != null) { 52799 this.miscProps.date = rawProps.date; 52800 } 52801 return superSuccess; 52802 } 52803 else { 52804 return false; 52805 } 52806 }; 52807 return SingleEventDef; 52808}(EventDef_1.default)); 52809exports.default = SingleEventDef; 52810// Parsing 52811// --------------------------------------------------------------------------------------------------------------------- 52812SingleEventDef.defineStandardProps({ 52813 start: false, 52814 date: false, 52815 end: false, 52816 allDay: false 52817}); 52818 52819 52820/***/ }), 52821/* 14 */ 52822/***/ (function(module, exports) { 52823 52824Object.defineProperty(exports, "__esModule", { value: true }); 52825var Mixin = /** @class */ (function () { 52826 function Mixin() { 52827 } 52828 Mixin.mixInto = function (destClass) { 52829 var _this = this; 52830 Object.getOwnPropertyNames(this.prototype).forEach(function (name) { 52831 if (!destClass.prototype[name]) { 52832 destClass.prototype[name] = _this.prototype[name]; 52833 } 52834 }); 52835 }; 52836 /* 52837 will override existing methods 52838 TODO: remove! not used anymore 52839 */ 52840 Mixin.mixOver = function (destClass) { 52841 var _this = this; 52842 Object.getOwnPropertyNames(this.prototype).forEach(function (name) { 52843 destClass.prototype[name] = _this.prototype[name]; 52844 }); 52845 }; 52846 return Mixin; 52847}()); 52848exports.default = Mixin; 52849 52850 52851/***/ }), 52852/* 15 */
52853/***/ (function(module, exports) { 52854 52855Object.defineProperty(exports, "__esModule", { value: true }); 52856var Interaction = /** @class */ (function () { 52857 function Interaction(component) { 52858 this.view = component._getView(); 52859 this.component = component; 52860 } 52861 Interaction.prototype.opt = function (name) { 52862 return this.view.opt(name); 52863 }; 52864 Interaction.prototype.end = function () { 52865 // subclasses can implement 52866 }; 52867 return Interaction; 52868}()); 52869exports.default = Interaction; 52870 52871 52872/***/ }), 52873/* 16 */ 52874/***/ (function(module, exports, __webpack_require__) { 52875 52876Object.defineProperty(exports, "__esModule", { value: true }); 52877exports.version = '3.9.0'; 52878// When introducing internal API incompatibilities (where fullcalendar plugins would break), 52879// the minor version of the calendar should be upped (ex: 2.7.2 -> 2.8.0) 52880// and the below integer should be incremented. 52881exports.internalApiVersion = 12; 52882var util_1 = __webpack_require__(4); 52883exports.applyAll = util_1.applyAll; 52884exports.debounce = util_1.debounce; 52885exports.isInt = util_1.isInt; 52886exports.htmlEscape = util_1.htmlEscape; 52887exports.cssToStr = util_1.cssToStr; 52888exports.proxy = util_1.proxy; 52889exports.capitaliseFirstLetter = util_1.capitaliseFirstLetter; 52890exports.getOuterRect = util_1.getOuterRect; 52891exports.getClientRect = util_1.getClientRect; 52892exports.getContentRect = util_1.getContentRect; 52893exports.getScrollbarWidths = util_1.getScrollbarWidths; 52894exports.preventDefault = util_1.preventDefault; 52895exports.parseFieldSpecs = util_1.parseFieldSpecs; 52896exports.compareByFieldSpecs = util_1.compareByFieldSpecs; 52897exports.compareByFieldSpec = util_1.compareByFieldSpec; 52898exports.flexibleCompare = util_1.flexibleCompare; 52899exports.computeGreatestUnit = util_1.computeGreatestUnit; 52900exports.divideRangeByDuration = util_1.divideRangeByDuration; 52901exports.divideDurationByDuration = util_1.divideDurationByDuration; 52902exports.multiplyDuration = util_1.multiplyDuration; 52903exports.durationHasTime = util_1.durationHasTime; 52904exports.log = util_1.log; 52905exports.warn = util_1.warn; 52906exports.removeExact = util_1.removeExact; 52907exports.intersectRects = util_1.intersectRects; 52908var date_formatting_1 = __webpack_require__(47); 52909exports.formatDate = date_formatting_1.formatDate; 52910exports.formatRange = date_formatting_1.formatRange; 52911exports.queryMostGranularFormatUnit = date_formatting_1.queryMostGranularFormatUnit; 52912var locale_1 = __webpack_require__(31); 52913exports.datepickerLocale = locale_1.datepickerLocale; 52914exports.locale = locale_1.locale; 52915var moment_ext_1 = __webpack_require__(10); 52916exports.moment = moment_ext_1.default; 52917var EmitterMixin_1 = __webpack_require__(11); 52918exports.EmitterMixin = EmitterMixin_1.default; 52919var ListenerMixin_1 = __webpack_require__(7); 52920exports.ListenerMixin = ListenerMixin_1.default; 52921var Model_1 = __webpack_require__(48); 52922exports.Model = Model_1.default; 52923var Constraints_1 = __webpack_require__(207); 52924exports.Constraints = Constraints_1.default; 52925var UnzonedRange_1 = __webpack_require__(5); 52926exports.UnzonedRange = UnzonedRange_1.default; 52927var ComponentFootprint_1 = __webpack_require__(12); 52928exports.ComponentFootprint = ComponentFootprint_1.default; 52929var BusinessHourGenerator_1 = __webpack_require__(212); 52930exports.BusinessHourGenerator = BusinessHourGenerator_1.default; 52931var EventDef_1 = __webpack_require__(34); 52932exports.EventDef = EventDef_1.default; 52933var EventDefMutation_1 = __webpack_require__(37); 52934exports.EventDefMutation = EventDefMutation_1.default; 52935var EventSourceParser_1 = __webpack_require__(38); 52936exports.EventSourceParser = EventSourceParser_1.default; 52937var EventSource_1 = __webpack_require__(6); 52938exports.EventSource = EventSource_1.default; 52939var ThemeRegistry_1 = __webpack_require__(51); 52940exports.defineThemeSystem = ThemeRegistry_1.defineThemeSystem; 52941var EventInstanceGroup_1 = __webpack_require__(18); 52942exports.EventInstanceGroup = EventInstanceGroup_1.default; 52943var ArrayEventSource_1 = __webpack_require__(52); 52944exports.ArrayEventSource = ArrayEventSource_1.default; 52945var FuncEventSource_1 = __webpack_require__(215); 52946exports.FuncEventSource = FuncEventSource_1.default; 52947var JsonFeedEventSource_1 = __webpack_require__(216); 52948exports.JsonFeedEventSource = JsonFeedEventSource_1.default; 52949var EventFootprint_1 = __webpack_require__(36); 52950exports.EventFootprint = EventFootprint_1.default; 52951var Class_1 = __webpack_require__(33); 52952exports.Class = Class_1.default; 52953var Mixin_1 = __webpack_require__(14); 52954exports.Mixin = Mixin_1.default;
52955var CoordCache_1 = __webpack_require__(53); 52956exports.CoordCache = CoordCache_1.default; 52957var DragListener_1 = __webpack_require__(54); 52958exports.DragListener = DragListener_1.default; 52959var Promise_1 = __webpack_require__(20); 52960exports.Promise = Promise_1.default; 52961var TaskQueue_1 = __webpack_require__(217); 52962exports.TaskQueue = TaskQueue_1.default; 52963var RenderQueue_1 = __webpack_require__(218); 52964exports.RenderQueue = RenderQueue_1.default; 52965var Scroller_1 = __webpack_require__(39); 52966exports.Scroller = Scroller_1.default; 52967var Theme_1 = __webpack_require__(19); 52968exports.Theme = Theme_1.default; 52969var DateComponent_1 = __webpack_require__(219); 52970exports.DateComponent = DateComponent_1.default; 52971var InteractiveDateComponent_1 = __webpack_require__(40); 52972exports.InteractiveDateComponent = InteractiveDateComponent_1.default; 52973var Calendar_1 = __webpack_require__(220); 52974exports.Calendar = Calendar_1.default; 52975var View_1 = __webpack_require__(41); 52976exports.View = View_1.default; 52977var ViewRegistry_1 = __webpack_require__(22); 52978exports.defineView = ViewRegistry_1.defineView; 52979exports.getViewConfig = ViewRegistry_1.getViewConfig; 52980var DayTableMixin_1 = __webpack_require__(55); 52981exports.DayTableMixin = DayTableMixin_1.default; 52982var BusinessHourRenderer_1 = __webpack_require__(56); 52983exports.BusinessHourRenderer = BusinessHourRenderer_1.default; 52984var EventRenderer_1 = __webpack_require__(42); 52985exports.EventRenderer = EventRenderer_1.default; 52986var FillRenderer_1 = __webpack_require__(57); 52987exports.FillRenderer = FillRenderer_1.default; 52988var HelperRenderer_1 = __webpack_require__(58); 52989exports.HelperRenderer = HelperRenderer_1.default; 52990var ExternalDropping_1 = __webpack_require__(222); 52991exports.ExternalDropping = ExternalDropping_1.default; 52992var EventResizing_1 = __webpack_require__(223); 52993exports.EventResizing = EventResizing_1.default; 52994var EventPointing_1 = __webpack_require__(59); 52995exports.EventPointing = EventPointing_1.default; 52996var EventDragging_1 = __webpack_require__(224); 52997exports.EventDragging = EventDragging_1.default; 52998var DateSelecting_1 = __webpack_require__(225); 52999exports.DateSelecting = DateSelecting_1.default; 53000var StandardInteractionsMixin_1 = __webpack_require__(60); 53001exports.StandardInteractionsMixin = StandardInteractionsMixin_1.default; 53002var AgendaView_1 = __webpack_require__(226); 53003exports.AgendaView = AgendaView_1.default; 53004var TimeGrid_1 = __webpack_require__(227); 53005exports.TimeGrid = TimeGrid_1.default; 53006var DayGrid_1 = __webpack_require__(61); 53007exports.DayGrid = DayGrid_1.default; 53008var BasicView_1 = __webpack_require__(62); 53009exports.BasicView = BasicView_1.default; 53010var MonthView_1 = __webpack_require__(229); 53011exports.MonthView = MonthView_1.default; 53012var ListView_1 = __webpack_require__(230); 53013exports.ListView = ListView_1.default; 53014 53015 53016/***/ }), 53017/* 17 */ 53018/***/ (function(module, exports, __webpack_require__) { 53019 53020Object.defineProperty(exports, "__esModule", { value: true }); 53021var UnzonedRange_1 = __webpack_require__(5); 53022/* 53023Meant to be immutable 53024*/ 53025var EventDateProfile = /** @class */ (function () { 53026 function EventDateProfile(start, end, calendar) { 53027 this.start = start; 53028 this.end = end || null; 53029 this.unzonedRange = this.buildUnzonedRange(calendar); 53030 } 53031 /* 53032 Needs an EventSource object 53033 */ 53034 EventDateProfile.parse = function (rawProps, source) { 53035 var startInput = rawProps.start || rawProps.date; 53036 var endInput = rawProps.end; 53037 if (!startInput) { 53038 return false; 53039 } 53040 var calendar = source.calendar; 53041 var start = calendar.moment(startInput); 53042 var end = endInput ? calendar.moment(endInput) : null; 53043 var forcedAllDay = rawProps.allDay; 53044 var forceEventDuration = calendar.opt('forceEventDuration'); 53045 if (!start.isValid()) { 53046 return false; 53047 } 53048 if (end && (!end.isValid() || !end.isAfter(start))) { 53049 end = null; 53050 } 53051 if (forcedAllDay == null) { 53052 forcedAllDay = source.allDayDefault; 53053 if (forcedAllDay == null) { 53054 forcedAllDay = calendar.opt('allDayDefault'); 53055 } 53056 } 53057 if (forcedAllDay === true) { 53058 start.stripTime(); 53059 if (end) { 53060 end.stripTime(); 53061 } 53062 } 53063 else if (forcedAllDay === false) { 53064 if (!start.hasTime()) { 53065 start.time(0); 53066 } 53067 if (end && !end.hasTime()) { 53068 end.time(0); 53069 } 53070 } 53071 if (!end && forceEventDuration) { 53072 end = calendar.getDefaultEventEnd(!start.hasTime(), start); 53073 } 53074 return new EventDateProfile(start, end, calendar); 53075 }; 53076 EventDateProfile.isStandardProp = function (propName) { 53077 return propName === 'start' || propName === 'date' || propName === 'end' || propName === 'allDay'; 53078 }; 53079 EventDateProfile.prototype.isAllDay = function () { 53080 return !(this.start.hasTime() || (this.end && this.end.hasTime())); 53081 }; 53082 /* 53083 Needs a Calendar object 53084 */ 53085 EventDateProfile.prototype.buildUnzonedRange = function (calendar) { 53086 var startMs = this.start.clone().stripZone().valueOf(); 53087 var endMs = this.getEnd(calendar).stripZone().valueOf(); 53088 return new UnzonedRange_1.default(startMs, endMs); 53089 }; 53090 /* 53091 Needs a Calendar object 53092 */ 53093 EventDateProfile.prototype.getEnd = function (calendar) { 53094 return this.end ? 53095 this.end.clone() : 53096 // derive the end from the start and allDay. compute allDay if necessary 53097 calendar.getDefaultEventEnd(this.isAllDay(), this.start); 53098 }; 53099 return EventDateProfile; 53100}()); 53101exports.default = EventDateProfile; 53102 53103 53104/***/ }), 53105/* 18 */ 53106/***/ (function(module, exports, __webpack_require__) { 53107 53108Object.defineProperty(exports, "__esModule", { value: true });
53109var UnzonedRange_1 = __webpack_require__(5); 53110var util_1 = __webpack_require__(35); 53111var EventRange_1 = __webpack_require__(211); 53112/* 53113It's expected that there will be at least one EventInstance, 53114OR that an explicitEventDef is assigned. 53115*/ 53116var EventInstanceGroup = /** @class */ (function () { 53117 function EventInstanceGroup(eventInstances) { 53118 this.eventInstances = eventInstances || []; 53119 } 53120 EventInstanceGroup.prototype.getAllEventRanges = function (constraintRange) { 53121 if (constraintRange) { 53122 return this.sliceNormalRenderRanges(constraintRange); 53123 } 53124 else { 53125 return this.eventInstances.map(util_1.eventInstanceToEventRange); 53126 } 53127 }; 53128 EventInstanceGroup.prototype.sliceRenderRanges = function (constraintRange) { 53129 if (this.isInverse()) { 53130 return this.sliceInverseRenderRanges(constraintRange); 53131 } 53132 else { 53133 return this.sliceNormalRenderRanges(constraintRange); 53134 } 53135 }; 53136 EventInstanceGroup.prototype.sliceNormalRenderRanges = function (constraintRange) { 53137 var eventInstances = this.eventInstances; 53138 var i; 53139 var eventInstance; 53140 var slicedRange; 53141 var slicedEventRanges = []; 53142 for (i = 0; i < eventInstances.length; i++) { 53143 eventInstance = eventInstances[i]; 53144 slicedRange = eventInstance.dateProfile.unzonedRange.intersect(constraintRange); 53145 if (slicedRange) { 53146 slicedEventRanges.push(new EventRange_1.default(slicedRange, eventInstance.def, eventInstance)); 53147 } 53148 } 53149 return slicedEventRanges; 53150 }; 53151 EventInstanceGroup.prototype.sliceInverseRenderRanges = function (constraintRange) { 53152 var unzonedRanges = this.eventInstances.map(util_1.eventInstanceToUnzonedRange); 53153 var ownerDef = this.getEventDef(); 53154 unzonedRanges = UnzonedRange_1.default.invertRanges(unzonedRanges, constraintRange); 53155 return unzonedRanges.map(function (unzonedRange) { 53156 return new EventRange_1.default(unzonedRange, ownerDef); // don't give an EventInstance 53157 }); 53158 }; 53159 EventInstanceGroup.prototype.isInverse = function () { 53160 return this.getEventDef().hasInverseRendering(); 53161 }; 53162 EventInstanceGroup.prototype.getEventDef = function () { 53163 return this.explicitEventDef || this.eventInstances[0].def; 53164 }; 53165 return EventInstanceGroup; 53166}()); 53167exports.default = EventInstanceGroup; 53168 53169 53170/***/ }), 53171/* 19 */ 53172/***/ (function(module, exports, __webpack_require__) { 53173 53174Object.defineProperty(exports, "__esModule", { value: true }); 53175var $ = __webpack_require__(3); 53176var Theme = /** @class */ (function () { 53177 function Theme(optionsManager) { 53178 this.optionsManager = optionsManager; 53179 this.processIconOverride(); 53180 } 53181 Theme.prototype.processIconOverride = function () { 53182 if (this.iconOverrideOption) { 53183 this.setIconOverride(this.optionsManager.get(this.iconOverrideOption)); 53184 } 53185 }; 53186 Theme.prototype.setIconOverride = function (iconOverrideHash) { 53187 var iconClassesCopy; 53188 var buttonName; 53189 if ($.isPlainObject(iconOverrideHash)) { 53190 iconClassesCopy = $.extend({}, this.iconClasses); 53191 for (buttonName in iconOverrideHash) { 53192 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]); 53193 } 53194 this.iconClasses = iconClassesCopy; 53195 } 53196 else if (iconOverrideHash === false) { 53197 this.iconClasses = {}; 53198 } 53199 }; 53200 Theme.prototype.applyIconOverridePrefix = function (className) { 53201 var prefix = this.iconOverridePrefix; 53202 if (prefix && className.indexOf(prefix) !== 0) { 53203 className = prefix + className; 53204 } 53205 return className; 53206 }; 53207 Theme.prototype.getClass = function (key) { 53208 return this.classes[key] || ''; 53209 }; 53210 Theme.prototype.getIconClass = function (buttonName) { 53211 var className = this.iconClasses[buttonName]; 53212 if (className) { 53213 return this.baseIconClass + ' ' + className; 53214 } 53215 return ''; 53216 }; 53217 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) { 53218 var className; 53219 if (this.iconOverrideCustomButtonOption) { 53220 className = customButtonProps[this.iconOverrideCustomButtonOption]; 53221 if (className) { 53222 return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className); 53223 } 53224 } 53225 return ''; 53226 }; 53227 return Theme; 53228}()); 53229exports.default = Theme; 53230Theme.prototype.classes = {}; 53231Theme.prototype.iconClasses = {}; 53232Theme.prototype.baseIconClass = ''; 53233Theme.prototype.iconOverridePrefix = ''; 53234 53235 53236/***/ }), 53237/* 20 */ 53238/***/ (function(module, exports, __webpack_require__) { 53239 53240Object.defineProperty(exports, "__esModule", { value: true });
53241var $ = __webpack_require__(3); 53242var PromiseStub = { 53243 construct: function (executor) { 53244 var deferred = $.Deferred(); 53245 var promise = deferred.promise(); 53246 if (typeof executor === 'function') { 53247 executor(function (val) { 53248 deferred.resolve(val); 53249 attachImmediatelyResolvingThen(promise, val); 53250 }, function () { 53251 deferred.reject(); 53252 attachImmediatelyRejectingThen(promise); 53253 }); 53254 } 53255 return promise; 53256 }, 53257 resolve: function (val) { 53258 var deferred = $.Deferred().resolve(val); 53259 var promise = deferred.promise(); 53260 attachImmediatelyResolvingThen(promise, val); 53261 return promise; 53262 }, 53263 reject: function () { 53264 var deferred = $.Deferred().reject(); 53265 var promise = deferred.promise(); 53266 attachImmediatelyRejectingThen(promise); 53267 return promise; 53268 } 53269}; 53270exports.default = PromiseStub; 53271function attachImmediatelyResolvingThen(promise, val) { 53272 promise.then = function (onResolve) { 53273 if (typeof onResolve === 'function') { 53274 return PromiseStub.resolve(onResolve(val)); 53275 } 53276 return promise; 53277 }; 53278} 53279function attachImmediatelyRejectingThen(promise) { 53280 promise.then = function (onResolve, onReject) { 53281 if (typeof onReject === 'function') { 53282 onReject(); 53283 } 53284 return promise; 53285 }; 53286} 53287 53288 53289/***/ }), 53290/* 21 */ 53291/***/ (function(module, exports, __webpack_require__) { 53292 53293Object.defineProperty(exports, "__esModule", { value: true }); 53294var $ = __webpack_require__(3); 53295var exportHooks = __webpack_require__(16); 53296var EmitterMixin_1 = __webpack_require__(11); 53297var ListenerMixin_1 = __webpack_require__(7); 53298exportHooks.touchMouseIgnoreWait = 500; 53299var globalEmitter = null; 53300var neededCount = 0; 53301/* 53302Listens to document and window-level user-interaction events, like touch events and mouse events, 53303and fires these events as-is to whoever is observing a GlobalEmitter. 53304Best when used as a singleton via GlobalEmitter.get() 53305 53306Normalizes mouse/touch events. For examples: 53307- ignores the the simulated mouse events that happen after a quick tap: mousemove+mousedown+mouseup+click 53308- compensates for various buggy scenarios where a touchend does not fire 53309*/ 53310var GlobalEmitter = /** @class */ (function () { 53311 function GlobalEmitter() { 53312 this.isTouching = false; 53313 this.mouseIgnoreDepth = 0; 53314 } 53315 // gets the singleton 53316 GlobalEmitter.get = function () { 53317 if (!globalEmitter) { 53318 globalEmitter = new GlobalEmitter(); 53319 globalEmitter.bind(); 53320 } 53321 return globalEmitter; 53322 }; 53323 // called when an object knows it will need a GlobalEmitter in the near future. 53324 GlobalEmitter.needed = function () { 53325 GlobalEmitter.get(); // ensures globalEmitter 53326 neededCount++; 53327 }; 53328 // called when the object that originally called needed() doesn't need a GlobalEmitter anymore. 53329 GlobalEmitter.unneeded = function () { 53330 neededCount--; 53331 if (!neededCount) { 53332 globalEmitter.unbind(); 53333 globalEmitter = null; 53334 } 53335 }; 53336 GlobalEmitter.prototype.bind = function () { 53337 var _this = this; 53338 this.listenTo($(document), { 53339 touchstart: this.handleTouchStart, 53340 touchcancel: this.handleTouchCancel, 53341 touchend: this.handleTouchEnd, 53342 mousedown: this.handleMouseDown, 53343 mousemove: this.handleMouseMove, 53344 mouseup: this.handleMouseUp, 53345 click: this.handleClick, 53346 selectstart: this.handleSelectStart, 53347 contextmenu: this.handleContextMenu 53348 }); 53349 // because we need to call preventDefault 53350 // because https://www.chromestatus.com/features/5093566007214080 53351 // TODO: investigate performance because this is a global handler 53352 window.addEventListener('touchmove', this.handleTouchMoveProxy = function (ev) { 53353 _this.handleTouchMove($.Event(ev)); 53354 }, { passive: false } // allows preventDefault() 53355 ); 53356 // attach a handler to get called when ANY scroll action happens on the page. 53357 // this was impossible to do with normal on/off because 'scroll' doesn't bubble. 53358 // http://stackoverflow.com/a/32954565/96342 53359 window.addEventListener('scroll', this.handleScrollProxy = function (ev) { 53360 _this.handleScroll($.Event(ev)); 53361 }, true // useCapture 53362 ); 53363 }; 53364 GlobalEmitter.prototype.unbind = function () { 53365 this.stopListeningTo($(document)); 53366 window.removeEventListener('touchmove', this.handleTouchMoveProxy); 53367 window.removeEventListener('scroll', this.handleScrollProxy, true // useCapture 53368 ); 53369 }; 53370 // Touch Handlers 53371 // ----------------------------------------------------------------------------------------------------------------- 53372 GlobalEmitter.prototype.handleTouchStart = function (ev) { 53373 // if a previous touch interaction never ended with a touchend, then implicitly end it, 53374 // but since a new touch interaction is about to begin, don't start the mouse ignore period. 53375 this.stopTouch(ev, true);
53375 // skipMouseIgnore=true 53376 this.isTouching = true; 53377 this.trigger('touchstart', ev); 53378 }; 53379 GlobalEmitter.prototype.handleTouchMove = function (ev) { 53380 if (this.isTouching) { 53381 this.trigger('touchmove', ev); 53382 } 53383 }; 53384 GlobalEmitter.prototype.handleTouchCancel = function (ev) { 53385 if (this.isTouching) { 53386 this.trigger('touchcancel', ev); 53387 // Have touchcancel fire an artificial touchend. That way, handlers won't need to listen to both. 53388 // If touchend fires later, it won't have any effect b/c isTouching will be false. 53389 this.stopTouch(ev); 53390 } 53391 }; 53392 GlobalEmitter.prototype.handleTouchEnd = function (ev) { 53393 this.stopTouch(ev); 53394 }; 53395 // Mouse Handlers 53396 // ----------------------------------------------------------------------------------------------------------------- 53397 GlobalEmitter.prototype.handleMouseDown = function (ev) { 53398 if (!this.shouldIgnoreMouse()) { 53399 this.trigger('mousedown', ev); 53400 } 53401 }; 53402 GlobalEmitter.prototype.handleMouseMove = function (ev) { 53403 if (!this.shouldIgnoreMouse()) { 53404 this.trigger('mousemove', ev); 53405 } 53406 }; 53407 GlobalEmitter.prototype.handleMouseUp = function (ev) { 53408 if (!this.shouldIgnoreMouse()) { 53409 this.trigger('mouseup', ev); 53410 } 53411 }; 53412 GlobalEmitter.prototype.handleClick = function (ev) { 53413 if (!this.shouldIgnoreMouse()) { 53414 this.trigger('click', ev); 53415 } 53416 }; 53417 // Misc Handlers 53418 // ----------------------------------------------------------------------------------------------------------------- 53419 GlobalEmitter.prototype.handleSelectStart = function (ev) { 53420 this.trigger('selectstart', ev); 53421 }; 53422 GlobalEmitter.prototype.handleContextMenu = function (ev) { 53423 this.trigger('contextmenu', ev); 53424 }; 53425 GlobalEmitter.prototype.handleScroll = function (ev) { 53426 this.trigger('scroll', ev); 53427 }; 53428 // Utils 53429 // ----------------------------------------------------------------------------------------------------------------- 53430 GlobalEmitter.prototype.stopTouch = function (ev, skipMouseIgnore) { 53431 if (skipMouseIgnore === void 0) { skipMouseIgnore = false; } 53432 if (this.isTouching) { 53433 this.isTouching = false; 53434 this.trigger('touchend', ev); 53435 if (!skipMouseIgnore) { 53436 this.startTouchMouseIgnore(); 53437 } 53438 } 53439 }; 53440 GlobalEmitter.prototype.startTouchMouseIgnore = function () { 53441 var _this = this; 53442 var wait = exportHooks.touchMouseIgnoreWait; 53443 if (wait) { 53444 this.mouseIgnoreDepth++; 53445 setTimeout(function () { 53446 _this.mouseIgnoreDepth--; 53447 }, wait); 53448 } 53449 }; 53450 GlobalEmitter.prototype.shouldIgnoreMouse = function () { 53451 return this.isTouching || Boolean(this.mouseIgnoreDepth); 53452 }; 53453 return GlobalEmitter; 53454}()); 53455exports.default = GlobalEmitter; 53456ListenerMixin_1.default.mixInto(GlobalEmitter); 53457EmitterMixin_1.default.mixInto(GlobalEmitter); 53458 53459 53460/***/ }), 53461/* 22 */ 53462/***/ (function(module, exports, __webpack_require__) { 53463 53464Object.defineProperty(exports, "__esModule", { value: true }); 53465var exportHooks = __webpack_require__(16); 53466exports.viewHash = {}; 53467exportHooks.views = exports.viewHash; 53468function defineView(viewName, viewConfig) { 53469 exports.viewHash[viewName] = viewConfig; 53470} 53471exports.defineView = defineView; 53472function getViewConfig(viewName) { 53473 return exports.viewHash[viewName]; 53474} 53475exports.getViewConfig = getViewConfig; 53476 53477 53478/***/ }), 53479/* 23 */ 53480/***/ (function(module, exports, __webpack_require__) { 53481 53482Object.defineProperty(exports, "__esModule", { value: true }); 53483var tslib_1 = __webpack_require__(2); 53484var util_1 = __webpack_require__(4); 53485var DragListener_1 = __webpack_require__(54); 53486/* Tracks mouse movements over a component and raises events about which hit the mouse is over. 53487------------------------------------------------------------------------------------------------------------------------ 53488options: 53489- subjectEl 53490- subjectCenter 53491*/ 53492var HitDragListener = /** @class */ (function (_super) { 53493 tslib_1.__extends(HitDragListener, _super); 53494 function HitDragListener(component, options) { 53495 var _this = _super.call(this, options) || this; 53496 _this.component = component; 53497 return _this; 53498 } 53499 // Called when drag listening starts (but a real drag has not necessarily began). 53500 // ev might be undefined if dragging was started manually. 53501 HitDragListener.prototype.handleInteractionStart = function (ev) { 53502 var subjectEl = this.subjectEl; 53503 var subjectRect; 53504 var origPoint; 53505 var point; 53506 this.component.hitsNeeded(); 53507 this.computeScrollBounds(); // for autoscroll 53508 if (ev) { 53509 origPoint = { left: util_1.getEvX(ev), top: util_1.getEvY(ev) }; 53510 point = origPoint;
53511 // constrain the point to bounds of the element being dragged 53512 if (subjectEl) { 53513 subjectRect = util_1.getOuterRect(subjectEl); // used for centering as well 53514 point = util_1.constrainPoint(point, subjectRect); 53515 } 53516 this.origHit = this.queryHit(point.left, point.top); 53517 // treat the center of the subject as the collision point? 53518 if (subjectEl && this.options.subjectCenter) { 53519 // only consider the area the subject overlaps the hit. best for large subjects. 53520 // TODO: skip this if hit didn't supply left/right/top/bottom 53521 if (this.origHit) { 53522 subjectRect = util_1.intersectRects(this.origHit, subjectRect) || 53523 subjectRect; // in case there is no intersection 53524 } 53525 point = util_1.getRectCenter(subjectRect); 53526 } 53527 this.coordAdjust = util_1.diffPoints(point, origPoint); // point - origPoint 53528 } 53529 else { 53530 this.origHit = null; 53531 this.coordAdjust = null; 53532 } 53533 // call the super-method. do it after origHit has been computed 53534 _super.prototype.handleInteractionStart.call(this, ev); 53535 }; 53536 // Called when the actual drag has started 53537 HitDragListener.prototype.handleDragStart = function (ev) { 53538 var hit; 53539 _super.prototype.handleDragStart.call(this, ev); 53540 // might be different from this.origHit if the min-distance is large 53541 hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev)); 53542 // report the initial hit the mouse is over 53543 // especially important if no min-distance and drag starts immediately 53544 if (hit) { 53545 this.handleHitOver(hit); 53546 } 53547 }; 53548 // Called when the drag moves 53549 HitDragListener.prototype.handleDrag = function (dx, dy, ev) { 53550 var hit; 53551 _super.prototype.handleDrag.call(this, dx, dy, ev); 53552 hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev)); 53553 if (!isHitsEqual(hit, this.hit)) { 53554 if (this.hit) { 53555 this.handleHitOut(); 53556 } 53557 if (hit) { 53558 this.handleHitOver(hit); 53559 } 53560 } 53561 }; 53562 // Called when dragging has been stopped 53563 HitDragListener.prototype.handleDragEnd = function (ev) { 53564 this.handleHitDone(); 53565 _super.prototype.handleDragEnd.call(this, ev); 53566 }; 53567 // Called when a the mouse has just moved over a new hit 53568 HitDragListener.prototype.handleHitOver = function (hit) { 53569 var isOrig = isHitsEqual(hit, this.origHit); 53570 this.hit = hit; 53571 this.trigger('hitOver', this.hit, isOrig, this.origHit); 53572 }; 53573 // Called when the mouse has just moved out of a hit 53574 HitDragListener.prototype.handleHitOut = function () { 53575 if (this.hit) { 53576 this.trigger('hitOut', this.hit); 53577 this.handleHitDone(); 53578 this.hit = null; 53579 } 53580 }; 53581 // Called after a hitOut. Also called before a dragStop 53582 HitDragListener.prototype.handleHitDone = function () { 53583 if (this.hit) { 53584 this.trigger('hitDone', this.hit); 53585 } 53586 }; 53587 // Called when the interaction ends, whether there was a real drag or not 53588 HitDragListener.prototype.handleInteractionEnd = function (ev, isCancelled) { 53589 _super.prototype.handleInteractionEnd.call(this, ev, isCancelled); 53590 this.origHit = null; 53591 this.hit = null; 53592 this.component.hitsNotNeeded(); 53593 }; 53594 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling 53595 HitDragListener.prototype.handleScrollEnd = function () { 53596 _super.prototype.handleScrollEnd.call(this); 53597 // hits' absolute positions will be in new places after a user's scroll. 53598 // HACK for recomputing. 53599 if (this.isDragging) { 53600 this.component.releaseHits(); 53601 this.component.prepareHits(); 53602 } 53603 }; 53604 // Gets the hit underneath the coordinates for the given mouse event 53605 HitDragListener.prototype.queryHit = function (left, top) { 53606 if (this.coordAdjust) { 53607 left += this.coordAdjust.left; 53608 top += this.coordAdjust.top; 53609 } 53610 return this.component.queryHit(left, top); 53611 }; 53612 return HitDragListener; 53613}(DragListener_1.default)); 53614exports.default = HitDragListener; 53615// Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component. 53616// Two null values will be considered equal, as two "out of the component" states are the same. 53617function isHitsEqual(hit0, hit1) { 53618 if (!hit0 && !hit1) { 53619 return true; 53620 } 53621 if (hit0 && hit1) { 53622 return hit0.component === hit1.component && 53623 isHitPropsWithin(hit0, hit1) && 53624 isHitPropsWithin(hit1, hit0); // ensures all props are identical 53625 } 53626 return false; 53627} 53628// Returns true if all of subHit's non-standard properties are within superHit 53629function isHitPropsWithin(subHit, superHit) { 53630 for (var propName in subHit) { 53631 if (!/^(component|left|right|top|bottom)$/.test(propName)) { 53632 if (subHit[propName] !== superHit[propName]) { 53633 return false; 53634 } 53635 } 53636 } 53637 return true; 53638} 53639 53640 53641/***/ }), 53642/* 24 */, 53643/* 25 */, 53644/* 26 */, 53645/* 27 */, 53646/* 28 */, 53647/* 29 */, 53648/* 30 */, 53649/* 31 */ 53650/***/ (function(module, exports, __webpack_require__) { 53651 53652Object.defineProperty(exports, "__esModule", { value: true });
53653var $ = __webpack_require__(3); 53654var moment = __webpack_require__(0); 53655var exportHooks = __webpack_require__(16); 53656var options_1 = __webpack_require__(32); 53657var util_1 = __webpack_require__(4); 53658exports.localeOptionHash = {}; 53659exportHooks.locales = exports.localeOptionHash; 53660// NOTE: can't guarantee any of these computations will run because not every locale has datepicker 53661// configs, so make sure there are English fallbacks for these in the defaults file. 53662var dpComputableOptions = { 53663 buttonText: function (dpOptions) { 53664 return { 53665 // the translations sometimes wrongly contain HTML entities 53666 prev: util_1.stripHtmlEntities(dpOptions.prevText), 53667 next: util_1.stripHtmlEntities(dpOptions.nextText), 53668 today: util_1.stripHtmlEntities(dpOptions.currentText) 53669 }; 53670 }, 53671 // Produces format strings like "MMMM YYYY" -> "September 2014" 53672 monthYearFormat: function (dpOptions) { 53673 return dpOptions.showMonthAfterYear ? 53674 'YYYY[' + dpOptions.yearSuffix + '] MMMM' : 53675 'MMMM YYYY[' + dpOptions.yearSuffix + ']'; 53676 } 53677}; 53678var momComputableOptions = { 53679 // Produces format strings like "ddd M/D" -> "Fri 9/15" 53680 dayOfMonthFormat: function (momOptions, fcOptions) { 53681 var format = momOptions.longDateFormat('l'); // for the format like "M/D/YYYY" 53682 // strip the year off the edge, as well as other misc non-whitespace chars 53683 format = format.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, ''); 53684 if (fcOptions.isRTL) { 53685 format += ' ddd'; // for RTL, add day-of-week to end 53686 } 53687 else { 53688 format = 'ddd ' + format; // for LTR, add day-of-week to beginning 53689 } 53690 return format; 53691 }, 53692 // Produces format strings like "h:mma" -> "6:00pm" 53693 mediumTimeFormat: function (momOptions) { 53694 return momOptions.longDateFormat('LT') 53695 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand 53696 }, 53697 // Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm" 53698 smallTimeFormat: function (momOptions) { 53699 return momOptions.longDateFormat('LT') 53700 .replace(':mm', '(:mm)') 53701 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales 53702 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand 53703 }, 53704 // Produces format strings like "h(:mm)t" -> "6p" / "6:30p" 53705 extraSmallTimeFormat: function (momOptions) { 53706 return momOptions.longDateFormat('LT') 53707 .replace(':mm', '(:mm)') 53708 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales 53709 .replace(/\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand 53710 }, 53711 // Produces format strings like "ha" / "H" -> "6pm" / "18" 53712 hourFormat: function (momOptions) { 53713 return momOptions.longDateFormat('LT') 53714 .replace(':mm', '') 53715 .replace(/(\Wmm)$/, '') // like above, but for foreign locales 53716 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand 53717 }, 53718 // Produces format strings like "h:mm" -> "6:30" (with no AM/PM) 53719 noMeridiemTimeFormat: function (momOptions) { 53720 return momOptions.longDateFormat('LT') 53721 .replace(/\s*a$/i, ''); // remove trailing AM/PM 53722 } 53723}; 53724// options that should be computed off live calendar options (considers override options) 53725// TODO: best place for this? related to locale? 53726// TODO: flipping text based on isRTL is a bad idea because the CSS `direction` might want to handle it 53727var instanceComputableOptions = { 53728 // Produces format strings for results like "Mo 16" 53729 smallDayDateFormat: function (options) { 53730 return options.isRTL ? 53731 'D dd' : 53732 'dd D'; 53733 }, 53734 // Produces format strings for results like "Wk 5" 53735 weekFormat: function (options) { 53736 return options.isRTL ? 53737 'w[ ' + options.weekNumberTitle + ']' : 53738 '[' + options.weekNumberTitle + ' ]w'; 53739 },
53740 // Produces format strings for results like "Wk5" 53741 smallWeekFormat: function (options) { 53742 return options.isRTL ? 53743 'w[' + options.weekNumberTitle + ']' : 53744 '[' + options.weekNumberTitle + ']w'; 53745 } 53746}; 53747// TODO: make these computable properties in optionsManager 53748function populateInstanceComputableOptions(options) { 53749 $.each(instanceComputableOptions, function (name, func) { 53750 if (options[name] == null) { 53751 options[name] = func(options); 53752 } 53753 }); 53754} 53755exports.populateInstanceComputableOptions = populateInstanceComputableOptions; 53756// Initialize jQuery UI datepicker translations while using some of the translations 53757// Will set this as the default locales for datepicker. 53758function datepickerLocale(localeCode, dpLocaleCode, dpOptions) { 53759 // get the FullCalendar internal option hash for this locale. create if necessary 53760 var fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {}); 53761 // transfer some simple options from datepicker to fc 53762 fcOptions.isRTL = dpOptions.isRTL; 53763 fcOptions.weekNumberTitle = dpOptions.weekHeader; 53764 // compute some more complex options from datepicker 53765 $.each(dpComputableOptions, function (name, func) { 53766 fcOptions[name] = func(dpOptions); 53767 }); 53768 var jqDatePicker = $.datepicker; 53769 // is jQuery UI Datepicker is on the page? 53770 if (jqDatePicker) { 53771 // Register the locale data. 53772 // FullCalendar and MomentJS use locale codes like "pt-br" but Datepicker 53773 // does it like "pt-BR" or if it doesn't have the locale, maybe just "pt". 53774 // Make an alias so the locale can be referenced either way. 53775 jqDatePicker.regional[dpLocaleCode] = 53776 jqDatePicker.regional[localeCode] = // alias 53777 dpOptions; 53778 // Alias 'en' to the default locale data. Do this every time. 53779 jqDatePicker.regional.en = jqDatePicker.regional['']; 53780 // Set as Datepicker's global defaults. 53781 jqDatePicker.setDefaults(dpOptions); 53782 } 53783} 53784exports.datepickerLocale = datepickerLocale; 53785// Sets FullCalendar-specific translations. Will set the locales as the global default. 53786function locale(localeCode, newFcOptions) { 53787 var fcOptions; 53788 var momOptions; 53789 // get the FullCalendar internal option hash for this locale. create if necessary 53790 fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {}); 53791 // provided new options for this locales? merge them in 53792 if (newFcOptions) { 53793 fcOptions = exports.localeOptionHash[localeCode] = options_1.mergeOptions([fcOptions, newFcOptions]); 53794 } 53795 // compute locale options that weren't defined. 53796 // always do this. newFcOptions can be undefined when initializing from i18n file, 53797 // so no way to tell if this is an initialization or a default-setting. 53798 momOptions = getMomentLocaleData(localeCode); // will fall back to en 53799 $.each(momComputableOptions, function (name, func) { 53800 if (fcOptions[name] == null) { 53801 fcOptions[name] = (func)(momOptions, fcOptions); 53802 } 53803 }); 53804 // set it as the default locale for FullCalendar 53805 options_1.globalDefaults.locale = localeCode; 53806} 53807exports.locale = locale; 53808// Returns moment's internal locale data. If doesn't exist, returns English. 53809function getMomentLocaleData(localeCode) { 53810 return moment.localeData(localeCode) || moment.localeData('en'); 53811} 53812exports.getMomentLocaleData = getMomentLocaleData; 53813// Initialize English by forcing computation of moment-derived options. 53814// Also, sets it as the default. 53815locale('en', options_1.englishDefaults); 53816 53817 53818/***/ }), 53819/* 32 */ 53820/***/ (function(module, exports, __webpack_require__) { 53821 53822Object.defineProperty(exports, "__esModule", { value: true }); 53823var util_1 = __webpack_require__(4); 53824exports.globalDefaults = { 53825 titleRangeSeparator: ' \u2013 ', 53826 monthYearFormat: 'MMMM YYYY', 53827 defaultTimedEventDuration: '02:00:00', 53828 defaultAllDayEventDuration: { days: 1 }, 53829 forceEventDuration: false, 53830 nextDayThreshold: '09:00:00', 53831 // display 53832 columnHeader: true, 53833 defaultView: 'month', 53834 aspectRatio: 1.35, 53835 header: { 53836 left: 'title',
53837 center: '', 53838 right: 'today prev,next' 53839 }, 53840 weekends: true, 53841 weekNumbers: false, 53842 weekNumberTitle: 'W', 53843 weekNumberCalculation: 'local', 53844 // editable: false, 53845 // nowIndicator: false, 53846 scrollTime: '06:00:00', 53847 minTime: '00:00:00', 53848 maxTime: '24:00:00', 53849 showNonCurrentDates: true, 53850 // event ajax 53851 lazyFetching: true, 53852 startParam: 'start', 53853 endParam: 'end', 53854 timezoneParam: 'timezone', 53855 timezone: false, 53856 // allDayDefault: undefined, 53857 // locale 53858 locale: null, 53859 isRTL: false, 53860 buttonText: { 53861 prev: 'prev', 53862 next: 'next', 53863 prevYear: 'prev year', 53864 nextYear: 'next year', 53865 year: 'year', 53866 today: 'today', 53867 month: 'month', 53868 week: 'week', 53869 day: 'day' 53870 }, 53871 // buttonIcons: null, 53872 allDayText: 'all-day', 53873 // allows setting a min-height to the event segment to prevent short events overlapping each other 53874 agendaEventMinHeight: 0, 53875 // jquery-ui theming 53876 theme: false, 53877 // themeButtonIcons: null, 53878 // eventResizableFromStart: false, 53879 dragOpacity: .75, 53880 dragRevertDuration: 500, 53881 dragScroll: true, 53882 // selectable: false, 53883 unselectAuto: true, 53884 // selectMinDistance: 0, 53885 dropAccept: '*', 53886 eventOrder: 'title', 53887 // eventRenderWait: null, 53888 eventLimit: false, 53889 eventLimitText: 'more', 53890 eventLimitClick: 'popover', 53891 dayPopoverFormat: 'LL', 53892 handleWindowResize: true, 53893 windowResizeDelay: 100, 53894 longPressDelay: 1000 53895}; 53896exports.englishDefaults = { 53897 dayPopoverFormat: 'dddd, MMMM D' 53898}; 53899exports.rtlDefaults = { 53900 header: { 53901 left: 'next,prev today', 53902 center: '', 53903 right: 'title' 53904 }, 53905 buttonIcons: { 53906 prev: 'right-single-arrow', 53907 next: 'left-single-arrow', 53908 prevYear: 'right-double-arrow', 53909 nextYear: 'left-double-arrow' 53910 }, 53911 themeButtonIcons: { 53912 prev: 'circle-triangle-e', 53913 next: 'circle-triangle-w', 53914 nextYear: 'seek-prev', 53915 prevYear: 'seek-next' 53916 } 53917}; 53918var complexOptions = [ 53919 'header', 53920 'footer', 53921 'buttonText', 53922 'buttonIcons', 53923 'themeButtonIcons' 53924]; 53925// Merges an array of option objects into a single object 53926function mergeOptions(optionObjs) { 53927 return util_1.mergeProps(optionObjs, complexOptions); 53928} 53929exports.mergeOptions = mergeOptions; 53930 53931 53932/***/ }), 53933/* 33 */ 53934/***/ (function(module, exports, __webpack_require__) { 53935 53936Object.defineProperty(exports, "__esModule", { value: true }); 53937var tslib_1 = __webpack_require__(2); 53938var util_1 = __webpack_require__(4); 53939// Class that all other classes will inherit from 53940var Class = /** @class */ (function () { 53941 function Class() { 53942 } 53943 // Called on a class to create a subclass. 53944 // LIMITATION: cannot provide a constructor! 53945 Class.extend = function (members) { 53946 var SubClass = /** @class */ (function (_super) { 53947 tslib_1.__extends(SubClass, _super); 53948 function SubClass() { 53949 return _super !== null && _super.apply(this, arguments) || this; 53950 } 53951 return SubClass; 53952 }(this)); 53953 util_1.copyOwnProps(members, SubClass.prototype); 53954 return SubClass; 53955 }; 53956 // Adds new member variables/methods to the class's prototype. 53957 // Can be called with another class, or a plain object hash containing new members. 53958 Class.mixin = function (members) { 53959 util_1.copyOwnProps(members, this.prototype); 53960 }; 53961 return Class; 53962}()); 53963exports.default = Class; 53964 53965 53966/***/ }), 53967/* 34 */ 53968/***/ (function(module, exports, __webpack_require__) { 53969 53970Object.defineProperty(exports, "__esModule", { value: true }); 53971var $ = __webpack_require__(3); 53972var ParsableModelMixin_1 = __webpack_require__(208); 53973var EventDef = /** @class */ (function () { 53974 function EventDef(source) { 53975 this.source = source; 53976 this.className = []; 53977 this.miscProps = {}; 53978 } 53979 EventDef.parse = function (rawInput, source) { 53980 var def = new this(source); 53981 if (def.applyProps(rawInput)) { 53982 return def; 53983 } 53984 return false; 53985 }; 53986 EventDef.normalizeId = function (id) { 53987 return String(id); 53988 }; 53989 EventDef.generateId = function () { 53990 return '_fc' + (EventDef.uuid++); 53991 }; 53992 EventDef.prototype.clone = function () { 53993 var copy = new this.constructor(this.source); 53994 copy.id = this.id; 53995 copy.rawId = this.rawId; 53996 copy.uid = this.uid; // not really unique anymore :( 53997 EventDef.copyVerbatimStandardProps(this, copy); 53998 copy.className = this.className.slice(); // copy 53999 copy.miscProps = $.extend({}, this.miscProps); 54000 return copy; 54001 }; 54002 EventDef.prototype.hasInverseRendering = function () { 54003 return this.getRendering() === 'inverse-background'; 54004 }; 54005 EventDef.prototype.hasBgRendering = function () { 54006 var rendering = this.getRendering(); 54007 return rendering === 'inverse-background' || rendering === 'background'; 54008 }; 54009 EventDef.prototype.getRendering = function () { 54010 if (this.rendering != null) { 54011 return this.rendering; 54012 } 54013 return this.source.rendering; 54014 }; 54015 EventDef.prototype.getConstraint = function () { 54016 if (this.constraint != null) { 54017 return this.constraint; 54018 } 54019 if (this.source.constraint != null) { 54020 return this.source.constraint; 54021 } 54022 return this.source.calendar.opt('eventConstraint'); // what about View option? 54023 }; 54024 EventDef.prototype.getOverlap = function () { 54025 if (this.overlap != null) { 54026 return this.overlap; 54027 } 54028 if (this.source.overlap != null) { 54029 return this.source.overlap; 54030 } 54031 return this.source.calendar.opt('eventOverlap'); // what about View option? 54032 }; 54033 EventDef.prototype.isStartExplicitlyEditable = function () { 54034 if (this.startEditable != null) { 54035 return this.startEditable; 54036 } 54037 return this.source.startEditable; 54038 }; 54039 EventDef.prototype.isDurationExplicitlyEditable = function () { 54040 if (this.durationEditable != null) { 54041 return this.durationEditable; 54042 } 54043 return this.source.durationEditable; 54044 }; 54045 EventDef.prototype.isExplicitlyEditable = function () { 54046 if (this.editable != null) { 54047 return this.editable; 54048 } 54049 return this.source.editable; 54050 }; 54051 EventDef.prototype.toLegacy = function () { 54052 var obj = $.extend({}, this.miscProps); 54053 obj._id = this.uid; 54054 obj.source = this.source; 54055 obj.className = this.className.slice(); // copy 54056 obj.allDay = this.isAllDay(); 54057 if (this.rawId != null) { 54058 obj.id = this.rawId; 54059 } 54060 EventDef.copyVerbatimStandardProps(this, obj); 54061 return obj;
54062 }; 54063 EventDef.prototype.applyManualStandardProps = function (rawProps) { 54064 if (rawProps.id != null) { 54065 this.id = EventDef.normalizeId((this.rawId = rawProps.id)); 54066 } 54067 else { 54068 this.id = EventDef.generateId(); 54069 } 54070 if (rawProps._id != null) { 54071 this.uid = String(rawProps._id); 54072 } 54073 else { 54074 this.uid = EventDef.generateId(); 54075 } 54076 // TODO: converge with EventSource 54077 if ($.isArray(rawProps.className)) { 54078 this.className = rawProps.className; 54079 } 54080 if (typeof rawProps.className === 'string') { 54081 this.className = rawProps.className.split(/\s+/); 54082 } 54083 return true; 54084 }; 54085 EventDef.prototype.applyMiscProps = function (rawProps) { 54086 $.extend(this.miscProps, rawProps); 54087 }; 54088 EventDef.uuid = 0; 54089 EventDef.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps; 54090 EventDef.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps; 54091 return EventDef; 54092}()); 54093exports.default = EventDef; 54094ParsableModelMixin_1.default.mixInto(EventDef); 54095EventDef.defineStandardProps({ 54096 // not automatically assigned (`false`) 54097 _id: false, 54098 id: false, 54099 className: false, 54100 source: false, 54101 // automatically assigned (`true`) 54102 title: true, 54103 url: true, 54104 rendering: true, 54105 constraint: true, 54106 overlap: true, 54107 editable: true, 54108 startEditable: true, 54109 durationEditable: true, 54110 color: true, 54111 backgroundColor: true, 54112 borderColor: true, 54113 textColor: true 54114}); 54115 54116 54117/***/ }), 54118/* 35 */ 54119/***/ (function(module, exports, __webpack_require__) { 54120 54121Object.defineProperty(exports, "__esModule", { value: true }); 54122var EventRange_1 = __webpack_require__(211); 54123var EventFootprint_1 = __webpack_require__(36); 54124var ComponentFootprint_1 = __webpack_require__(12); 54125function eventDefsToEventInstances(eventDefs, unzonedRange) { 54126 var eventInstances = []; 54127 var i; 54128 for (i = 0; i < eventDefs.length; i++) { 54129 eventInstances.push.apply(eventInstances, // append 54130 eventDefs[i].buildInstances(unzonedRange)); 54131 } 54132 return eventInstances; 54133} 54134exports.eventDefsToEventInstances = eventDefsToEventInstances; 54135function eventInstanceToEventRange(eventInstance) { 54136 return new EventRange_1.default(eventInstance.dateProfile.unzonedRange, eventInstance.def, eventInstance); 54137} 54138exports.eventInstanceToEventRange = eventInstanceToEventRange; 54139function eventRangeToEventFootprint(eventRange) { 54140 return new EventFootprint_1.default(new ComponentFootprint_1.default(eventRange.unzonedRange, eventRange.eventDef.isAllDay()), eventRange.eventDef, eventRange.eventInstance // might not exist 54141 ); 54142} 54143exports.eventRangeToEventFootprint = eventRangeToEventFootprint; 54144function eventInstanceToUnzonedRange(eventInstance) { 54145 return eventInstance.dateProfile.unzonedRange; 54146} 54147exports.eventInstanceToUnzonedRange = eventInstanceToUnzonedRange; 54148function eventFootprintToComponentFootprint(eventFootprint) { 54149 return eventFootprint.componentFootprint; 54150} 54151exports.eventFootprintToComponentFootprint = eventFootprintToComponentFootprint; 54152 54153 54154/***/ }), 54155/* 36 */ 54156/***/ (function(module, exports) { 54157 54158Object.defineProperty(exports, "__esModule", { value: true }); 54159var EventFootprint = /** @class */ (function () { 54160 function EventFootprint(componentFootprint, eventDef, eventInstance) { 54161 this.componentFootprint = componentFootprint; 54162 this.eventDef = eventDef; 54163 if (eventInstance) { 54164 this.eventInstance = eventInstance; 54165 } 54166 } 54167 EventFootprint.prototype.getEventLegacy = function () { 54168 return (this.eventInstance || this.eventDef).toLegacy(); 54169 }; 54170 return EventFootprint; 54171}()); 54172exports.default = EventFootprint; 54173 54174 54175/***/ }), 54176/* 37 */ 54177/***/ (function(module, exports, __webpack_require__) { 54178 54179Object.defineProperty(exports, "__esModule", { value: true }); 54180var util_1 = __webpack_require__(4); 54181var EventDateProfile_1 = __webpack_require__(17); 54182var EventDef_1 = __webpack_require__(34); 54183var EventDefDateMutation_1 = __webpack_require__(50); 54184var SingleEventDef_1 = __webpack_require__(13); 54185var EventDefMutation = /** @class */ (function () { 54186 function EventDefMutation() { 54187 } 54188 EventDefMutation.createFromRawProps = function (eventInstance, rawProps, largeUnit) { 54189 var eventDef = eventInstance.def; 54190 var dateProps = {}; 54191 var standardProps = {}; 54192 var miscProps = {}; 54193 var verbatimStandardProps = {}; 54194 var eventDefId = null; 54195 var className = null; 54196 var propName; 54197 var dateProfile; 54198 var dateMutation; 54199 var defMutation; 54200 for (propName in rawProps) { 54201 if (EventDateProfile_1.default.isStandardProp(propName)) { 54202 dateProps[propName] = rawProps[propName]; 54203 } 54204 else if (eventDef.isStandardProp(propName)) { 54205 standardProps[propName] = rawProps[propName]; 54206 } 54207 else if (eventDef.miscProps[propName] !== rawProps[propName]) { 54208 miscProps[propName] = rawProps[propName]; 54209 } 54210 } 54211 dateProfile = EventDateProfile_1.default.parse(dateProps, eventDef.source); 54212 if (dateProfile) { 54213 dateMutation = EventDefDateMutation_1.default.createFromDiff(eventInstance.dateProfile, dateProfile, largeUnit); 54214 } 54215 if (standardProps.id !== eventDef.id) { 54216 eventDefId = standardProps.id; // only apply if there's a change 54217 } 54218 if (!util_1.isArraysEqual(standardProps.className, eventDef.className)) { 54219 className = standardProps.className; // only apply if there's a change 54220 } 54221 EventDef_1.default.copyVerbatimStandardProps(standardProps, // src 54222 verbatimStandardProps // dest 54223 ); 54224 defMutation = new EventDefMutation(); 54225 defMutation.eventDefId = eventDefId; 54226 defMutation.className = className; 54227 defMutation.verbatimStandardProps = verbatimStandardProps; 54228 defMutation.miscProps = miscProps; 54229 if (dateMutation) { 54230 defMutation.dateMutation = dateMutation; 54231 } 54232 return defMutation; 54233 }; 54234 /* 54235 eventDef assumed to be a SingleEventDef. 54236 returns an undo function. 54237 */ 54238 EventDefMutation.prototype.mutateSingle = function (eventDef) { 54239 var origDateProfile; 54240 if (this.dateMutation) { 54241 origDateProfile = eventDef.dateProfile; 54242 eventDef.dateProfile = this.dateMutation.buildNewDateProfile(origDateProfile, eventDef.source.calendar); 54243 } 54244 // can't undo 54245 // TODO: more DRY with EventDef::applyManualStandardProps 54246 if (this.eventDefId != null) { 54247 eventDef.id = EventDef_1.default.normalizeId((eventDef.rawId = this.eventDefId)); 54248 } 54249 // can't undo 54250 // TODO: more DRY with EventDef::applyManualStandardProps 54251 if (this.className) { 54252 eventDef.className = this.className; 54253 } 54254 // can't undo 54255 if (this.verbatimStandardProps) { 54256 SingleEventDef_1.default.copyVerbatimStandardProps(this.verbatimStandardProps, // src 54257 eventDef // dest 54258 ); 54259 } 54260 // can't undo 54261 if (this.miscProps) { 54262 eventDef.applyMiscProps(this.miscProps); 54263 } 54264 if (origDateProfile) { 54265 return function () { 54266 eventDef.dateProfile = origDateProfile; 54267 }; 54268 } 54269 else { 54270 return function () { }; 54271 } 54272 }; 54273 EventDefMutation.prototype.setDateMutation = function (dateMutation) { 54274 if (dateMutation && !dateMutation.isEmpty()) { 54275 this.dateMutation = dateMutation; 54276 } 54277 else { 54278 this.dateMutation = null; 54279 } 54280 }; 54281 EventDefMutation.prototype.isEmpty = function () { 54282 return !this.dateMutation; 54283 }; 54284 return EventDefMutation; 54285}()); 54286exports.default = EventDefMutation; 54287 54288 54289/***/ }), 54290/* 38 */
54291/***/ (function(module, exports) { 54292 54293Object.defineProperty(exports, "__esModule", { value: true }); 54294exports.default = { 54295 sourceClasses: [], 54296 registerClass: function (EventSourceClass) { 54297 this.sourceClasses.unshift(EventSourceClass); // give highest priority 54298 }, 54299 parse: function (rawInput, calendar) { 54300 var sourceClasses = this.sourceClasses; 54301 var i; 54302 var eventSource; 54303 for (i = 0; i < sourceClasses.length; i++) { 54304 eventSource = sourceClasses[i].parse(rawInput, calendar); 54305 if (eventSource) { 54306 return eventSource; 54307 } 54308 } 54309 } 54310}; 54311 54312 54313/***/ }), 54314/* 39 */ 54315/***/ (function(module, exports, __webpack_require__) { 54316 54317Object.defineProperty(exports, "__esModule", { value: true }); 54318var tslib_1 = __webpack_require__(2); 54319var $ = __webpack_require__(3); 54320var util_1 = __webpack_require__(4); 54321var Class_1 = __webpack_require__(33); 54322/* 54323Embodies a div that has potential scrollbars 54324*/ 54325var Scroller = /** @class */ (function (_super) { 54326 tslib_1.__extends(Scroller, _super); 54327 function Scroller(options) { 54328 var _this = _super.call(this) || this; 54329 options = options || {}; 54330 _this.overflowX = options.overflowX || options.overflow || 'auto'; 54331 _this.overflowY = options.overflowY || options.overflow || 'auto'; 54332 return _this; 54333 } 54334 Scroller.prototype.render = function () { 54335 this.el = this.renderEl(); 54336 this.applyOverflow(); 54337 }; 54338 Scroller.prototype.renderEl = function () { 54339 return (this.scrollEl = $('<div class="fc-scroller"></div>')); 54340 }; 54341 // sets to natural height, unlocks overflow 54342 Scroller.prototype.clear = function () { 54343 this.setHeight('auto'); 54344 this.applyOverflow(); 54345 }; 54346 Scroller.prototype.destroy = function () { 54347 this.el.remove(); 54348 }; 54349 // Overflow 54350 // ----------------------------------------------------------------------------------------------------------------- 54351 Scroller.prototype.applyOverflow = function () { 54352 this.scrollEl.css({ 54353 'overflow-x': this.overflowX, 54354 'overflow-y': this.overflowY 54355 }); 54356 }; 54357 // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'. 54358 // Useful for preserving scrollbar widths regardless of future resizes. 54359 // Can pass in scrollbarWidths for optimization. 54360 Scroller.prototype.lockOverflow = function (scrollbarWidths) { 54361 var overflowX = this.overflowX; 54362 var overflowY = this.overflowY;
54363 scrollbarWidths = scrollbarWidths || this.getScrollbarWidths(); 54364 if (overflowX === 'auto') { 54365 overflowX = (scrollbarWidths.top || scrollbarWidths.bottom || // horizontal scrollbars? 54366 // OR scrolling pane with massless scrollbars? 54367 this.scrollEl[0].scrollWidth - 1 > this.scrollEl[0].clientWidth) ? 'scroll' : 'hidden'; 54368 } 54369 if (overflowY === 'auto') { 54370 overflowY = (scrollbarWidths.left || scrollbarWidths.right || // vertical scrollbars? 54371 // OR scrolling pane with massless scrollbars? 54372 this.scrollEl[0].scrollHeight - 1 > this.scrollEl[0].clientHeight) ? 'scroll' : 'hidden'; 54373 } 54374 this.scrollEl.css({ 'overflow-x': overflowX, 'overflow-y': overflowY }); 54375 }; 54376 // Getters / Setters 54377 // ----------------------------------------------------------------------------------------------------------------- 54378 Scroller.prototype.setHeight = function (height) { 54379 this.scrollEl.height(height); 54380 }; 54381 Scroller.prototype.getScrollTop = function () { 54382 return this.scrollEl.scrollTop(); 54383 }; 54384 Scroller.prototype.setScrollTop = function (top) { 54385 this.scrollEl.scrollTop(top); 54386 }; 54387 Scroller.prototype.getClientWidth = function () { 54388 return this.scrollEl[0].clientWidth; 54389 }; 54390 Scroller.prototype.getClientHeight = function () { 54391 return this.scrollEl[0].clientHeight; 54392 }; 54393 Scroller.prototype.getScrollbarWidths = function () { 54394 return util_1.getScrollbarWidths(this.scrollEl); 54395 }; 54396 return Scroller; 54397}(Class_1.default)); 54398exports.default = Scroller; 54399 54400 54401/***/ }), 54402/* 40 */ 54403/***/ (function(module, exports, __webpack_require__) { 54404 54405Object.defineProperty(exports, "__esModule", { value: true }); 54406var tslib_1 = __webpack_require__(2); 54407var $ = __webpack_require__(3); 54408var util_1 = __webpack_require__(4); 54409var DateComponent_1 = __webpack_require__(219); 54410var GlobalEmitter_1 = __webpack_require__(21); 54411var InteractiveDateComponent = /** @class */ (function (_super) { 54412 tslib_1.__extends(InteractiveDateComponent, _super); 54413 function InteractiveDateComponent(_view, _options) { 54414 var _this = _super.call(this, _view, _options) || this; 54415 // self-config, overridable by subclasses 54416 _this.segSelector = '.fc-event-container > *'; // what constitutes an event element? 54417 if (_this.dateSelectingClass) { 54418 _this.dateClicking = new _this.dateClickingClass(_this); 54419 } 54420 if (_this.dateSelectingClass) { 54421 _this.dateSelecting = new _this.dateSelectingClass(_this); 54422 } 54423 if (_this.eventPointingClass) { 54424 _this.eventPointing = new _this.eventPointingClass(_this); 54425 } 54426 if (_this.eventDraggingClass && _this.eventPointing) { 54427 _this.eventDragging = new _this.eventDraggingClass(_this, _this.eventPointing); 54428 } 54429 if (_this.eventResizingClass && _this.eventPointing) { 54430 _this.eventResizing = new _this.eventResizingClass(_this, _this.eventPointing); 54431 } 54432 if (_this.externalDroppingClass) { 54433 _this.externalDropping = new _this.externalDroppingClass(_this); 54434 } 54435 return _this; 54436 } 54437 // Sets the container element that the view should render inside of, does global DOM-related initializations, 54438 // and renders all the non-date-related content inside. 54439 InteractiveDateComponent.prototype.setElement = function (el) { 54440 _super.prototype.setElement.call(this, el); 54441 if (this.dateClicking) { 54442 this.dateClicking.bindToEl(el); 54443 } 54444 if (this.dateSelecting) { 54445 this.dateSelecting.bindToEl(el); 54446 } 54447 this.bindAllSegHandlersToEl(el); 54448 }; 54449 InteractiveDateComponent.prototype.removeElement = function () { 54450 this.endInteractions(); 54451 _super.prototype.removeElement.call(this); 54452 }; 54453 InteractiveDateComponent.prototype.executeEventUnrender = function () { 54454 this.endInteractions(); 54455 _super.prototype.executeEventUnrender.call(this); 54456 }; 54457 InteractiveDateComponent.prototype.bindGlobalHandlers = function () { 54458 _super.prototype.bindGlobalHandlers.call(this); 54459 if (this.externalDropping) { 54460 this.externalDropping.bindToDocument(); 54461 } 54462 }; 54463 InteractiveDateComponent.prototype.unbindGlobalHandlers = function () { 54464 _super.prototype.unbindGlobalHandlers.call(this); 54465 if (this.externalDropping) { 54466 this.externalDropping.unbindFromDocument(); 54467 } 54468 }; 54469 InteractiveDateComponent.prototype.bindDateHandlerToEl = function (el, name, handler) { 54470 var _this = this; 54471 // attach a handler to the grid's root element. 54472 // jQuery will take care of unregistering them when removeElement gets called. 54473 this.el.on(name, function (ev) { 54474 if (!$(ev.target).is(_this.segSelector + ':not(.fc-helper),' + // directly on an event element 54475 _this.segSelector + ':not(.fc-helper) *,' + // within an event element 54476 '.fc-more,' + // a "more.." link 54477 'a[data-goto]' // a clickable nav link 54478 )) { 54479 return handler.call(_this, ev); 54480 } 54481 }); 54482 }; 54483 InteractiveDateComponent.prototype.bindAllSegHandlersToEl = function (el) { 54484 [ 54485 this.eventPointing, 54486 this.eventDragging, 54487 this.eventResizing 54488 ].forEach(function (eventInteraction) { 54489 if (eventInteraction) { 54490 eventInteraction.bindToEl(el); 54491 } 54492 }); 54493 }; 54494 InteractiveDateComponent.prototype.bindSegHandlerToEl = function (el, name, handler) { 54495 var _this = this; 54496 el.on(name, this.segSelector, function (ev) { 54497 var segEl = $(ev.currentTarget); 54498 if (!segEl.is('.fc-helper')) { 54499 var seg = segEl.data('fc-seg'); // grab segment data. put there by View::renderEventsPayload 54500 if (seg && !_this.shouldIgnoreEventPointing()) { 54501 return handler.call(_this, seg, ev); // context will be the Grid 54502 } 54503 } 54504 }); 54505 }; 54506 InteractiveDateComponent.prototype.shouldIgnoreMouse = function () { 54507 // HACK 54508 // This will still work even though bindDateHandlerToEl doesn't use GlobalEmitter. 54509 return GlobalEmitter_1.default.get().shouldIgnoreMouse(); 54510 }; 54511 InteractiveDateComponent.prototype.shouldIgnoreTouch = function () { 54512 var view = this._getView(); 54513 // On iOS (and Android?) when a new selection is initiated overtop another selection, 54514 // the touchend never fires because the elements gets removed mid-touch-interaction (my theory). 54515 // HACK: simply don't allow this to happen. 54516 // ALSO: prevent selection when an *event* is already raised. 54517 return view.isSelected || view.selectedEvent; 54518 }; 54519 InteractiveDateComponent.prototype.shouldIgnoreEventPointing = function () { 54520 // only call the handlers if there is not a drag/resize in progress 54521 return (this.eventDragging && this.eventDragging.isDragging) || 54522 (this.eventResizing && this.eventResizing.isResizing); 54523 }; 54524 InteractiveDateComponent.prototype.canStartSelection = function (seg, ev) { 54525 return util_1.getEvIsTouch(ev) && 54526 !this.canStartResize(seg, ev) && 54527 (this.isEventDefDraggable(seg.footprint.eventDef) || 54528 this.isEventDefResizable(seg.footprint.eventDef)); 54529 }; 54530 InteractiveDateComponent.prototype.canStartDrag = function (seg, ev) { 54531 return !this.canStartResize(seg, ev) && 54532 this.isEventDefDraggable(seg.footprint.eventDef); 54533 }; 54534 InteractiveDateComponent.prototype.canStartResize = function (seg, ev) { 54535 var view = this._getView(); 54536 var eventDef = seg.footprint.eventDef; 54537 return (!util_1.getEvIsTouch(ev) || view.isEventDefSelected(eventDef)) && 54538 this.isEventDefResizable(eventDef) && 54539 $(ev.target).is('.fc-resizer'); 54540 }; 54541 // Kills all in-progress dragging. 54542 // Useful for when public API methods that result in re-rendering are invoked during a drag. 54543 // Also useful for when touch devices misbehave and don't fire their touchend. 54544 InteractiveDateComponent.prototype.endInteractions = function () { 54545 [ 54546 this.dateClicking, 54547 this.dateSelecting, 54548 this.eventPointing, 54549 this.eventDragging, 54550 this.eventResizing 54551 ].forEach(function (interaction) { 54552 if (interaction) { 54553 interaction.end(); 54554 } 54555 }); 54556 }; 54557 // Event Drag-n-Drop 54558 // --------------------------------------------------------------------------------------------------------------- 54559 // Computes if the given event is allowed to be dragged by the user 54560 InteractiveDateComponent.prototype.isEventDefDraggable = function (eventDef) { 54561 return this.isEventDefStartEditable(eventDef); 54562 }; 54563 InteractiveDateComponent.prototype.isEventDefStartEditable = function (eventDef) { 54564 var isEditable = eventDef.isStartExplicitlyEditable(); 54565 if (isEditable == null) { 54566 isEditable = this.opt('eventStartEditable'); 54567 if (isEditable == null) { 54568 isEditable = this.isEventDefGenerallyEditable(eventDef); 54569 } 54570 } 54571 return isEditable; 54572 }; 54573 InteractiveDateComponent.prototype.isEventDefGenerallyEditable = function (eventDef) { 54574 var isEditable = eventDef.isExplicitlyEditable(); 54575 if (isEditable == null) { 54576 isEditable = this.opt('editable'); 54577 } 54578 return isEditable; 54579 }; 54580 // Event Resizing 54581 // --------------------------------------------------------------------------------------------------------------- 54582 // Computes if the given event is allowed to be resized from its starting edge 54583 InteractiveDateComponent.prototype.isEventDefResizableFromStart = function (eventDef) { 54584 return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef); 54585 }; 54586 // Computes if the given event is allowed to be resized from its ending edge 54587 InteractiveDateComponent.prototype.isEventDefResizableFromEnd = function (eventDef) { 54588 return this.isEventDefResizable(eventDef); 54589 }; 54590 // Computes if the given event is allowed to be resized by the user at all 54591 InteractiveDateComponent.prototype.isEventDefResizable = function (eventDef) { 54592 var isResizable = eventDef.isDurationExplicitlyEditable(); 54593 if (isResizable == null) { 54594 isResizable = this.opt('eventDurationEditable'); 54595 if (isResizable == null) { 54596 isResizable = this.isEventDefGenerallyEditable(eventDef); 54597 } 54598 } 54599 return isResizable; 54600 }; 54601 // Event Mutation / Constraints 54602 // --------------------------------------------------------------------------------------------------------------- 54603 // Diffs the two dates, returning a duration, based on granularity of the grid 54604 // TODO: port isTimeScale into this system? 54605 InteractiveDateComponent.prototype.diffDates = function (a, b) { 54606 if (this.largeUnit) { 54607 return util_1.diffByUnit(a, b, this.largeUnit); 54608 } 54609 else { 54610 return util_1.diffDayTime(a, b); 54611 } 54612 }; 54613 // is it allowed, in relation to the view's validRange? 54614 // NOTE: very similar to isExternalInstanceGroupAllowed 54615 InteractiveDateComponent.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) { 54616 var view = this._getView(); 54617 var dateProfile = this.dateProfile; 54618 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); 54619 var i; 54620 for (i = 0; i < eventFootprints.length; i++) { 54621 // TODO: just use getAllEventRanges directly 54622 if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) { 54623 return false; 54624 } 54625 } 54626 return view.calendar.constraints.isEventInstanceGroupAllowed(eventInstanceGroup); 54627 }; 54628 // NOTE: very similar to isEventInstanceGroupAllowed 54629 // when it's a completely anonymous external drag, no event. 54630 InteractiveDateComponent.prototype.isExternalInstanceGroupAllowed = function (eventInstanceGroup) { 54631 var view = this._getView(); 54632 var dateProfile = this.dateProfile; 54633 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); 54634 var i; 54635 for (i = 0; i < eventFootprints.length; i++) { 54636 if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) { 54637 return false; 54638 } 54639 } 54640 for (i = 0; i < eventFootprints.length; i++) { 54641 // treat it as a selection 54642 // TODO: pass in eventInstanceGroup instead 54643 // because we don't want calendar's constraint system to depend on a component's 54644 // determination of footprints. 54645 if (!view.calendar.constraints.isSelectionFootprintAllowed(eventFootprints[i].componentFootprint)) { 54646 return false; 54647 } 54648 } 54649 return true; 54650 }; 54651 return InteractiveDateComponent; 54652}(DateComponent_1.default)); 54653exports.default = InteractiveDateComponent; 54654 54655 54656/***/ }), 54657/* 41 */ 54658/***/ (function(module, exports, __webpack_require__) { 54659 54660Object.defineProperty(exports, "__esModule", { value: true });
54661var tslib_1 = __webpack_require__(2); 54662var $ = __webpack_require__(3); 54663var moment = __webpack_require__(0); 54664var util_1 = __webpack_require__(4); 54665var RenderQueue_1 = __webpack_require__(218); 54666var DateProfileGenerator_1 = __webpack_require__(221); 54667var InteractiveDateComponent_1 = __webpack_require__(40); 54668var GlobalEmitter_1 = __webpack_require__(21); 54669var UnzonedRange_1 = __webpack_require__(5); 54670/* An abstract class from which other views inherit from 54671----------------------------------------------------------------------------------------------------------------------*/ 54672var View = /** @class */ (function (_super) { 54673 tslib_1.__extends(View, _super); 54674 function View(calendar, viewSpec) { 54675 var _this = _super.call(this, null, viewSpec.options) || this; 54676 _this.batchRenderDepth = 0; 54677 _this.isSelected = false; // boolean whether a range of time is user-selected or not 54678 _this.calendar = calendar; 54679 _this.viewSpec = viewSpec; 54680 // shortcuts 54681 _this.type = viewSpec.type; 54682 // .name is deprecated 54683 _this.name = _this.type; 54684 _this.initRenderQueue(); 54685 _this.initHiddenDays(); 54686 _this.dateProfileGenerator = new _this.dateProfileGeneratorClass(_this); 54687 _this.bindBaseRenderHandlers(); 54688 _this.eventOrderSpecs = util_1.parseFieldSpecs(_this.opt('eventOrder')); 54689 // legacy 54690 if (_this['initialize']) { 54691 _this['initialize'](); 54692 } 54693 return _this; 54694 } 54695 View.prototype._getView = function () { 54696 return this; 54697 }; 54698 // Retrieves an option with the given name 54699 View.prototype.opt = function (name) { 54700 return this.options[name]; 54701 }; 54702 /* Render Queue 54703 ------------------------------------------------------------------------------------------------------------------*/ 54704 View.prototype.initRenderQueue = function () { 54705 this.renderQueue = new RenderQueue_1.default({ 54706 event: this.opt('eventRenderWait') 54707 }); 54708 this.renderQueue.on('start', this.onRenderQueueStart.bind(this)); 54709 this.renderQueue.on('stop', this.onRenderQueueStop.bind(this)); 54710 this.on('before:change', this.startBatchRender); 54711 this.on('change', this.stopBatchRender); 54712 }; 54713 View.prototype.onRenderQueueStart = function () { 54714 this.calendar.freezeContentHeight(); 54715 this.addScroll(this.queryScroll()); 54716 }; 54717 View.prototype.onRenderQueueStop = function () { 54718 if (this.calendar.updateViewSize()) { 54719 this.popScroll(); 54720 } 54721 this.calendar.thawContentHeight(); 54722 }; 54723 View.prototype.startBatchRender = function () { 54724 if (!(this.batchRenderDepth++)) { 54725 this.renderQueue.pause(); 54726 } 54727 }; 54728 View.prototype.stopBatchRender = function () { 54729 if (!(--this.batchRenderDepth)) { 54730 this.renderQueue.resume(); 54731 } 54732 }; 54733 View.prototype.requestRender = function (func, namespace, actionType) { 54734 this.renderQueue.queue(func, namespace, actionType); 54735 }; 54736 // given func will auto-bind to `this` 54737 View.prototype.whenSizeUpdated = function (func) { 54738 if (this.renderQueue.isRunning) { 54739 this.renderQueue.one('stop', func.bind(this)); 54740 } 54741 else { 54742 func.call(this); 54743 } 54744 }; 54745 /* Title and Date Formatting 54746 ------------------------------------------------------------------------------------------------------------------*/ 54747 // Computes what the title at the top of the calendar should be for this view 54748 View.prototype.computeTitle = function (dateProfile) { 54749 var unzonedRange; 54750 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after 54751 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 54752 unzonedRange = dateProfile.currentUnzonedRange; 54753 } 54754 else { 54755 unzonedRange = dateProfile.activeUnzonedRange; 54756 } 54757 return this.formatRange({ 54758 start: this.calendar.msToMoment(unzonedRange.startMs, dateProfile.isRangeAllDay), 54759 end: this.calendar.msToMoment(unzonedRange.endMs, dateProfile.isRangeAllDay) 54760 }, dateProfile.isRangeAllDay, this.opt('titleFormat') || this.computeTitleFormat(dateProfile), this.opt('titleRangeSeparator')); 54761 };
54762 // Generates the format string that should be used to generate the title for the current date range. 54763 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. 54764 View.prototype.computeTitleFormat = function (dateProfile) { 54765 var currentRangeUnit = dateProfile.currentRangeUnit; 54766 if (currentRangeUnit === 'year') { 54767 return 'YYYY'; 54768 } 54769 else if (currentRangeUnit === 'month') { 54770 return this.opt('monthYearFormat'); // like "September 2014" 54771 } 54772 else if (dateProfile.currentUnzonedRange.as('days') > 1) { 54773 return 'll'; // multi-day range. shorter, like "Sep 9 - 10 2014" 54774 } 54775 else { 54776 return 'LL'; // one day. longer, like "September 9 2014" 54777 } 54778 }; 54779 // Date Setting/Unsetting 54780 // ----------------------------------------------------------------------------------------------------------------- 54781 View.prototype.setDate = function (date) { 54782 var currentDateProfile = this.get('dateProfile'); 54783 var newDateProfile = this.dateProfileGenerator.build(date, undefined, true); // forceToValid=true 54784 if (!currentDateProfile || 54785 !currentDateProfile.activeUnzonedRange.equals(newDateProfile.activeUnzonedRange)) { 54786 this.set('dateProfile', newDateProfile); 54787 } 54788 }; 54789 View.prototype.unsetDate = function () { 54790 this.unset('dateProfile'); 54791 }; 54792 // Event Data 54793 // ----------------------------------------------------------------------------------------------------------------- 54794 View.prototype.fetchInitialEvents = function (dateProfile) { 54795 var calendar = this.calendar; 54796 var forceAllDay = dateProfile.isRangeAllDay && !this.usesMinMaxTime; 54797 return calendar.requestEvents(calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, forceAllDay), calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, forceAllDay)); 54798 }; 54799 View.prototype.bindEventChanges = function () { 54800 this.listenTo(this.calendar, 'eventsReset', this.resetEvents); // TODO: make this a real event 54801 }; 54802 View.prototype.unbindEventChanges = function () { 54803 this.stopListeningTo(this.calendar, 'eventsReset'); 54804 }; 54805 View.prototype.setEvents = function (eventsPayload) { 54806 this.set('currentEvents', eventsPayload); 54807 this.set('hasEvents', true); 54808 }; 54809 View.prototype.unsetEvents = function () { 54810 this.unset('currentEvents'); 54811 this.unset('hasEvents'); 54812 }; 54813 View.prototype.resetEvents = function (eventsPayload) { 54814 this.startBatchRender(); 54815 this.unsetEvents(); 54816 this.setEvents(eventsPayload); 54817 this.stopBatchRender(); 54818 }; 54819 // Date High-level Rendering 54820 // ----------------------------------------------------------------------------------------------------------------- 54821 View.prototype.requestDateRender = function (dateProfile) { 54822 var _this = this; 54823 this.requestRender(function () { 54824 _this.executeDateRender(dateProfile); 54825 }, 'date', 'init'); 54826 }; 54827 View.prototype.requestDateUnrender = function () { 54828 var _this = this; 54829 this.requestRender(function () { 54830 _this.executeDateUnrender(); 54831 }, 'date', 'destroy'); 54832 }; 54833 // if dateProfile not specified, uses current 54834 View.prototype.executeDateRender = function (dateProfile) { 54835 _super.prototype.executeDateRender.call(this, dateProfile); 54836 if (this['render']) { 54837 this['render'](); // TODO: deprecate 54838 } 54839 this.trigger('datesRendered'); 54840 this.addScroll({ isDateInit: true }); 54841 this.startNowIndicator(); // shouldn't render yet because updateSize will be called soon 54842 }; 54843 View.prototype.executeDateUnrender = function () { 54844 this.unselect(); 54845 this.stopNowIndicator(); 54846 this.trigger('before:datesUnrendered'); 54847 if (this['destroy']) { 54848 this['destroy'](); // TODO: deprecate 54849 } 54850 _super.prototype.executeDateUnrender.call(this); 54851 }; 54852 // "Base" rendering 54853 // -----------------------------------------------------------------------------------------------------------------
54854 View.prototype.bindBaseRenderHandlers = function () { 54855 var _this = this; 54856 this.on('datesRendered', function () { 54857 _this.whenSizeUpdated(_this.triggerViewRender); 54858 }); 54859 this.on('before:datesUnrendered', function () { 54860 _this.triggerViewDestroy(); 54861 }); 54862 }; 54863 View.prototype.triggerViewRender = function () { 54864 this.publiclyTrigger('viewRender', { 54865 context: this, 54866 args: [this, this.el] 54867 }); 54868 }; 54869 View.prototype.triggerViewDestroy = function () { 54870 this.publiclyTrigger('viewDestroy', { 54871 context: this, 54872 args: [this, this.el] 54873 }); 54874 }; 54875 // Event High-level Rendering 54876 // ----------------------------------------------------------------------------------------------------------------- 54877 View.prototype.requestEventsRender = function (eventsPayload) { 54878 var _this = this; 54879 this.requestRender(function () { 54880 _this.executeEventRender(eventsPayload); 54881 _this.whenSizeUpdated(_this.triggerAfterEventsRendered); 54882 }, 'event', 'init'); 54883 }; 54884 View.prototype.requestEventsUnrender = function () { 54885 var _this = this; 54886 this.requestRender(function () { 54887 _this.triggerBeforeEventsDestroyed(); 54888 _this.executeEventUnrender(); 54889 }, 'event', 'destroy'); 54890 }; 54891 // Business Hour High-level Rendering 54892 // ----------------------------------------------------------------------------------------------------------------- 54893 View.prototype.requestBusinessHoursRender = function (businessHourGenerator) { 54894 var _this = this; 54895 this.requestRender(function () { 54896 _this.renderBusinessHours(businessHourGenerator); 54897 }, 'businessHours', 'init'); 54898 }; 54899 View.prototype.requestBusinessHoursUnrender = function () { 54900 var _this = this; 54901 this.requestRender(function () { 54902 _this.unrenderBusinessHours(); 54903 }, 'businessHours', 'destroy'); 54904 }; 54905 // Misc view rendering utils 54906 // ----------------------------------------------------------------------------------------------------------------- 54907 // Binds DOM handlers to elements that reside outside the view container, such as the document 54908 View.prototype.bindGlobalHandlers = function () { 54909 _super.prototype.bindGlobalHandlers.call(this); 54910 this.listenTo(GlobalEmitter_1.default.get(), { 54911 touchstart: this.processUnselect, 54912 mousedown: this.handleDocumentMousedown 54913 }); 54914 }; 54915 // Unbinds DOM handlers from elements that reside outside the view container 54916 View.prototype.unbindGlobalHandlers = function () { 54917 _super.prototype.unbindGlobalHandlers.call(this); 54918 this.stopListeningTo(GlobalEmitter_1.default.get()); 54919 }; 54920 /* Now Indicator 54921 ------------------------------------------------------------------------------------------------------------------*/ 54922 // Immediately render the current time indicator and begins re-rendering it at an interval, 54923 // which is defined by this.getNowIndicatorUnit(). 54924 // TODO: somehow do this for the current whole day's background too 54925 View.prototype.startNowIndicator = function () { 54926 var _this = this; 54927 var unit; 54928 var update; 54929 var delay; // ms wait value 54930 if (this.opt('nowIndicator')) { 54931 unit = this.getNowIndicatorUnit(); 54932 if (unit) { 54933 update = util_1.proxy(this, 'updateNowIndicator'); // bind to `this` 54934 this.initialNowDate = this.calendar.getNow(); 54935 this.initialNowQueriedMs = new Date().valueOf(); 54936 // wait until the beginning of the next interval 54937 delay = this.initialNowDate.clone().startOf(unit).add(1, unit).valueOf() - this.initialNowDate.valueOf(); 54938 this.nowIndicatorTimeoutID = setTimeout(function () { 54939 _this.nowIndicatorTimeoutID = null; 54940 update();
54941 delay = +moment.duration(1, unit); 54942 delay = Math.max(100, delay); // prevent too frequent 54943 _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval 54944 }, delay); 54945 } 54946 // rendering will be initiated in updateSize 54947 } 54948 }; 54949 // rerenders the now indicator, computing the new current time from the amount of time that has passed 54950 // since the initial getNow call. 54951 View.prototype.updateNowIndicator = function () { 54952 if (this.isDatesRendered && 54953 this.initialNowDate // activated before? 54954 ) { 54955 this.unrenderNowIndicator(); // won't unrender if unnecessary 54956 this.renderNowIndicator(this.initialNowDate.clone().add(new Date().valueOf() - this.initialNowQueriedMs) // add ms 54957 ); 54958 this.isNowIndicatorRendered = true; 54959 } 54960 }; 54961 // Immediately unrenders the view's current time indicator and stops any re-rendering timers. 54962 // Won't cause side effects if indicator isn't rendered. 54963 View.prototype.stopNowIndicator = function () { 54964 if (this.isNowIndicatorRendered) { 54965 if (this.nowIndicatorTimeoutID) { 54966 clearTimeout(this.nowIndicatorTimeoutID); 54967 this.nowIndicatorTimeoutID = null; 54968 } 54969 if (this.nowIndicatorIntervalID) { 54970 clearInterval(this.nowIndicatorIntervalID); 54971 this.nowIndicatorIntervalID = null; 54972 } 54973 this.unrenderNowIndicator(); 54974 this.isNowIndicatorRendered = false; 54975 } 54976 }; 54977 /* Dimensions 54978 ------------------------------------------------------------------------------------------------------------------*/ 54979 View.prototype.updateSize = function (totalHeight, isAuto, isResize) { 54980 if (this['setHeight']) { 54981 this['setHeight'](totalHeight, isAuto); 54982 } 54983 else { 54984 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 54985 } 54986 this.updateNowIndicator(); 54987 }; 54988 /* Scroller 54989 ------------------------------------------------------------------------------------------------------------------*/ 54990 View.prototype.addScroll = function (scroll) { 54991 var queuedScroll = this.queuedScroll || (this.queuedScroll = {}); 54992 $.extend(queuedScroll, scroll); 54993 }; 54994 View.prototype.popScroll = function () { 54995 this.applyQueuedScroll(); 54996 this.queuedScroll = null; 54997 }; 54998 View.prototype.applyQueuedScroll = function () { 54999 if (this.queuedScroll) { 55000 this.applyScroll(this.queuedScroll); 55001 } 55002 }; 55003 View.prototype.queryScroll = function () { 55004 var scroll = {}; 55005 if (this.isDatesRendered) { 55006 $.extend(scroll, this.queryDateScroll()); 55007 } 55008 return scroll; 55009 }; 55010 View.prototype.applyScroll = function (scroll) { 55011 if (scroll.isDateInit && this.isDatesRendered) { 55012 $.extend(scroll, this.computeInitialDateScroll()); 55013 } 55014 if (this.isDatesRendered) { 55015 this.applyDateScroll(scroll); 55016 } 55017 }; 55018 View.prototype.computeInitialDateScroll = function () { 55019 return {}; // subclasses must implement 55020 }; 55021 View.prototype.queryDateScroll = function () { 55022 return {}; // subclasses must implement 55023 }; 55024 View.prototype.applyDateScroll = function (scroll) { 55025 // subclasses must implement 55026 }; 55027 /* Event Drag-n-Drop 55028 ------------------------------------------------------------------------------------------------------------------*/ 55029 View.prototype.reportEventDrop = function (eventInstance, eventMutation, el, ev) { 55030 var eventManager = this.calendar.eventManager; 55031 var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation); 55032 var dateMutation = eventMutation.dateMutation; 55033 // update the EventInstance, for handlers 55034 if (dateMutation) { 55035 eventInstance.dateProfile = dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar); 55036 } 55037 this.triggerEventDrop(eventInstance, 55038 // a drop doesn't necessarily mean a date mutation (ex: resource change) 55039 (dateMutation && dateMutation.dateDelta) || moment.duration(), undoFunc, el, ev); 55040 }; 55041 // Triggers event-drop handlers that have subscribed via the API 55042 View.prototype.triggerEventDrop = function (eventInstance, dateDelta, undoFunc, el, ev) { 55043 this.publiclyTrigger('eventDrop', { 55044 context: el[0], 55045 args: [ 55046 eventInstance.toLegacy(), 55047 dateDelta, 55048 undoFunc, 55049 ev, 55050 {}, 55051 this 55052 ] 55053 }); 55054 }; 55055 /* External Element Drag-n-Drop 55056 ------------------------------------------------------------------------------------------------------------------*/ 55057 // Must be called when an external element, via jQuery UI, has been dropped onto the calendar. 55058 // `meta` is the parsed data that has been embedded into the dragging event. 55059 // `dropLocation` is an object that contains the new zoned start/end/allDay values for the event. 55060 View.prototype.reportExternalDrop = function (singleEventDef, isEvent, isSticky, el, ev, ui) { 55061 if (isEvent) { 55062 this.calendar.eventManager.addEventDef(singleEventDef, isSticky); 55063 } 55064 this.triggerExternalDrop(singleEventDef, isEvent, el, ev, ui); 55065 }; 55066 // Triggers external-drop handlers that have subscribed via the API 55067 View.prototype.triggerExternalDrop = function (singleEventDef, isEvent, el, ev, ui) { 55068 // trigger 'drop' regardless of whether element represents an event 55069 this.publiclyTrigger('drop', { 55070 context: el[0], 55071 args: [ 55072 singleEventDef.dateProfile.start.clone(), 55073 ev, 55074 ui, 55075 this 55076 ] 55077 }); 55078 if (isEvent) { 55079 // signal an external event landed 55080 this.publiclyTrigger('eventReceive', { 55081 context: this, 55082 args: [ 55083 singleEventDef.buildInstance().toLegacy(), 55084 this 55085 ] 55086 }); 55087 } 55088 }; 55089 /* Event Resizing 55090 ------------------------------------------------------------------------------------------------------------------*/ 55091 // Must be called when an event in the view has been resized to a new length 55092 View.prototype.reportEventResize = function (eventInstance, eventMutation, el, ev) { 55093 var eventManager = this.calendar.eventManager;
55094 var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation); 55095 // update the EventInstance, for handlers 55096 eventInstance.dateProfile = eventMutation.dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar); 55097 this.triggerEventResize(eventInstance, eventMutation.dateMutation.endDelta, undoFunc, el, ev); 55098 }; 55099 // Triggers event-resize handlers that have subscribed via the API 55100 View.prototype.triggerEventResize = function (eventInstance, durationDelta, undoFunc, el, ev) { 55101 this.publiclyTrigger('eventResize', { 55102 context: el[0], 55103 args: [ 55104 eventInstance.toLegacy(), 55105 durationDelta, 55106 undoFunc, 55107 ev, 55108 {}, 55109 this 55110 ] 55111 }); 55112 }; 55113 /* Selection (time range) 55114 ------------------------------------------------------------------------------------------------------------------*/ 55115 // Selects a date span on the view. `start` and `end` are both Moments. 55116 // `ev` is the native mouse event that begin the interaction. 55117 View.prototype.select = function (footprint, ev) { 55118 this.unselect(ev); 55119 this.renderSelectionFootprint(footprint); 55120 this.reportSelection(footprint, ev); 55121 }; 55122 View.prototype.renderSelectionFootprint = function (footprint) { 55123 if (this['renderSelection']) { 55124 this['renderSelection'](footprint.toLegacy(this.calendar)); 55125 } 55126 else { 55127 _super.prototype.renderSelectionFootprint.call(this, footprint); 55128 } 55129 }; 55130 // Called when a new selection is made. Updates internal state and triggers handlers. 55131 View.prototype.reportSelection = function (footprint, ev) { 55132 this.isSelected = true; 55133 this.triggerSelect(footprint, ev); 55134 }; 55135 // Triggers handlers to 'select' 55136 View.prototype.triggerSelect = function (footprint, ev) { 55137 var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile? 55138 this.publiclyTrigger('select', { 55139 context: this, 55140 args: [ 55141 dateProfile.start, 55142 dateProfile.end, 55143 ev, 55144 this 55145 ] 55146 }); 55147 }; 55148 // Undoes a selection. updates in the internal state and triggers handlers. 55149 // `ev` is the native mouse event that began the interaction. 55150 View.prototype.unselect = function (ev) { 55151 if (this.isSelected) { 55152 this.isSelected = false; 55153 if (this['destroySelection']) { 55154 this['destroySelection'](); // TODO: deprecate 55155 } 55156 this.unrenderSelection(); 55157 this.publiclyTrigger('unselect', { 55158 context: this, 55159 args: [ev, this] 55160 }); 55161 } 55162 }; 55163 /* Event Selection 55164 ------------------------------------------------------------------------------------------------------------------*/ 55165 View.prototype.selectEventInstance = function (eventInstance) { 55166 if (!this.selectedEventInstance || 55167 this.selectedEventInstance !== eventInstance) { 55168 this.unselectEventInstance(); 55169 this.getEventSegs().forEach(function (seg) { 55170 if (seg.footprint.eventInstance === eventInstance && 55171 seg.el // necessary? 55172 ) { 55173 seg.el.addClass('fc-selected'); 55174 } 55175 }); 55176 this.selectedEventInstance = eventInstance; 55177 } 55178 }; 55179 View.prototype.unselectEventInstance = function () { 55180 if (this.selectedEventInstance) { 55181 this.getEventSegs().forEach(function (seg) { 55182 if (seg.el) { 55183 seg.el.removeClass('fc-selected'); 55184 } 55185 }); 55186 this.selectedEventInstance = null; 55187 } 55188 }; 55189 View.prototype.isEventDefSelected = function (eventDef) { 55190 // event references might change on refetchEvents(), while selectedEventInstance doesn't, 55191 // so compare IDs 55192 return this.selectedEventInstance && this.selectedEventInstance.def.id === eventDef.id; 55193 }; 55194 /* Mouse / Touch Unselecting (time range & event unselection) 55195 ------------------------------------------------------------------------------------------------------------------*/ 55196 // TODO: move consistently to down/start or up/end? 55197 // TODO: don't kill previous selection if touch scrolling 55198 View.prototype.handleDocumentMousedown = function (ev) { 55199 if (util_1.isPrimaryMouseButton(ev)) { 55200 this.processUnselect(ev); 55201 } 55202 }; 55203 View.prototype.processUnselect = function (ev) { 55204 this.processRangeUnselect(ev); 55205 this.processEventUnselect(ev); 55206 }; 55207 View.prototype.processRangeUnselect = function (ev) { 55208 var ignore;
55209 // is there a time-range selection? 55210 if (this.isSelected && this.opt('unselectAuto')) { 55211 // only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element 55212 ignore = this.opt('unselectCancel'); 55213 if (!ignore || !$(ev.target).closest(ignore).length) { 55214 this.unselect(ev); 55215 } 55216 } 55217 }; 55218 View.prototype.processEventUnselect = function (ev) { 55219 if (this.selectedEventInstance) { 55220 if (!$(ev.target).closest('.fc-selected').length) { 55221 this.unselectEventInstance(); 55222 } 55223 } 55224 }; 55225 /* Triggers 55226 ------------------------------------------------------------------------------------------------------------------*/ 55227 View.prototype.triggerBaseRendered = function () { 55228 this.publiclyTrigger('viewRender', { 55229 context: this, 55230 args: [this, this.el] 55231 }); 55232 }; 55233 View.prototype.triggerBaseUnrendered = function () { 55234 this.publiclyTrigger('viewDestroy', { 55235 context: this, 55236 args: [this, this.el] 55237 }); 55238 }; 55239 // Triggers handlers to 'dayClick' 55240 // Span has start/end of the clicked area. Only the start is useful. 55241 View.prototype.triggerDayClick = function (footprint, dayEl, ev) { 55242 var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile? 55243 this.publiclyTrigger('dayClick', { 55244 context: dayEl, 55245 args: [dateProfile.start, ev, this] 55246 }); 55247 }; 55248 /* Date Utils 55249 ------------------------------------------------------------------------------------------------------------------*/ 55250 // For DateComponent::getDayClasses 55251 View.prototype.isDateInOtherMonth = function (date, dateProfile) { 55252 return false; 55253 }; 55254 // Arguments after name will be forwarded to a hypothetical function value 55255 // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects. 55256 // Always clone your objects if you fear mutation. 55257 View.prototype.getUnzonedRangeOption = function (name) { 55258 var val = this.opt(name); 55259 if (typeof val === 'function') { 55260 val = val.apply(null, Array.prototype.slice.call(arguments, 1)); 55261 } 55262 if (val) { 55263 return this.calendar.parseUnzonedRange(val); 55264 } 55265 }; 55266 /* Hidden Days 55267 ------------------------------------------------------------------------------------------------------------------*/ 55268 // Initializes internal variables related to calculating hidden days-of-week 55269 View.prototype.initHiddenDays = function () { 55270 var hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden 55271 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) 55272 var dayCnt = 0; 55273 var i; 55274 if (this.opt('weekends') === false) { 55275 hiddenDays.push(0, 6); // 0=sunday, 6=saturday 55276 } 55277 for (i = 0; i < 7; i++) { 55278 if (!(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)) { 55279 dayCnt++; 55280 } 55281 } 55282 if (!dayCnt) { 55283 throw new Error('invalid hiddenDays'); // all days were hidden? bad. 55284 } 55285 this.isHiddenDayHash = isHiddenDayHash; 55286 }; 55287 // Remove days from the beginning and end of the range that are computed as hidden. 55288 // If the whole range is trimmed off, returns null 55289 View.prototype.trimHiddenDays = function (inputUnzonedRange) { 55290 var start = inputUnzonedRange.getStart(); 55291 var end = inputUnzonedRange.getEnd(); 55292 if (start) { 55293 start = this.skipHiddenDays(start); 55294 } 55295 if (end) { 55296 end = this.skipHiddenDays(end, -1, true); 55297 } 55298 if (start === null || end === null || start < end) { 55299 return new UnzonedRange_1.default(start, end); 55300 } 55301 return null; 55302 }; 55303 // Is the current day hidden? 55304 // `day` is a day-of-week index (0-6), or a Moment
55305 View.prototype.isHiddenDay = function (day) { 55306 if (moment.isMoment(day)) { 55307 day = day.day(); 55308 } 55309 return this.isHiddenDayHash[day]; 55310 }; 55311 // Incrementing the current day until it is no longer a hidden day, returning a copy. 55312 // DOES NOT CONSIDER validUnzonedRange! 55313 // If the initial value of `date` is not a hidden day, don't do anything. 55314 // Pass `isExclusive` as `true` if you are dealing with an end date. 55315 // `inc` defaults to `1` (increment one day forward each time) 55316 View.prototype.skipHiddenDays = function (date, inc, isExclusive) { 55317 if (inc === void 0) { inc = 1; } 55318 if (isExclusive === void 0) { isExclusive = false; } 55319 var out = date.clone(); 55320 while (this.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]) { 55321 out.add(inc, 'days'); 55322 } 55323 return out; 55324 }; 55325 return View; 55326}(InteractiveDateComponent_1.default)); 55327exports.default = View; 55328View.prototype.usesMinMaxTime = false; 55329View.prototype.dateProfileGeneratorClass = DateProfileGenerator_1.default; 55330View.watch('displayingDates', ['isInDom', 'dateProfile'], function (deps) { 55331 this.requestDateRender(deps.dateProfile); 55332}, function () { 55333 this.requestDateUnrender(); 55334}); 55335View.watch('displayingBusinessHours', ['displayingDates', 'businessHourGenerator'], function (deps) { 55336 this.requestBusinessHoursRender(deps.businessHourGenerator); 55337}, function () { 55338 this.requestBusinessHoursUnrender(); 55339}); 55340View.watch('initialEvents', ['dateProfile'], function (deps) { 55341 return this.fetchInitialEvents(deps.dateProfile); 55342}); 55343View.watch('bindingEvents', ['initialEvents'], function (deps) { 55344 this.setEvents(deps.initialEvents); 55345 this.bindEventChanges(); 55346}, function () { 55347 this.unbindEventChanges(); 55348 this.unsetEvents(); 55349}); 55350View.watch('displayingEvents', ['displayingDates', 'hasEvents'], function () { 55351 this.requestEventsRender(this.get('currentEvents')); 55352}, function () { 55353 this.requestEventsUnrender(); 55354}); 55355View.watch('title', ['dateProfile'], function (deps) { 55356 return (this.title = this.computeTitle(deps.dateProfile)); // assign to View for legacy reasons 55357}); 55358View.watch('legacyDateProps', ['dateProfile'], function (deps) { 55359 var calendar = this.calendar; 55360 var dateProfile = deps.dateProfile; 55361 // DEPRECATED, but we need to keep it updated... 55362 this.start = calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, dateProfile.isRangeAllDay); 55363 this.end = calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, dateProfile.isRangeAllDay); 55364 this.intervalStart = calendar.msToMoment(dateProfile.currentUnzonedRange.startMs, dateProfile.isRangeAllDay); 55365 this.intervalEnd = calendar.msToMoment(dateProfile.currentUnzonedRange.endMs, dateProfile.isRangeAllDay); 55366}); 55367 55368 55369/***/ }), 55370/* 42 */ 55371/***/ (function(module, exports, __webpack_require__) { 55372 55373Object.defineProperty(exports, "__esModule", { value: true }); 55374var $ = __webpack_require__(3); 55375var util_1 = __webpack_require__(4); 55376var EventRenderer = /** @class */ (function () { 55377 function EventRenderer(component, fillRenderer) { 55378 this.view = component._getView(); 55379 this.component = component; 55380 this.fillRenderer = fillRenderer; 55381 } 55382 EventRenderer.prototype.opt = function (name) { 55383 return this.view.opt(name); 55384 }; 55385 // Updates values that rely on options and also relate to range 55386 EventRenderer.prototype.rangeUpdated = function () { 55387 var displayEventTime; 55388 var displayEventEnd; 55389 this.eventTimeFormat = 55390 this.opt('eventTimeFormat') || 55391 this.opt('timeFormat') || // deprecated 55392 this.computeEventTimeFormat(); 55393 displayEventTime = this.opt('displayEventTime'); 55394 if (displayEventTime == null) { 55395 displayEventTime = this.computeDisplayEventTime(); // might be based off of range 55396 } 55397 displayEventEnd = this.opt('displayEventEnd'); 55398 if (displayEventEnd == null) { 55399 displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range 55400 } 55401 this.displayEventTime = displayEventTime; 55402 this.displayEventEnd = displayEventEnd; 55403 }; 55404 EventRenderer.prototype.render = function (eventsPayload) { 55405 var dateProfile = this.component._getDateProfile(); 55406 var eventDefId; 55407 var instanceGroup; 55408 var eventRanges;
55409 var bgRanges = []; 55410 var fgRanges = []; 55411 for (eventDefId in eventsPayload) { 55412 instanceGroup = eventsPayload[eventDefId]; 55413 eventRanges = instanceGroup.sliceRenderRanges(dateProfile.activeUnzonedRange); 55414 if (instanceGroup.getEventDef().hasBgRendering()) { 55415 bgRanges.push.apply(bgRanges, eventRanges); 55416 } 55417 else { 55418 fgRanges.push.apply(fgRanges, eventRanges); 55419 } 55420 } 55421 this.renderBgRanges(bgRanges); 55422 this.renderFgRanges(fgRanges); 55423 }; 55424 EventRenderer.prototype.unrender = function () { 55425 this.unrenderBgRanges(); 55426 this.unrenderFgRanges(); 55427 }; 55428 EventRenderer.prototype.renderFgRanges = function (eventRanges) { 55429 var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges); 55430 var segs = this.component.eventFootprintsToSegs(eventFootprints); 55431 // render an `.el` on each seg 55432 // returns a subset of the segs. segs that were actually rendered 55433 segs = this.renderFgSegEls(segs); 55434 if (this.renderFgSegs(segs) !== false) { 55435 this.fgSegs = segs; 55436 } 55437 }; 55438 EventRenderer.prototype.unrenderFgRanges = function () { 55439 this.unrenderFgSegs(this.fgSegs || []); 55440 this.fgSegs = null; 55441 }; 55442 EventRenderer.prototype.renderBgRanges = function (eventRanges) { 55443 var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges); 55444 var segs = this.component.eventFootprintsToSegs(eventFootprints); 55445 if (this.renderBgSegs(segs) !== false) { 55446 this.bgSegs = segs; 55447 } 55448 }; 55449 EventRenderer.prototype.unrenderBgRanges = function () { 55450 this.unrenderBgSegs(); 55451 this.bgSegs = null; 55452 }; 55453 EventRenderer.prototype.getSegs = function () { 55454 return (this.bgSegs || []).concat(this.fgSegs || []); 55455 }; 55456 // Renders foreground event segments onto the grid 55457 EventRenderer.prototype.renderFgSegs = function (segs) { 55458 // subclasses must implement 55459 // segs already has rendered els, and has been filtered. 55460 return false; // signal failure if not implemented 55461 }; 55462 // Unrenders all currently rendered foreground segments 55463 EventRenderer.prototype.unrenderFgSegs = function (segs) { 55464 // subclasses must implement 55465 }; 55466 EventRenderer.prototype.renderBgSegs = function (segs) { 55467 var _this = this; 55468 if (this.fillRenderer) { 55469 this.fillRenderer.renderSegs('bgEvent', segs, { 55470 getClasses: function (seg) { 55471 return _this.getBgClasses(seg.footprint.eventDef); 55472 }, 55473 getCss: function (seg) { 55474 return { 55475 'background-color': _this.getBgColor(seg.footprint.eventDef) 55476 }; 55477 }, 55478 filterEl: function (seg, el) { 55479 return _this.filterEventRenderEl(seg.footprint, el); 55480 } 55481 }); 55482 } 55483 else { 55484 return false; // signal failure if no fillRenderer 55485 } 55486 }; 55487 EventRenderer.prototype.unrenderBgSegs = function () { 55488 if (this.fillRenderer) { 55489 this.fillRenderer.unrender('bgEvent'); 55490 } 55491 }; 55492 // Renders and assigns an `el` property for each foreground event segment. 55493 // Only returns segments that successfully rendered. 55494 EventRenderer.prototype.renderFgSegEls = function (segs, disableResizing) { 55495 var _this = this; 55496 if (disableResizing === void 0) { disableResizing = false; } 55497 var hasEventRenderHandlers = this.view.hasPublicHandlers('eventRender'); 55498 var html = ''; 55499 var renderedSegs = []; 55500 var i; 55501 if (segs.length) { 55502 // build a large concatenation of event segment HTML 55503 for (i = 0; i < segs.length; i++) { 55504 this.beforeFgSegHtml(segs[i]); 55505 html += this.fgSegHtml(segs[i], disableResizing); 55506 } 55507 // Grab individual elements from the combined HTML string. Use each as the default rendering. 55508 // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false. 55509 $(html).each(function (i, node) { 55510 var seg = segs[i]; 55511 var el = $(node); 55512 if (hasEventRenderHandlers) { 55513 el = _this.filterEventRenderEl(seg.footprint, el); 55514 } 55515 if (el) { 55516 el.data('fc-seg', seg); // used by handlers 55517 seg.el = el; 55518 renderedSegs.push(seg); 55519 } 55520 }); 55521 } 55522 return renderedSegs; 55523 }; 55524 EventRenderer.prototype.beforeFgSegHtml = function (seg) { 55525 }; 55526 // Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls() 55527 EventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { 55528 // subclasses should implement 55529 }; 55530 // Generic utility for generating the HTML classNames for an event segment's element 55531 EventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable) { 55532 var classes = [ 55533 'fc-event', 55534 seg.isStart ? 'fc-start' : 'fc-not-start', 55535 seg.isEnd ? 'fc-end' : 'fc-not-end' 55536 ].concat(this.getClasses(seg.footprint.eventDef)); 55537 if (isDraggable) { 55538 classes.push('fc-draggable'); 55539 } 55540 if (isResizable) { 55541 classes.push('fc-resizable'); 55542 } 55543 // event is currently selected? attach a className. 55544 if (this.view.isEventDefSelected(seg.footprint.eventDef)) { 55545 classes.push('fc-selected'); 55546 } 55547 return classes; 55548 }; 55549 // Given an event and the default element used for rendering, returns the element that should actually be used. 55550 // Basically runs events and elements through the eventRender hook. 55551 EventRenderer.prototype.filterEventRenderEl = function (eventFootprint, el) { 55552 var legacy = eventFootprint.getEventLegacy(); 55553 var custom = this.view.publiclyTrigger('eventRender', { 55554 context: legacy, 55555 args: [legacy, el, this.view] 55556 }); 55557 if (custom === false) { 55558 el = null; 55559 } 55560 else if (custom && custom !== true) { 55561 el = $(custom); 55562 } 55563 return el; 55564 }; 55565 // Compute the text that should be displayed on an event's element. 55566 // `range` can be the Event object itself, or something range-like, with at least a `start`. 55567 // If event times are disabled, or the event has no time, will return a blank string. 55568 // If not specified, formatStr will default to the eventTimeFormat setting, 55569 // and displayEnd will default to the displayEventEnd setting. 55570 EventRenderer.prototype.getTimeText = function (eventFootprint, formatStr, displayEnd) { 55571 return this._getTimeText(eventFootprint.eventInstance.dateProfile.start, eventFootprint.eventInstance.dateProfile.end, eventFootprint.componentFootprint.isAllDay, formatStr, displayEnd); 55572 }; 55573 EventRenderer.prototype._getTimeText = function (start, end, isAllDay, formatStr, displayEnd) { 55574 if (formatStr == null) { 55575 formatStr = this.eventTimeFormat; 55576 } 55577 if (displayEnd == null) { 55578 displayEnd = this.displayEventEnd; 55579 } 55580 if (this.displayEventTime && !isAllDay) { 55581 if (displayEnd && end) { 55582 return this.view.formatRange({ start: start, end: end }, false, // allDay 55583 formatStr); 55584 } 55585 else { 55586 return start.format(formatStr); 55587 } 55588 } 55589 return ''; 55590 }; 55591 EventRenderer.prototype.computeEventTimeFormat = function () { 55592 return this.opt('smallTimeFormat'); 55593 }; 55594 EventRenderer.prototype.computeDisplayEventTime = function () { 55595 return true; 55596 }; 55597 EventRenderer.prototype.computeDisplayEventEnd = function () { 55598 return true; 55599 }; 55600 EventRenderer.prototype.getBgClasses = function (eventDef) { 55601 var classNames = this.getClasses(eventDef); 55602 classNames.push('fc-bgevent'); 55603 return classNames; 55604 }; 55605 EventRenderer.prototype.getClasses = function (eventDef) {
55606 var objs = this.getStylingObjs(eventDef); 55607 var i; 55608 var classNames = []; 55609 for (i = 0; i < objs.length; i++) { 55610 classNames.push.apply(// append 55611 classNames, objs[i].eventClassName || objs[i].className || []); 55612 } 55613 return classNames; 55614 }; 55615 // Utility for generating event skin-related CSS properties 55616 EventRenderer.prototype.getSkinCss = function (eventDef) { 55617 return { 55618 'background-color': this.getBgColor(eventDef), 55619 'border-color': this.getBorderColor(eventDef), 55620 color: this.getTextColor(eventDef) 55621 }; 55622 }; 55623 // Queries for caller-specified color, then falls back to default 55624 EventRenderer.prototype.getBgColor = function (eventDef) { 55625 var objs = this.getStylingObjs(eventDef); 55626 var i; 55627 var val; 55628 for (i = 0; i < objs.length && !val; i++) { 55629 val = objs[i].eventBackgroundColor || objs[i].eventColor || 55630 objs[i].backgroundColor || objs[i].color; 55631 } 55632 if (!val) { 55633 val = this.opt('eventBackgroundColor') || this.opt('eventColor'); 55634 } 55635 return val; 55636 }; 55637 // Queries for caller-specified color, then falls back to default 55638 EventRenderer.prototype.getBorderColor = function (eventDef) { 55639 var objs = this.getStylingObjs(eventDef); 55640 var i; 55641 var val; 55642 for (i = 0; i < objs.length && !val; i++) { 55643 val = objs[i].eventBorderColor || objs[i].eventColor || 55644 objs[i].borderColor || objs[i].color; 55645 } 55646 if (!val) { 55647 val = this.opt('eventBorderColor') || this.opt('eventColor'); 55648 } 55649 return val; 55650 }; 55651 // Queries for caller-specified color, then falls back to default 55652 EventRenderer.prototype.getTextColor = function (eventDef) { 55653 var objs = this.getStylingObjs(eventDef); 55654 var i; 55655 var val; 55656 for (i = 0; i < objs.length && !val; i++) { 55657 val = objs[i].eventTextColor || 55658 objs[i].textColor; 55659 } 55660 if (!val) { 55661 val = this.opt('eventTextColor'); 55662 } 55663 return val; 55664 }; 55665 EventRenderer.prototype.getStylingObjs = function (eventDef) { 55666 var objs = this.getFallbackStylingObjs(eventDef); 55667 objs.unshift(eventDef); 55668 return objs; 55669 }; 55670 EventRenderer.prototype.getFallbackStylingObjs = function (eventDef) { 55671 return [eventDef.source]; 55672 }; 55673 EventRenderer.prototype.sortEventSegs = function (segs) { 55674 segs.sort(util_1.proxy(this, 'compareEventSegs')); 55675 }; 55676 // A cmp function for determining which segments should take visual priority 55677 EventRenderer.prototype.compareEventSegs = function (seg1, seg2) { 55678 var f1 = seg1.footprint; 55679 var f2 = seg2.footprint; 55680 var cf1 = f1.componentFootprint; 55681 var cf2 = f2.componentFootprint; 55682 var r1 = cf1.unzonedRange; 55683 var r2 = cf2.unzonedRange; 55684 return r1.startMs - r2.startMs || // earlier events go first 55685 (r2.endMs - r2.startMs) - (r1.endMs - r1.startMs) || // tie? longer events go first 55686 cf2.isAllDay - cf1.isAllDay || // tie? put all-day events first (booleans cast to 0/1) 55687 util_1.compareByFieldSpecs(f1.eventDef, f2.eventDef, this.view.eventOrderSpecs, f1.eventDef.miscProps, f2.eventDef.miscProps); 55688 }; 55689 return EventRenderer; 55690}()); 55691exports.default = EventRenderer; 55692 55693 55694/***/ }), 55695/* 43 */, 55696/* 44 */, 55697/* 45 */, 55698/* 46 */, 55699/* 47 */ 55700/***/ (function(module, exports, __webpack_require__) { 55701 55702Object.defineProperty(exports, "__esModule", { value: true }); 55703var moment_ext_1 = __webpack_require__(10); 55704// Plugin 55705// ------------------------------------------------------------------------------------------------- 55706moment_ext_1.newMomentProto.format = function () { 55707 if (this._fullCalendar && arguments[0]) { 55708 return formatDate(this, arguments[0]); // our extended formatting 55709 } 55710 if (this._ambigTime) { 55711 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD'); 55712 } 55713 if (this._ambigZone) { 55714 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss'); 55715 } 55716 if (this._fullCalendar) { 55717 // moment.format() doesn't ensure english, but we want to. 55718 return moment_ext_1.oldMomentFormat(englishMoment(this)); 55719 } 55720 return moment_ext_1.oldMomentProto.format.apply(this, arguments); 55721}; 55722moment_ext_1.newMomentProto.toISOString = function () { 55723 if (this._ambigTime) { 55724 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD'); 55725 } 55726 if (this._ambigZone) { 55727 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss'); 55728 } 55729 if (this._fullCalendar) { 55730 // depending on browser, moment might not output english. ensure english. 55731 // https://github.com/moment/moment/blob/2.18.1/src/lib/moment/format.js#L22 55732 return moment_ext_1.oldMomentProto.toISOString.apply(englishMoment(this), arguments); 55733 } 55734 return moment_ext_1.oldMomentProto.toISOString.apply(this, arguments); 55735}; 55736function englishMoment(mom) { 55737 if (mom.locale() !== 'en') { 55738 return mom.clone().locale('en'); 55739 } 55740 return mom; 55741} 55742// Config 55743// --------------------------------------------------------------------------------------------------------------------- 55744/* 55745Inserted between chunks in the fake ("intermediate") formatting string. 55746Important that it passes as whitespace (\s) because moment often identifies non-standalone months 55747via a regexp with an \s. 55748*/ 55749var PART_SEPARATOR = '\u000b'; // vertical tab 55750/* 55751Inserted as the first character of a literal-text chunk to indicate that the literal text is not actually literal text, 55752but rather, a "special" token that has custom rendering (see specialTokens map). 55753*/ 55754var SPECIAL_TOKEN_MARKER = '\u001f'; // information separator 1 55755/* 55756Inserted at the beginning and end of a span of text that must have non-zero numeric characters. 55757Handling of these markers is done in a post-processing step at the very end of text rendering. 55758*/ 55759var MAYBE_MARKER = '\u001e'; // information separator 2 55760var MAYBE_REGEXP = new RegExp(MAYBE_MARKER + '([^' + MAYBE_MARKER + ']*)' + MAYBE_MARKER, 'g'); // must be global 55761/* 55762Addition formatting tokens we want recognized 55763*/ 55764var specialTokens = { 55765 t: function (date) { 55766 return moment_ext_1.oldMomentFormat(date, 'a').charAt(0);
55767 }, 55768 T: function (date) { 55769 return moment_ext_1.oldMomentFormat(date, 'A').charAt(0); 55770 } 55771}; 55772/* 55773The first characters of formatting tokens for units that are 1 day or larger. 55774`value` is for ranking relative size (lower means bigger). 55775`unit` is a normalized unit, used for comparing moments. 55776*/ 55777var largeTokenMap = { 55778 Y: { value: 1, unit: 'year' }, 55779 M: { value: 2, unit: 'month' }, 55780 W: { value: 3, unit: 'week' }, 55781 w: { value: 3, unit: 'week' }, 55782 D: { value: 4, unit: 'day' }, 55783 d: { value: 4, unit: 'day' } // day of week 55784}; 55785// Single Date Formatting 55786// --------------------------------------------------------------------------------------------------------------------- 55787/* 55788Formats `date` with a Moment formatting string, but allow our non-zero areas and special token 55789*/ 55790function formatDate(date, formatStr) { 55791 return renderFakeFormatString(getParsedFormatString(formatStr).fakeFormatString, date); 55792} 55793exports.formatDate = formatDate; 55794// Date Range Formatting 55795// ------------------------------------------------------------------------------------------------- 55796// TODO: make it work with timezone offset 55797/* 55798Using a formatting string meant for a single date, generate a range string, like 55799"Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ. 55800If the dates are the same as far as the format string is concerned, just return a single 55801rendering of one date, without any separator. 55802*/ 55803function formatRange(date1, date2, formatStr, separator, isRTL) { 55804 var localeData; 55805 date1 = moment_ext_1.default.parseZone(date1); 55806 date2 = moment_ext_1.default.parseZone(date2); 55807 localeData = date1.localeData(); 55808 // Expand localized format strings, like "LL" -> "MMMM D YYYY". 55809 // BTW, this is not important for `formatDate` because it is impossible to put custom tokens 55810 // or non-zero areas in Moment's localized format strings. 55811 formatStr = localeData.longDateFormat(formatStr) || formatStr; 55812 return renderParsedFormat(getParsedFormatString(formatStr), date1, date2, separator || ' - ', isRTL); 55813} 55814exports.formatRange = formatRange; 55815/* 55816Renders a range with an already-parsed format string. 55817*/ 55818function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) { 55819 var sameUnits = parsedFormat.sameUnits; 55820 var unzonedDate1 = date1.clone().stripZone(); // for same-unit comparisons 55821 var unzonedDate2 = date2.clone().stripZone(); // " 55822 var renderedParts1 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date1); 55823 var renderedParts2 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date2); 55824 var leftI; 55825 var leftStr = ''; 55826 var rightI; 55827 var rightStr = ''; 55828 var middleI; 55829 var middleStr1 = ''; 55830 var middleStr2 = ''; 55831 var middleStr = ''; 55832 // Start at the leftmost side of the formatting string and continue until you hit a token 55833 // that is not the same between dates. 55834 for (leftI = 0; leftI < sameUnits.length && (!sameUnits[leftI] || unzonedDate1.isSame(unzonedDate2, sameUnits[leftI])); leftI++) { 55835 leftStr += renderedParts1[leftI]; 55836 } 55837 // Similarly, start at the rightmost side of the formatting string and move left 55838 for (rightI = sameUnits.length - 1; rightI > leftI && (!sameUnits[rightI] || unzonedDate1.isSame(unzonedDate2, sameUnits[rightI])); rightI--) { 55839 // If current chunk is on the boundary of unique date-content, and is a special-case 55840 // date-formatting postfix character, then don't consume it. Consider it unique date-content. 55841 // TODO: make configurable 55842 if (rightI - 1 === leftI && renderedParts1[rightI] === '.') { 55843 break; 55844 } 55845 rightStr = renderedParts1[rightI] + rightStr; 55846 } 55847 // The area in the middle is different for both of the dates. 55848 // Collect them distinctly so we can jam them together later. 55849 for (middleI = leftI; middleI <= rightI; middleI++) { 55850 middleStr1 += renderedParts1[middleI]; 55851 middleStr2 += renderedParts2[middleI]; 55852 } 55853 if (middleStr1 || middleStr2) { 55854 if (isRTL) { 55855 middleStr = middleStr2 + separator + middleStr1;
55856 } 55857 else { 55858 middleStr = middleStr1 + separator + middleStr2; 55859 } 55860 } 55861 return processMaybeMarkers(leftStr + middleStr + rightStr); 55862} 55863// Format String Parsing 55864// --------------------------------------------------------------------------------------------------------------------- 55865var parsedFormatStrCache = {}; 55866/* 55867Returns a parsed format string, leveraging a cache. 55868*/ 55869function getParsedFormatString(formatStr) { 55870 return parsedFormatStrCache[formatStr] || 55871 (parsedFormatStrCache[formatStr] = parseFormatString(formatStr)); 55872} 55873/* 55874Parses a format string into the following: 55875- fakeFormatString: a momentJS formatting string, littered with special control characters that get post-processed. 55876- sameUnits: for every part in fakeFormatString, if the part is a token, the value will be a unit string (like "day"), 55877 that indicates how similar a range's start & end must be in order to share the same formatted text. 55878 If not a token, then the value is null. 55879 Always a flat array (not nested liked "chunks"). 55880*/ 55881function parseFormatString(formatStr) { 55882 var chunks = chunkFormatString(formatStr); 55883 return { 55884 fakeFormatString: buildFakeFormatString(chunks), 55885 sameUnits: buildSameUnits(chunks) 55886 }; 55887} 55888/* 55889Break the formatting string into an array of chunks. 55890A 'maybe' chunk will have nested chunks. 55891*/ 55892function chunkFormatString(formatStr) { 55893 var chunks = []; 55894 var match; 55895 // TODO: more descrimination 55896 // \4 is a backreference to the first character of a multi-character set.
55897 var chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g; 55898 while ((match = chunker.exec(formatStr))) { 55899 if (match[1]) { 55900 chunks.push.apply(chunks, // append 55901 splitStringLiteral(match[1])); 55902 } 55903 else if (match[2]) { 55904 chunks.push({ maybe: chunkFormatString(match[2]) }); 55905 } 55906 else if (match[3]) { 55907 chunks.push({ token: match[3] }); 55908 } 55909 else if (match[5]) { 55910 chunks.push.apply(chunks, // append 55911 splitStringLiteral(match[5])); 55912 } 55913 } 55914 return chunks; 55915} 55916/* 55917Potentially splits a literal-text string into multiple parts. For special cases. 55918*/ 55919function splitStringLiteral(s) { 55920 if (s === '. ') { 55921 return ['.', ' ']; // for locales with periods bound to the end of each year/month/date 55922 } 55923 else { 55924 return [s]; 55925 } 55926} 55927/* 55928Given chunks parsed from a real format string, generate a fake (aka "intermediate") format string with special control 55929characters that will eventually be given to moment for formatting, and then post-processed. 55930*/ 55931function buildFakeFormatString(chunks) { 55932 var parts = []; 55933 var i; 55934 var chunk; 55935 for (i = 0; i < chunks.length; i++) { 55936 chunk = chunks[i]; 55937 if (typeof chunk === 'string') { 55938 parts.push('[' + chunk + ']'); 55939 } 55940 else if (chunk.token) { 55941 if (chunk.token in specialTokens) { 55942 parts.push(SPECIAL_TOKEN_MARKER + // useful during post-processing 55943 '[' + chunk.token + ']' // preserve as literal text 55944 ); 55945 } 55946 else { 55947 parts.push(chunk.token); // unprotected text implies a format string 55948 } 55949 } 55950 else if (chunk.maybe) { 55951 parts.push(MAYBE_MARKER + // useful during post-processing 55952 buildFakeFormatString(chunk.maybe) + 55953 MAYBE_MARKER); 55954 } 55955 } 55956 return parts.join(PART_SEPARATOR); 55957} 55958/* 55959Given parsed chunks from a real formatting string, generates an array of unit strings (like "day") that indicate 55960in which regard two dates must be similar in order to share range formatting text. 55961The `chunks` can be nested (because of "maybe" chunks), however, the returned array will be flat. 55962*/ 55963function buildSameUnits(chunks) { 55964 var units = []; 55965 var i; 55966 var chunk; 55967 var tokenInfo; 55968 for (i = 0; i < chunks.length; i++) { 55969 chunk = chunks[i]; 55970 if (chunk.token) { 55971 tokenInfo = largeTokenMap[chunk.token.charAt(0)]; 55972 units.push(tokenInfo ? tokenInfo.unit : 'second'); // default to a very strict same-second 55973 } 55974 else if (chunk.maybe) { 55975 units.push.apply(units, // append 55976 buildSameUnits(chunk.maybe)); 55977 } 55978 else { 55979 units.push(null); 55980 } 55981 } 55982 return units; 55983} 55984// Rendering to text 55985// --------------------------------------------------------------------------------------------------------------------- 55986/* 55987Formats a date with a fake format string, post-processes the control characters, then returns. 55988*/ 55989function renderFakeFormatString(fakeFormatString, date) { 55990 return processMaybeMarkers(renderFakeFormatStringParts(fakeFormatString, date).join('')); 55991} 55992/* 55993Formats a date into parts that will have been post-processed, EXCEPT for the "maybe" markers. 55994*/ 55995function renderFakeFormatStringParts(fakeFormatString, date) { 55996 var parts = []; 55997 var fakeRender = moment_ext_1.oldMomentFormat(date, fakeFormatString); 55998 var fakeParts = fakeRender.split(PART_SEPARATOR); 55999 var i; 56000 var fakePart; 56001 for (i = 0; i < fakeParts.length; i++) { 56002 fakePart = fakeParts[i]; 56003 if (fakePart.charAt(0) === SPECIAL_TOKEN_MARKER) { 56004 parts.push( 56005 // the literal string IS the token's name. 56006 // call special token's registered function. 56007 specialTokens[fakePart.substring(1)](date)); 56008 } 56009 else { 56010 parts.push(fakePart); 56011 } 56012 } 56013 return parts; 56014} 56015/* 56016Accepts an almost-finally-formatted string and processes the "maybe" control characters, returning a new string. 56017*/ 56018function processMaybeMarkers(s) { 56019 return s.replace(MAYBE_REGEXP, function (m0, m1) { 56020 if (m1.match(/[1-9]/)) { 56021 return m1; 56022 } 56023 else { 56024 return ''; 56025 } 56026 });
56027} 56028// Misc Utils 56029// ------------------------------------------------------------------------------------------------- 56030/* 56031Returns a unit string, either 'year', 'month', 'day', or null for the most granular formatting token in the string. 56032*/ 56033function queryMostGranularFormatUnit(formatStr) { 56034 var chunks = chunkFormatString(formatStr); 56035 var i; 56036 var chunk; 56037 var candidate; 56038 var best; 56039 for (i = 0; i < chunks.length; i++) { 56040 chunk = chunks[i]; 56041 if (chunk.token) { 56042 candidate = largeTokenMap[chunk.token.charAt(0)]; 56043 if (candidate) { 56044 if (!best || candidate.value > best.value) { 56045 best = candidate; 56046 } 56047 } 56048 } 56049 } 56050 if (best) { 56051 return best.unit; 56052 } 56053 return null; 56054} 56055exports.queryMostGranularFormatUnit = queryMostGranularFormatUnit; 56056 56057 56058/***/ }), 56059/* 48 */ 56060/***/ (function(module, exports, __webpack_require__) { 56061 56062Object.defineProperty(exports, "__esModule", { value: true }); 56063var tslib_1 = __webpack_require__(2); 56064var Class_1 = __webpack_require__(33); 56065var EmitterMixin_1 = __webpack_require__(11); 56066var ListenerMixin_1 = __webpack_require__(7); 56067var Model = /** @class */ (function (_super) { 56068 tslib_1.__extends(Model, _super); 56069 function Model() { 56070 var _this = _super.call(this) || this; 56071 _this._watchers = {}; 56072 _this._props = {}; 56073 _this.applyGlobalWatchers(); 56074 _this.constructed(); 56075 return _this; 56076 } 56077 Model.watch = function (name) { 56078 var args = []; 56079 for (var _i = 1; _i < arguments.length; _i++) { 56080 args[_i - 1] = arguments[_i]; 56081 } 56082 // subclasses should make a masked-copy of the superclass's map 56083 // TODO: write test 56084 if (!this.prototype.hasOwnProperty('_globalWatchArgs')) { 56085 this.prototype._globalWatchArgs = Object.create(this.prototype._globalWatchArgs); 56086 } 56087 this.prototype._globalWatchArgs[name] = args; 56088 }; 56089 Model.prototype.constructed = function () { 56090 // useful for monkeypatching. TODO: BaseClass? 56091 }; 56092 Model.prototype.applyGlobalWatchers = function () { 56093 var map = this._globalWatchArgs; 56094 var name; 56095 for (name in map) { 56096 this.watch.apply(this, [name].concat(map[name])); 56097 } 56098 }; 56099 Model.prototype.has = function (name) { 56100 return name in this._props; 56101 }; 56102 Model.prototype.get = function (name) { 56103 if (name === undefined) { 56104 return this._props; 56105 } 56106 return this._props[name]; 56107 }; 56108 Model.prototype.set = function (name, val) { 56109 var newProps; 56110 if (typeof name === 'string') { 56111 newProps = {}; 56112 newProps[name] = val === undefined ? null : val; 56113 } 56114 else { 56115 newProps = name; 56116 } 56117 this.setProps(newProps); 56118 }; 56119 Model.prototype.reset = function (newProps) { 56120 var oldProps = this._props; 56121 var changeset = {}; // will have undefined's to signal unsets 56122 var name; 56123 for (name in oldProps) { 56124 changeset[name] = undefined; 56125 } 56126 for (name in newProps) { 56127 changeset[name] = newProps[name]; 56128 } 56129 this.setProps(changeset); 56130 }; 56131 Model.prototype.unset = function (name) { 56132 var newProps = {}; 56133 var names; 56134 var i; 56135 if (typeof name === 'string') { 56136 names = [name]; 56137 } 56138 else { 56139 names = name; 56140 } 56141 for (i = 0; i < names.length; i++) { 56142 newProps[names[i]] = undefined; 56143 } 56144 this.setProps(newProps); 56145 }; 56146 Model.prototype.setProps = function (newProps) { 56147 var changedProps = {}; 56148 var changedCnt = 0; 56149 var name; 56150 var val; 56151 for (name in newProps) { 56152 val = newProps[name]; 56153 // a change in value? 56154 // if an object, don't check equality, because might have been mutated internally. 56155 // TODO: eventually enforce immutability. 56156 if (typeof val === 'object' || 56157 val !== this._props[name]) { 56158 changedProps[name] = val; 56159 changedCnt++; 56160 } 56161 } 56162 if (changedCnt) { 56163 this.trigger('before:batchChange', changedProps); 56164 for (name in changedProps) { 56165 val = changedProps[name]; 56166 this.trigger('before:change', name, val); 56167 this.trigger('before:change:' + name, val); 56168 } 56169 for (name in changedProps) { 56170 val = changedProps[name]; 56171 if (val === undefined) { 56172 delete this._props[name]; 56173 } 56174 else { 56175 this._props[name] = val; 56176 } 56177 this.trigger('change:' + name, val); 56178 this.trigger('change', name, val); 56179 } 56180 this.trigger('batchChange', changedProps); 56181 } 56182 }; 56183 Model.prototype.watch = function (name, depList, startFunc, stopFunc) { 56184 var _this = this; 56185 this.unwatch(name); 56186 this._watchers[name] = this._watchDeps(depList, function (deps) { 56187 var res = startFunc.call(_this, deps); 56188 if (res && res.then) { 56189 _this.unset(name); // put in an unset state while resolving 56190 res.then(function (val) { 56191 _this.set(name, val); 56192 }); 56193 } 56194 else { 56195 _this.set(name, res); 56196 } 56197 }, function (deps) { 56198 _this.unset(name); 56199 if (stopFunc) { 56200 stopFunc.call(_this, deps); 56201 } 56202 }); 56203 }; 56204 Model.prototype.unwatch = function (name) { 56205 var watcher = this._watchers[name]; 56206 if (watcher) { 56207 delete this._watchers[name]; 56208 watcher.teardown(); 56209 } 56210 }; 56211 Model.prototype._watchDeps = function (depList, startFunc, stopFunc) { 56212 var _this = this; 56213 var queuedChangeCnt = 0; 56214 var depCnt = depList.length; 56215 var satisfyCnt = 0; 56216 var values = {}; // what's passed as the `deps` arguments 56217 var bindTuples = []; // array of [ eventName, handlerFunc ] arrays 56218 var isCallingStop = false; 56219 var onBeforeDepChange = function (depName, val, isOptional) { 56220 queuedChangeCnt++; 56221 if (queuedChangeCnt === 1) { 56222 if (satisfyCnt === depCnt) { 56223 isCallingStop = true; 56224 stopFunc(values); 56225 isCallingStop = false; 56226 } 56227 } 56228 }; 56229 var onDepChange = function (depName, val, isOptional) { 56230 if (val === undefined) { 56231 // required dependency that was previously set? 56232 if (!isOptional && values[depName] !== undefined) { 56233 satisfyCnt--; 56234 } 56235 delete values[depName]; 56236 } 56237 else { 56238 // required dependency that was previously unset? 56239 if (!isOptional && values[depName] === undefined) { 56240 satisfyCnt++; 56241 } 56242 values[depName] = val; 56243 } 56244 queuedChangeCnt--; 56245 if (!queuedChangeCnt) { 56246 // now finally satisfied or satisfied all along? 56247 if (satisfyCnt === depCnt) { 56248 // if the stopFunc initiated another value change, ignore it. 56249 // it will be processed by another change event anyway. 56250 if (!isCallingStop) { 56251 startFunc(values); 56252 } 56253 } 56254 } 56255 }; 56256 // intercept for .on() that remembers handlers 56257 var bind = function (eventName, handler) { 56258 _this.on(eventName, handler); 56259 bindTuples.push([eventName, handler]); 56260 }; 56261 // listen to dependency changes 56262 depList.forEach(function (depName) { 56263 var isOptional = false; 56264 if (depName.charAt(0) === '?') { 56265 depName = depName.substring(1); 56266 isOptional = true; 56267 } 56268 bind('before:change:' + depName, function (val) { 56269 onBeforeDepChange(depName, val, isOptional); 56270 }); 56271 bind('change:' + depName, function (val) { 56272 onDepChange(depName, val, isOptional); 56273 }); 56274 }); 56275 // process current dependency values 56276 depList.forEach(function (depName) { 56277 var isOptional = false; 56278 if (depName.charAt(0) === '?') { 56279 depName = depName.substring(1); 56280 isOptional = true; 56281 } 56282 if (_this.has(depName)) { 56283 values[depName] = _this.get(depName); 56284 satisfyCnt++; 56285 } 56286 else if (isOptional) { 56287 satisfyCnt++; 56288 } 56289 }); 56290 // initially satisfied 56291 if (satisfyCnt === depCnt) { 56292 startFunc(values); 56293 } 56294 return { 56295 teardown: function () { 56296 // remove all handlers 56297 for (var i = 0; i < bindTuples.length; i++) { 56298 _this.off(bindTuples[i][0], bindTuples[i][1]); 56299 } 56300 bindTuples = null; 56301 // was satisfied, so call stopFunc 56302 if (satisfyCnt === depCnt) { 56303 stopFunc(); 56304 } 56305 }, 56306 flash: function () { 56307 if (satisfyCnt === depCnt) { 56308 stopFunc(); 56309 startFunc(values); 56310 } 56311 } 56312 }; 56313 }; 56314 Model.prototype.flash = function (name) { 56315 var watcher = this._watchers[name]; 56316 if (watcher) { 56317 watcher.flash(); 56318 } 56319 }; 56320 return Model; 56321}(Class_1.default)); 56322exports.default = Model; 56323Model.prototype._globalWatchArgs = {}; // mutation protection in Model.watch 56324EmitterMixin_1.default.mixInto(Model); 56325ListenerMixin_1.default.mixInto(Model); 56326 56327 56328/***/ }), 56329/* 49 */ 56330/***/ (function(module, exports, __webpack_require__) { 56331 56332Object.defineProperty(exports, "__esModule", { value: true });
56333var moment = __webpack_require__(0); 56334var util_1 = __webpack_require__(4); 56335var SingleEventDef_1 = __webpack_require__(13); 56336var RecurringEventDef_1 = __webpack_require__(210); 56337exports.default = { 56338 parse: function (eventInput, source) { 56339 if (util_1.isTimeString(eventInput.start) || moment.isDuration(eventInput.start) || 56340 util_1.isTimeString(eventInput.end) || moment.isDuration(eventInput.end)) { 56341 return RecurringEventDef_1.default.parse(eventInput, source); 56342 } 56343 else { 56344 return SingleEventDef_1.default.parse(eventInput, source); 56345 } 56346 } 56347}; 56348 56349 56350/***/ }), 56351/* 50 */ 56352/***/ (function(module, exports, __webpack_require__) { 56353 56354Object.defineProperty(exports, "__esModule", { value: true }); 56355var util_1 = __webpack_require__(4); 56356var EventDateProfile_1 = __webpack_require__(17); 56357var EventDefDateMutation = /** @class */ (function () { 56358 function EventDefDateMutation() { 56359 this.clearEnd = false; 56360 this.forceTimed = false; 56361 this.forceAllDay = false; 56362 } 56363 EventDefDateMutation.createFromDiff = function (dateProfile0, dateProfile1, largeUnit) { 56364 var clearEnd = dateProfile0.end && !dateProfile1.end; 56365 var forceTimed = dateProfile0.isAllDay() && !dateProfile1.isAllDay(); 56366 var forceAllDay = !dateProfile0.isAllDay() && dateProfile1.isAllDay(); 56367 var dateDelta; 56368 var endDiff; 56369 var endDelta; 56370 var mutation; 56371 // subtracts the dates in the appropriate way, returning a duration 56372 function subtractDates(date1, date0) { 56373 if (largeUnit) { 56374 return util_1.diffByUnit(date1, date0, largeUnit); // poorly named 56375 } 56376 else if (dateProfile1.isAllDay()) { 56377 return util_1.diffDay(date1, date0); // poorly named 56378 } 56379 else { 56380 return util_1.diffDayTime(date1, date0); // poorly named 56381 } 56382 } 56383 dateDelta = subtractDates(dateProfile1.start, dateProfile0.start); 56384 if (dateProfile1.end) { 56385 // use unzonedRanges because dateProfile0.end might be null 56386 endDiff = subtractDates(dateProfile1.unzonedRange.getEnd(), dateProfile0.unzonedRange.getEnd()); 56387 endDelta = endDiff.subtract(dateDelta); 56388 } 56389 mutation = new EventDefDateMutation(); 56390 mutation.clearEnd = clearEnd; 56391 mutation.forceTimed = forceTimed; 56392 mutation.forceAllDay = forceAllDay; 56393 mutation.setDateDelta(dateDelta); 56394 mutation.setEndDelta(endDelta); 56395 return mutation; 56396 }; 56397 /* 56398 returns an undo function. 56399 */ 56400 EventDefDateMutation.prototype.buildNewDateProfile = function (eventDateProfile, calendar) { 56401 var start = eventDateProfile.start.clone(); 56402 var end = null; 56403 var shouldRezone = false; 56404 if (eventDateProfile.end && !this.clearEnd) { 56405 end = eventDateProfile.end.clone(); 56406 } 56407 else if (this.endDelta && !end) { 56408 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start); 56409 } 56410 if (this.forceTimed) { 56411 shouldRezone = true; 56412 if (!start.hasTime()) { 56413 start.time(0); 56414 } 56415 if (end && !end.hasTime()) { 56416 end.time(0); 56417 } 56418 } 56419 else if (this.forceAllDay) { 56420 if (start.hasTime()) { 56421 start.stripTime(); 56422 } 56423 if (end && end.hasTime()) { 56424 end.stripTime(); 56425 } 56426 } 56427 if (this.dateDelta) { 56428 shouldRezone = true; 56429 start.add(this.dateDelta); 56430 if (end) { 56431 end.add(this.dateDelta); 56432 } 56433 } 56434 // do this before adding startDelta to start, so we can work off of start 56435 if (this.endDelta) { 56436 shouldRezone = true; 56437 end.add(this.endDelta); 56438 } 56439 if (this.startDelta) { 56440 shouldRezone = true; 56441 start.add(this.startDelta); 56442 } 56443 if (shouldRezone) { 56444 start = calendar.applyTimezone(start); 56445 if (end) { 56446 end = calendar.applyTimezone(end); 56447 } 56448 } 56449 // TODO: okay to access calendar option?
56450 if (!end && calendar.opt('forceEventDuration')) { 56451 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start); 56452 } 56453 return new EventDateProfile_1.default(start, end, calendar); 56454 }; 56455 EventDefDateMutation.prototype.setDateDelta = function (dateDelta) { 56456 if (dateDelta && dateDelta.valueOf()) { 56457 this.dateDelta = dateDelta; 56458 } 56459 else { 56460 this.dateDelta = null; 56461 } 56462 }; 56463 EventDefDateMutation.prototype.setStartDelta = function (startDelta) { 56464 if (startDelta && startDelta.valueOf()) { 56465 this.startDelta = startDelta; 56466 } 56467 else { 56468 this.startDelta = null; 56469 } 56470 }; 56471 EventDefDateMutation.prototype.setEndDelta = function (endDelta) { 56472 if (endDelta && endDelta.valueOf()) { 56473 this.endDelta = endDelta; 56474 } 56475 else { 56476 this.endDelta = null; 56477 } 56478 }; 56479 EventDefDateMutation.prototype.isEmpty = function () { 56480 return !this.clearEnd && !this.forceTimed && !this.forceAllDay && 56481 !this.dateDelta && !this.startDelta && !this.endDelta; 56482 }; 56483 return EventDefDateMutation; 56484}()); 56485exports.default = EventDefDateMutation; 56486 56487 56488/***/ }), 56489/* 51 */ 56490/***/ (function(module, exports, __webpack_require__) { 56491 56492Object.defineProperty(exports, "__esModule", { value: true }); 56493var StandardTheme_1 = __webpack_require__(213); 56494var JqueryUiTheme_1 = __webpack_require__(214); 56495var themeClassHash = {}; 56496function defineThemeSystem(themeName, themeClass) { 56497 themeClassHash[themeName] = themeClass; 56498} 56499exports.defineThemeSystem = defineThemeSystem; 56500function getThemeSystemClass(themeSetting) { 56501 if (!themeSetting) { 56502 return StandardTheme_1.default; 56503 } 56504 else if (themeSetting === true) { 56505 return JqueryUiTheme_1.default; 56506 } 56507 else { 56508 return themeClassHash[themeSetting]; 56509 } 56510} 56511exports.getThemeSystemClass = getThemeSystemClass; 56512 56513 56514/***/ }), 56515/* 52 */ 56516/***/ (function(module, exports, __webpack_require__) { 56517 56518Object.defineProperty(exports, "__esModule", { value: true }); 56519var tslib_1 = __webpack_require__(2); 56520var $ = __webpack_require__(3); 56521var util_1 = __webpack_require__(4); 56522var Promise_1 = __webpack_require__(20); 56523var EventSource_1 = __webpack_require__(6); 56524var SingleEventDef_1 = __webpack_require__(13); 56525var ArrayEventSource = /** @class */ (function (_super) { 56526 tslib_1.__extends(ArrayEventSource, _super); 56527 function ArrayEventSource(calendar) { 56528 var _this = _super.call(this, calendar) || this; 56529 _this.eventDefs = []; // for if setRawEventDefs is never called 56530 return _this; 56531 } 56532 ArrayEventSource.parse = function (rawInput, calendar) { 56533 var rawProps; 56534 // normalize raw input 56535 if ($.isArray(rawInput.events)) { 56536 rawProps = rawInput; 56537 } 56538 else if ($.isArray(rawInput)) { 56539 rawProps = { events: rawInput }; 56540 } 56541 if (rawProps) { 56542 return EventSource_1.default.parse.call(this, rawProps, calendar); 56543 } 56544 return false; 56545 }; 56546 ArrayEventSource.prototype.setRawEventDefs = function (rawEventDefs) { 56547 this.rawEventDefs = rawEventDefs; 56548 this.eventDefs = this.parseEventDefs(rawEventDefs); 56549 }; 56550 ArrayEventSource.prototype.fetch = function (start, end, timezone) { 56551 var eventDefs = this.eventDefs; 56552 var i; 56553 if (this.currentTimezone != null && 56554 this.currentTimezone !== timezone) { 56555 for (i = 0; i < eventDefs.length; i++) { 56556 if (eventDefs[i] instanceof SingleEventDef_1.default) { 56557 eventDefs[i].rezone(); 56558 } 56559 } 56560 } 56561 this.currentTimezone = timezone; 56562 return Promise_1.default.resolve(eventDefs); 56563 }; 56564 ArrayEventSource.prototype.addEventDef = function (eventDef) { 56565 this.eventDefs.push(eventDef); 56566 }; 56567 /* 56568 eventDefId already normalized to a string 56569 */ 56570 ArrayEventSource.prototype.removeEventDefsById = function (eventDefId) { 56571 return util_1.removeMatching(this.eventDefs, function (eventDef) { 56572 return eventDef.id === eventDefId; 56573 }); 56574 }; 56575 ArrayEventSource.prototype.removeAllEventDefs = function () { 56576 this.eventDefs = []; 56577 }; 56578 ArrayEventSource.prototype.getPrimitive = function () { 56579 return this.rawEventDefs; 56580 };
56581 ArrayEventSource.prototype.applyManualStandardProps = function (rawProps) { 56582 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); 56583 this.setRawEventDefs(rawProps.events); 56584 return superSuccess; 56585 }; 56586 return ArrayEventSource; 56587}(EventSource_1.default)); 56588exports.default = ArrayEventSource; 56589ArrayEventSource.defineStandardProps({ 56590 events: false // don't automatically transfer 56591}); 56592 56593 56594/***/ }), 56595/* 53 */ 56596/***/ (function(module, exports, __webpack_require__) { 56597 56598Object.defineProperty(exports, "__esModule", { value: true }); 56599var $ = __webpack_require__(3); 56600var util_1 = __webpack_require__(4); 56601/* 56602A cache for the left/right/top/bottom/width/height values for one or more elements. 56603Works with both offset (from topleft document) and position (from offsetParent). 56604 56605options: 56606- els 56607- isHorizontal 56608- isVertical 56609*/ 56610var CoordCache = /** @class */ (function () { 56611 function CoordCache(options) { 56612 this.isHorizontal = false; // whether to query for left/right/width 56613 this.isVertical = false; // whether to query for top/bottom/height 56614 this.els = $(options.els); 56615 this.isHorizontal = options.isHorizontal; 56616 this.isVertical = options.isVertical; 56617 this.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null; 56618 } 56619 // Queries the els for coordinates and stores them. 56620 // Call this method before using and of the get* methods below. 56621 CoordCache.prototype.build = function () { 56622 var offsetParentEl = this.forcedOffsetParentEl; 56623 if (!offsetParentEl && this.els.length > 0) { 56624 offsetParentEl = this.els.eq(0).offsetParent(); 56625 } 56626 this.origin = offsetParentEl ? 56627 offsetParentEl.offset() : 56628 null;
56629 this.boundingRect = this.queryBoundingRect(); 56630 if (this.isHorizontal) { 56631 this.buildElHorizontals(); 56632 } 56633 if (this.isVertical) { 56634 this.buildElVerticals(); 56635 } 56636 }; 56637 // Destroys all internal data about coordinates, freeing memory 56638 CoordCache.prototype.clear = function () { 56639 this.origin = null; 56640 this.boundingRect = null; 56641 this.lefts = null; 56642 this.rights = null; 56643 this.tops = null; 56644 this.bottoms = null; 56645 }; 56646 // When called, if coord caches aren't built, builds them 56647 CoordCache.prototype.ensureBuilt = function () { 56648 if (!this.origin) { 56649 this.build(); 56650 } 56651 }; 56652 // Populates the left/right internal coordinate arrays 56653 CoordCache.prototype.buildElHorizontals = function () { 56654 var lefts = []; 56655 var rights = []; 56656 this.els.each(function (i, node) { 56657 var el = $(node); 56658 var left = el.offset().left; 56659 var width = el.outerWidth(); 56660 lefts.push(left); 56661 rights.push(left + width); 56662 }); 56663 this.lefts = lefts; 56664 this.rights = rights; 56665 }; 56666 // Populates the top/bottom internal coordinate arrays 56667 CoordCache.prototype.buildElVerticals = function () { 56668 var tops = []; 56669 var bottoms = []; 56670 this.els.each(function (i, node) { 56671 var el = $(node); 56672 var top = el.offset().top; 56673 var height = el.outerHeight(); 56674 tops.push(top); 56675 bottoms.push(top + height); 56676 }); 56677 this.tops = tops; 56678 this.bottoms = bottoms; 56679 }; 56680 // Given a left offset (from document left), returns the index of the el that it horizontally intersects. 56681 // If no intersection is made, returns undefined. 56682 CoordCache.prototype.getHorizontalIndex = function (leftOffset) { 56683 this.ensureBuilt(); 56684 var lefts = this.lefts; 56685 var rights = this.rights; 56686 var len = lefts.length; 56687 var i; 56688 for (i = 0; i < len; i++) { 56689 if (leftOffset >= lefts[i] && leftOffset < rights[i]) { 56690 return i; 56691 } 56692 } 56693 }; 56694 // Given a top offset (from document top), returns the index of the el that it vertically intersects. 56695 // If no intersection is made, returns undefined. 56696 CoordCache.prototype.getVerticalIndex = function (topOffset) { 56697 this.ensureBuilt(); 56698 var tops = this.tops; 56699 var bottoms = this.bottoms; 56700 var len = tops.length; 56701 var i; 56702 for (i = 0; i < len; i++) { 56703 if (topOffset >= tops[i] && topOffset < bottoms[i]) { 56704 return i; 56705 } 56706 } 56707 }; 56708 // Gets the left offset (from document left) of the element at the given index 56709 CoordCache.prototype.getLeftOffset = function (leftIndex) { 56710 this.ensureBuilt(); 56711 return this.lefts[leftIndex]; 56712 }; 56713 // Gets the left position (from offsetParent left) of the element at the given index 56714 CoordCache.prototype.getLeftPosition = function (leftIndex) { 56715 this.ensureBuilt(); 56716 return this.lefts[leftIndex] - this.origin.left; 56717 }; 56718 // Gets the right offset (from document left) of the element at the given index. 56719 // This value is NOT relative to the document's right edge, like the CSS concept of "right" would be. 56720 CoordCache.prototype.getRightOffset = function (leftIndex) { 56721 this.ensureBuilt(); 56722 return this.rights[leftIndex]; 56723 }; 56724 // Gets the right position (from offsetParent left) of the element at the given index. 56725 // This value is NOT relative to the offsetParent's right edge, like the CSS concept of "right" would be. 56726 CoordCache.prototype.getRightPosition = function (leftIndex) { 56727 this.ensureBuilt(); 56728 return this.rights[leftIndex] - this.origin.left; 56729 }; 56730 // Gets the width of the element at the given index 56731 CoordCache.prototype.getWidth = function (leftIndex) { 56732 this.ensureBuilt(); 56733 return this.rights[leftIndex] - this.lefts[leftIndex]; 56734 }; 56735 // Gets the top offset (from document top) of the element at the given index 56736 CoordCache.prototype.getTopOffset = function (topIndex) { 56737 this.ensureBuilt(); 56738 return this.tops[topIndex]; 56739 }; 56740 // Gets the top position (from offsetParent top) of the element at the given position 56741 CoordCache.prototype.getTopPosition = function (topIndex) { 56742 this.ensureBuilt(); 56743 return this.tops[topIndex] - this.origin.top; 56744 }; 56745 // Gets the bottom offset (from the document top) of the element at the given index. 56746 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be. 56747 CoordCache.prototype.getBottomOffset = function (topIndex) { 56748 this.ensureBuilt(); 56749 return this.bottoms[topIndex]; 56750 }; 56751 // Gets the bottom position (from the offsetParent top) of the element at the given index. 56752 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be. 56753 CoordCache.prototype.getBottomPosition = function (topIndex) { 56754 this.ensureBuilt(); 56755 return this.bottoms[topIndex] - this.origin.top; 56756 }; 56757 // Gets the height of the element at the given index 56758 CoordCache.prototype.getHeight = function (topIndex) { 56759 this.ensureBuilt(); 56760 return this.bottoms[topIndex] - this.tops[topIndex]; 56761 }; 56762 // Bounding Rect 56763 // TODO: decouple this from CoordCache 56764 // Compute and return what the elements' bounding rectangle is, from the user's perspective. 56765 // Right now, only returns a rectangle if constrained by an overflow:scroll element. 56766 // Returns null if there are no elements 56767 CoordCache.prototype.queryBoundingRect = function () { 56768 var scrollParentEl; 56769 if (this.els.length > 0) { 56770 scrollParentEl = util_1.getScrollParent(this.els.eq(0)); 56771 if (!scrollParentEl.is(document)) { 56772 return util_1.getClientRect(scrollParentEl); 56773 } 56774 } 56775 return null; 56776 }; 56777 CoordCache.prototype.isPointInBounds = function (leftOffset, topOffset) { 56778 return this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset); 56779 }; 56780 CoordCache.prototype.isLeftInBounds = function (leftOffset) { 56781 return !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right); 56782 }; 56783 CoordCache.prototype.isTopInBounds = function (topOffset) { 56784 return !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom); 56785 }; 56786 return CoordCache; 56787}()); 56788exports.default = CoordCache; 56789 56790 56791/***/ }), 56792/* 54 */ 56793/***/ (function(module, exports, __webpack_require__) { 56794 56795Object.defineProperty(exports, "__esModule", { value: true });
56796var $ = __webpack_require__(3); 56797var util_1 = __webpack_require__(4); 56798var ListenerMixin_1 = __webpack_require__(7); 56799var GlobalEmitter_1 = __webpack_require__(21); 56800/* Tracks a drag's mouse movement, firing various handlers 56801----------------------------------------------------------------------------------------------------------------------*/ 56802// TODO: use Emitter 56803var DragListener = /** @class */ (function () { 56804 function DragListener(options) { 56805 this.isInteracting = false; 56806 this.isDistanceSurpassed = false; 56807 this.isDelayEnded = false; 56808 this.isDragging = false; 56809 this.isTouch = false; 56810 this.isGeneric = false; // initiated by 'dragstart' (jqui) 56811 this.shouldCancelTouchScroll = true; 56812 this.scrollAlwaysKills = false; 56813 this.isAutoScroll = false; 56814 // defaults 56815 this.scrollSensitivity = 30; // pixels from edge for scrolling to start 56816 this.scrollSpeed = 200; // pixels per second, at maximum speed 56817 this.scrollIntervalMs = 50; // millisecond wait between scroll increment 56818 this.options = options || {}; 56819 } 56820 // Interaction (high-level) 56821 // ----------------------------------------------------------------------------------------------------------------- 56822 DragListener.prototype.startInteraction = function (ev, extraOptions) { 56823 if (extraOptions === void 0) { extraOptions = {}; } 56824 if (ev.type === 'mousedown') { 56825 if (GlobalEmitter_1.default.get().shouldIgnoreMouse()) { 56826 return; 56827 } 56828 else if (!util_1.isPrimaryMouseButton(ev)) { 56829 return; 56830 } 56831 else { 56832 ev.preventDefault(); // prevents native selection in most browsers 56833 } 56834 } 56835 if (!this.isInteracting) { 56836 // process options 56837 this.delay = util_1.firstDefined(extraOptions.delay, this.options.delay, 0); 56838 this.minDistance = util_1.firstDefined(extraOptions.distance, this.options.distance, 0); 56839 this.subjectEl = this.options.subjectEl; 56840 util_1.preventSelection($('body')); 56841 this.isInteracting = true; 56842 this.isTouch = util_1.getEvIsTouch(ev); 56843 this.isGeneric = ev.type === 'dragstart'; 56844 this.isDelayEnded = false; 56845 this.isDistanceSurpassed = false; 56846 this.originX = util_1.getEvX(ev); 56847 this.originY = util_1.getEvY(ev); 56848 this.scrollEl = util_1.getScrollParent($(ev.target)); 56849 this.bindHandlers(); 56850 this.initAutoScroll(); 56851 this.handleInteractionStart(ev); 56852 this.startDelay(ev); 56853 if (!this.minDistance) { 56854 this.handleDistanceSurpassed(ev); 56855 } 56856 } 56857 }; 56858 DragListener.prototype.handleInteractionStart = function (ev) { 56859 this.trigger('interactionStart', ev); 56860 }; 56861 DragListener.prototype.endInteraction = function (ev, isCancelled) { 56862 if (this.isInteracting) { 56863 this.endDrag(ev); 56864 if (this.delayTimeoutId) { 56865 clearTimeout(this.delayTimeoutId); 56866 this.delayTimeoutId = null; 56867 } 56868 this.destroyAutoScroll(); 56869 this.unbindHandlers(); 56870 this.isInteracting = false; 56871 this.handleInteractionEnd(ev, isCancelled); 56872 util_1.allowSelection($('body')); 56873 } 56874 }; 56875 DragListener.prototype.handleInteractionEnd = function (ev, isCancelled) { 56876 this.trigger('interactionEnd', ev, isCancelled || false); 56877 }; 56878 // Binding To DOM 56879 // ----------------------------------------------------------------------------------------------------------------- 56880 DragListener.prototype.bindHandlers = function () { 56881 // some browsers (Safari in iOS 10) don't allow preventDefault on touch events that are bound after touchstart, 56882 // so listen to the GlobalEmitter singleton, which is always bound, instead of the document directly. 56883 var globalEmitter = GlobalEmitter_1.default.get(); 56884 if (this.isGeneric) { 56885 this.listenTo($(document), { 56886 drag: this.handleMove, 56887 dragstop: this.endInteraction 56888 }); 56889 } 56890 else if (this.isTouch) { 56891 this.listenTo(globalEmitter, { 56892 touchmove: this.handleTouchMove, 56893 touchend: this.endInteraction, 56894 scroll: this.handleTouchScroll 56895 }); 56896 } 56897 else { 56898 this.listenTo(globalEmitter, { 56899 mousemove: this.handleMouseMove, 56900 mouseup: this.endInteraction 56901 }); 56902 } 56903 this.listenTo(globalEmitter, { 56904 selectstart: util_1.preventDefault, 56905 contextmenu: util_1.preventDefault // long taps would open menu on Chrome dev tools 56906 }); 56907 }; 56908 DragListener.prototype.unbindHandlers = function () { 56909 this.stopListeningTo(GlobalEmitter_1.default.get()); 56910 this.stopListeningTo($(document)); // for isGeneric 56911 }; 56912 // Drag (high-level) 56913 // ----------------------------------------------------------------------------------------------------------------- 56914 // extraOptions ignored if drag already started 56915 DragListener.prototype.startDrag = function (ev, extraOptions) { 56916 this.startInteraction(ev, extraOptions); // ensure interaction began 56917 if (!this.isDragging) { 56918 this.isDragging = true; 56919 this.handleDragStart(ev); 56920 } 56921 }; 56922 DragListener.prototype.handleDragStart = function (ev) { 56923 this.trigger('dragStart', ev); 56924 }; 56925 DragListener.prototype.handleMove = function (ev) { 56926 var dx = util_1.getEvX(ev) - this.originX; 56927 var dy = util_1.getEvY(ev) - this.originY; 56928 var minDistance = this.minDistance; 56929 var distanceSq; // current distance from the origin, squared 56930 if (!this.isDistanceSurpassed) { 56931 distanceSq = dx * dx + dy * dy; 56932 if (distanceSq >= minDistance * minDistance) { 56933 this.handleDistanceSurpassed(ev); 56934 } 56935 } 56936 if (this.isDragging) { 56937 this.handleDrag(dx, dy, ev); 56938 } 56939 }; 56940 // Called while the mouse is being moved and when we know a legitimate drag is taking place 56941 DragListener.prototype.handleDrag = function (dx, dy, ev) { 56942 this.trigger('drag', dx, dy, ev); 56943 this.updateAutoScroll(ev); // will possibly cause scrolling 56944 }; 56945 DragListener.prototype.endDrag = function (ev) { 56946 if (this.isDragging) { 56947 this.isDragging = false; 56948 this.handleDragEnd(ev); 56949 } 56950 }; 56951 DragListener.prototype.handleDragEnd = function (ev) { 56952 this.trigger('dragEnd', ev); 56953 }; 56954 // Delay 56955 // ----------------------------------------------------------------------------------------------------------------- 56956 DragListener.prototype.startDelay = function (initialEv) { 56957 var _this = this; 56958 if (this.delay) { 56959 this.delayTimeoutId = setTimeout(function () { 56960 _this.handleDelayEnd(initialEv); 56961 }, this.delay); 56962 } 56963 else { 56964 this.handleDelayEnd(initialEv); 56965 } 56966 }; 56967 DragListener.prototype.handleDelayEnd = function (initialEv) { 56968 this.isDelayEnded = true; 56969 if (this.isDistanceSurpassed) { 56970 this.startDrag(initialEv); 56971 } 56972 }; 56973 // Distance 56974 // ----------------------------------------------------------------------------------------------------------------- 56975 DragListener.prototype.handleDistanceSurpassed = function (ev) { 56976 this.isDistanceSurpassed = true; 56977 if (this.isDelayEnded) { 56978 this.startDrag(ev); 56979 } 56980 }; 56981 // Mouse / Touch 56982 // ----------------------------------------------------------------------------------------------------------------- 56983 DragListener.prototype.handleTouchMove = function (ev) { 56984 // prevent inertia and touchmove-scrolling while dragging 56985 if (this.isDragging && this.shouldCancelTouchScroll) { 56986 ev.preventDefault(); 56987 } 56988 this.handleMove(ev); 56989 }; 56990 DragListener.prototype.handleMouseMove = function (ev) { 56991 this.handleMove(ev); 56992 }; 56993 // Scrolling (unrelated to auto-scroll) 56994 // ----------------------------------------------------------------------------------------------------------------- 56995 DragListener.prototype.handleTouchScroll = function (ev) { 56996 // if the drag is being initiated by touch, but a scroll happens before 56997 // the drag-initiating delay is over, cancel the drag 56998 if (!this.isDragging || this.scrollAlwaysKills) { 56999 this.endInteraction(ev, true); // isCancelled=true 57000 } 57001 }; 57002 // Utils 57003 // ----------------------------------------------------------------------------------------------------------------- 57004 // Triggers a callback. Calls a function in the option hash of the same name. 57005 // Arguments beyond the first `name` are forwarded on. 57006 DragListener.prototype.trigger = function (name) { 57007 var args = []; 57008 for (var _i = 1; _i < arguments.length; _i++) { 57009 args[_i - 1] = arguments[_i]; 57010 } 57011 if (this.options[name]) { 57012 this.options[name].apply(this, args); 57013 } 57014 // makes _methods callable by event name. TODO: kill this 57015 if (this['_' + name]) { 57016 this['_' + name].apply(this, args); 57017 } 57018 }; 57019 // Auto-scroll 57020 // ----------------------------------------------------------------------------------------------------------------- 57021 DragListener.prototype.initAutoScroll = function () { 57022 var scrollEl = this.scrollEl; 57023 this.isAutoScroll = 57024 this.options.scroll && 57025 scrollEl && 57026 !scrollEl.is(window) && 57027 !scrollEl.is(document); 57028 if (this.isAutoScroll) { 57029 // debounce makes sure rapid calls don't happen 57030 this.listenTo(scrollEl, 'scroll', util_1.debounce(this.handleDebouncedScroll, 100)); 57031 } 57032 }; 57033 DragListener.prototype.destroyAutoScroll = function () { 57034 this.endAutoScroll(); // kill any animation loop 57035 // remove the scroll handler if there is a scrollEl 57036 if (this.isAutoScroll) { 57037 this.stopListeningTo(this.scrollEl, 'scroll'); // will probably get removed by unbindHandlers too :( 57038 } 57039 }; 57040 // Computes and stores the bounding rectangle of scrollEl 57041 DragListener.prototype.computeScrollBounds = function () { 57042 if (this.isAutoScroll) { 57043 this.scrollBounds = util_1.getOuterRect(this.scrollEl); 57044 // TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars 57045 } 57046 }; 57047 // Called when the dragging is in progress and scrolling should be updated 57048 DragListener.prototype.updateAutoScroll = function (ev) { 57049 var sensitivity = this.scrollSensitivity; 57050 var bounds = this.scrollBounds; 57051 var topCloseness; 57052 var bottomCloseness; 57053 var leftCloseness; 57054 var rightCloseness; 57055 var topVel = 0; 57056 var leftVel = 0; 57057 if (bounds) {
57058 // compute closeness to edges. valid range is from 0.0 - 1.0 57059 topCloseness = (sensitivity - (util_1.getEvY(ev) - bounds.top)) / sensitivity; 57060 bottomCloseness = (sensitivity - (bounds.bottom - util_1.getEvY(ev))) / sensitivity; 57061 leftCloseness = (sensitivity - (util_1.getEvX(ev) - bounds.left)) / sensitivity; 57062 rightCloseness = (sensitivity - (bounds.right - util_1.getEvX(ev))) / sensitivity; 57063 // translate vertical closeness into velocity. 57064 // mouse must be completely in bounds for velocity to happen. 57065 if (topCloseness >= 0 && topCloseness <= 1) { 57066 topVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up 57067 } 57068 else if (bottomCloseness >= 0 && bottomCloseness <= 1) { 57069 topVel = bottomCloseness * this.scrollSpeed; 57070 } 57071 // translate horizontal closeness into velocity 57072 if (leftCloseness >= 0 && leftCloseness <= 1) { 57073 leftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left 57074 } 57075 else if (rightCloseness >= 0 && rightCloseness <= 1) { 57076 leftVel = rightCloseness * this.scrollSpeed; 57077 } 57078 } 57079 this.setScrollVel(topVel, leftVel); 57080 }; 57081 // Sets the speed-of-scrolling for the scrollEl 57082 DragListener.prototype.setScrollVel = function (topVel, leftVel) { 57083 this.scrollTopVel = topVel; 57084 this.scrollLeftVel = leftVel; 57085 this.constrainScrollVel(); // massages into realistic values 57086 // if there is non-zero velocity, and an animation loop hasn't already started, then START 57087 if ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) { 57088 this.scrollIntervalId = setInterval(util_1.proxy(this, 'scrollIntervalFunc'), // scope to `this` 57089 this.scrollIntervalMs); 57090 } 57091 }; 57092 // Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way 57093 DragListener.prototype.constrainScrollVel = function () { 57094 var el = this.scrollEl; 57095 if (this.scrollTopVel < 0) { 57096 if (el.scrollTop() <= 0) { 57097 this.scrollTopVel = 0; 57098 } 57099 } 57100 else if (this.scrollTopVel > 0) { 57101 if (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { 57102 this.scrollTopVel = 0; 57103 } 57104 } 57105 if (this.scrollLeftVel < 0) { 57106 if (el.scrollLeft() <= 0) { 57107 this.scrollLeftVel = 0; 57108 } 57109 } 57110 else if (this.scrollLeftVel > 0) { 57111 if (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { 57112 this.scrollLeftVel = 0; 57113 } 57114 } 57115 }; 57116 // This function gets called during every iteration of the scrolling animation loop 57117 DragListener.prototype.scrollIntervalFunc = function () { 57118 var el = this.scrollEl; 57119 var frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by 57120 // change the value of scrollEl's scroll 57121 if (this.scrollTopVel) { 57122 el.scrollTop(el.scrollTop() + this.scrollTopVel * frac); 57123 } 57124 if (this.scrollLeftVel) { 57125 el.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac); 57126 } 57127 this.constrainScrollVel(); // since the scroll values changed, recompute the velocities 57128 // if scrolled all the way, which causes the vels to be zero, stop the animation loop 57129 if (!this.scrollTopVel && !this.scrollLeftVel) { 57130 this.endAutoScroll(); 57131 } 57132 }; 57133 // Kills any existing scrolling animation loop 57134 DragListener.prototype.endAutoScroll = function () { 57135 if (this.scrollIntervalId) { 57136 clearInterval(this.scrollIntervalId); 57137 this.scrollIntervalId = null; 57138 this.handleScrollEnd(); 57139 } 57140 }; 57141 // Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce) 57142 DragListener.prototype.handleDebouncedScroll = function () {
57143 // recompute all coordinates, but *only* if this is *not* part of our scrolling animation 57144 if (!this.scrollIntervalId) { 57145 this.handleScrollEnd(); 57146 } 57147 }; 57148 DragListener.prototype.handleScrollEnd = function () { 57149 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling 57150 }; 57151 return DragListener; 57152}()); 57153exports.default = DragListener; 57154ListenerMixin_1.default.mixInto(DragListener); 57155 57156 57157/***/ }), 57158/* 55 */ 57159/***/ (function(module, exports, __webpack_require__) { 57160 57161Object.defineProperty(exports, "__esModule", { value: true }); 57162var tslib_1 = __webpack_require__(2); 57163var util_1 = __webpack_require__(4); 57164var Mixin_1 = __webpack_require__(14); 57165/* 57166A set of rendering and date-related methods for a visual component comprised of one or more rows of day columns. 57167Prerequisite: the object being mixed into needs to be a *Grid* 57168*/ 57169var DayTableMixin = /** @class */ (function (_super) { 57170 tslib_1.__extends(DayTableMixin, _super); 57171 function DayTableMixin() { 57172 return _super !== null && _super.apply(this, arguments) || this; 57173 } 57174 // Populates internal variables used for date calculation and rendering 57175 DayTableMixin.prototype.updateDayTable = function () { 57176 var t = this; 57177 var view = t.view; 57178 var calendar = view.calendar; 57179 var date = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.startMs, true); 57180 var end = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.endMs, true); 57181 var dayIndex = -1; 57182 var dayIndices = []; 57183 var dayDates = []; 57184 var daysPerRow; 57185 var firstDay; 57186 var rowCnt; 57187 while (date.isBefore(end)) { 57188 if (view.isHiddenDay(date)) { 57189 dayIndices.push(dayIndex + 0.5); // mark that it's between indices 57190 } 57191 else { 57192 dayIndex++; 57193 dayIndices.push(dayIndex); 57194 dayDates.push(date.clone()); 57195 } 57196 date.add(1, 'days'); 57197 } 57198 if (this.breakOnWeeks) { 57199 // count columns until the day-of-week repeats 57200 firstDay = dayDates[0].day(); 57201 for (daysPerRow = 1; daysPerRow < dayDates.length; daysPerRow++) { 57202 if (dayDates[daysPerRow].day() === firstDay) { 57203 break; 57204 } 57205 } 57206 rowCnt = Math.ceil(dayDates.length / daysPerRow); 57207 } 57208 else { 57209 rowCnt = 1; 57210 daysPerRow = dayDates.length; 57211 } 57212 this.dayDates = dayDates; 57213 this.dayIndices = dayIndices; 57214 this.daysPerRow = daysPerRow; 57215 this.rowCnt = rowCnt; 57216 this.updateDayTableCols(); 57217 }; 57218 // Computes and assigned the colCnt property and updates any options that may be computed from it 57219 DayTableMixin.prototype.updateDayTableCols = function () { 57220 this.colCnt = this.computeColCnt(); 57221 this.colHeadFormat = 57222 this.opt('columnHeaderFormat') || 57223 this.opt('columnFormat') || // deprecated 57224 this.computeColHeadFormat(); 57225 }; 57226 // Determines how many columns there should be in the table 57227 DayTableMixin.prototype.computeColCnt = function () { 57228 return this.daysPerRow; 57229 }; 57230 // Computes the ambiguously-timed moment for the given cell 57231 DayTableMixin.prototype.getCellDate = function (row, col) { 57232 return this.dayDates[this.getCellDayIndex(row, col)].clone(); 57233 }; 57234 // Computes the ambiguously-timed date range for the given cell 57235 DayTableMixin.prototype.getCellRange = function (row, col) { 57236 var start = this.getCellDate(row, col); 57237 var end = start.clone().add(1, 'days'); 57238 return { start: start, end: end }; 57239 }; 57240 // Returns the number of day cells, chronologically, from the first of the grid (0-based) 57241 DayTableMixin.prototype.getCellDayIndex = function (row, col) { 57242 return row * this.daysPerRow + this.getColDayIndex(col); 57243 }; 57244 // Returns the numner of day cells, chronologically, from the first cell in *any given row* 57245 DayTableMixin.prototype.getColDayIndex = function (col) { 57246 if (this.isRTL) { 57247 return this.colCnt - 1 - col; 57248 } 57249 else { 57250 return col; 57251 } 57252 }; 57253 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 57254 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 57255 // If before the first offset, returns a negative number. 57256 // If after the last offset, returns an offset past the last cell offset. 57257 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 57258 DayTableMixin.prototype.getDateDayIndex = function (date) { 57259 var dayIndices = this.dayIndices; 57260 var dayOffset = date.diff(this.dayDates[0], 'days'); 57261 if (dayOffset < 0) {
57262 return dayIndices[0] - 1; 57263 } 57264 else if (dayOffset >= dayIndices.length) { 57265 return dayIndices[dayIndices.length - 1] + 1; 57266 } 57267 else { 57268 return dayIndices[dayOffset]; 57269 } 57270 }; 57271 /* Options 57272 ------------------------------------------------------------------------------------------------------------------*/ 57273 // Computes a default column header formatting string if `colFormat` is not explicitly defined 57274 DayTableMixin.prototype.computeColHeadFormat = function () { 57275 // if more than one week row, or if there are a lot of columns with not much space, 57276 // put just the day numbers will be in each cell 57277 if (this.rowCnt > 1 || this.colCnt > 10) { 57278 return 'ddd'; // "Sat" 57279 } 57280 else if (this.colCnt > 1) { 57281 return this.opt('dayOfMonthFormat'); // "Sat 12/10" 57282 } 57283 else { 57284 return 'dddd'; // "Saturday" 57285 } 57286 }; 57287 /* Slicing 57288 ------------------------------------------------------------------------------------------------------------------*/ 57289 // Slices up a date range into a segment for every week-row it intersects with 57290 DayTableMixin.prototype.sliceRangeByRow = function (unzonedRange) { 57291 var daysPerRow = this.daysPerRow; 57292 var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold 57293 var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index 57294 var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index 57295 var segs = []; 57296 var row; 57297 var rowFirst; 57298 var rowLast; // inclusive day-index range for current row 57299 var segFirst; 57300 var segLast; // inclusive day-index range for segment 57301 for (row = 0; row < this.rowCnt; row++) { 57302 rowFirst = row * daysPerRow; 57303 rowLast = rowFirst + daysPerRow - 1; 57304 // intersect segment's offset range with the row's 57305 segFirst = Math.max(rangeFirst, rowFirst); 57306 segLast = Math.min(rangeLast, rowLast); 57307 // deal with in-between indices 57308 segFirst = Math.ceil(segFirst); // in-between starts round to next cell 57309 segLast = Math.floor(segLast); // in-between ends round to prev cell 57310 if (segFirst <= segLast) { 57311 segs.push({ 57312 row: row, 57313 // normalize to start of row 57314 firstRowDayIndex: segFirst - rowFirst, 57315 lastRowDayIndex: segLast - rowFirst, 57316 // must be matching integers to be the segment's start/end 57317 isStart: segFirst === rangeFirst, 57318 isEnd: segLast === rangeLast 57319 }); 57320 } 57321 } 57322 return segs; 57323 }; 57324 // Slices up a date range into a segment for every day-cell it intersects with. 57325 // TODO: make more DRY with sliceRangeByRow somehow. 57326 DayTableMixin.prototype.sliceRangeByDay = function (unzonedRange) { 57327 var daysPerRow = this.daysPerRow; 57328 var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold 57329 var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index 57330 var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index 57331 var segs = []; 57332 var row; 57333 var rowFirst; 57334 var rowLast; // inclusive day-index range for current row 57335 var i; 57336 var segFirst; 57337 var segLast; // inclusive day-index range for segment 57338 for (row = 0; row < this.rowCnt; row++) { 57339 rowFirst = row * daysPerRow; 57340 rowLast = rowFirst + daysPerRow - 1; 57341 for (i = rowFirst; i <= rowLast; i++) { 57342 // intersect segment's offset range with the row's 57343 segFirst = Math.max(rangeFirst, i); 57344 segLast = Math.min(rangeLast, i); 57345 // deal with in-between indices
57346 segFirst = Math.ceil(segFirst); // in-between starts round to next cell 57347 segLast = Math.floor(segLast); // in-between ends round to prev cell 57348 if (segFirst <= segLast) { 57349 segs.push({ 57350 row: row, 57351 // normalize to start of row 57352 firstRowDayIndex: segFirst - rowFirst, 57353 lastRowDayIndex: segLast - rowFirst, 57354 // must be matching integers to be the segment's start/end 57355 isStart: segFirst === rangeFirst, 57356 isEnd: segLast === rangeLast 57357 }); 57358 } 57359 } 57360 } 57361 return segs; 57362 }; 57363 /* Header Rendering 57364 ------------------------------------------------------------------------------------------------------------------*/ 57365 DayTableMixin.prototype.renderHeadHtml = function () { 57366 var theme = this.view.calendar.theme; 57367 return '' + 57368 '<div class="fc-row ' + theme.getClass('headerRow') + '">' + 57369 '<table class="' + theme.getClass('tableGrid') + '">' + 57370 '<thead>' + 57371 this.renderHeadTrHtml() + 57372 '</thead>' + 57373 '</table>' + 57374 '</div>'; 57375 }; 57376 DayTableMixin.prototype.renderHeadIntroHtml = function () { 57377 return this.renderIntroHtml(); // fall back to generic 57378 }; 57379 DayTableMixin.prototype.renderHeadTrHtml = function () { 57380 return '' + 57381 '<tr>' + 57382 (this.isRTL ? '' : this.renderHeadIntroHtml()) + 57383 this.renderHeadDateCellsHtml() + 57384 (this.isRTL ? this.renderHeadIntroHtml() : '') + 57385 '</tr>'; 57386 }; 57387 DayTableMixin.prototype.renderHeadDateCellsHtml = function () { 57388 var htmls = []; 57389 var col; 57390 var date; 57391 for (col = 0; col < this.colCnt; col++) { 57392 date = this.getCellDate(0, col); 57393 htmls.push(this.renderHeadDateCellHtml(date)); 57394 } 57395 return htmls.join(''); 57396 }; 57397 // TODO: when internalApiVersion, accept an object for HTML attributes 57398 // (colspan should be no different) 57399 DayTableMixin.prototype.renderHeadDateCellHtml = function (date, colspan, otherAttrs) { 57400 var t = this; 57401 var view = t.view; 57402 var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. 57403 var classNames = [ 57404 'fc-day-header', 57405 view.calendar.theme.getClass('widgetHeader') 57406 ]; 57407 var innerHtml; 57408 if (typeof t.opt('columnHeaderHtml') === 'function') { 57409 innerHtml = t.opt('columnHeaderHtml')(date); 57410 } 57411 else if (typeof t.opt('columnHeaderText') === 'function') { 57412 innerHtml = util_1.htmlEscape(t.opt('columnHeaderText')(date)); 57413 } 57414 else { 57415 innerHtml = util_1.htmlEscape(date.format(t.colHeadFormat)); 57416 } 57417 // if only one row of days, the classNames on the header can represent the specific days beneath 57418 if (t.rowCnt === 1) { 57419 classNames = classNames.concat( 57420 // includes the day-of-week class 57421 // noThemeHighlight=true (don't highlight the header) 57422 t.getDayClasses(date, true)); 57423 } 57424 else { 57425 classNames.push('fc-' + util_1.dayIDs[date.day()]); // only add the day-of-week class 57426 } 57427 return '' + 57428 '<th class="' + classNames.join(' ') + '"' + 57429 ((isDateValid && t.rowCnt) === 1 ? 57430 ' data-date="' + date.format('YYYY-MM-DD') + '"' : 57431 '') + 57432 (colspan > 1 ? 57433 ' colspan="' + colspan + '"' : 57434 '') + 57435 (otherAttrs ? 57436 ' ' + otherAttrs : 57437 '') + 57438 '>' + 57439 (isDateValid ? 57440 // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff) 57441 view.buildGotoAnchorHtml({ date: date, forceOff: t.rowCnt > 1 || t.colCnt === 1 }, innerHtml) : 57442 // if not valid, display text, but no link 57443 innerHtml) + 57444 '</th>'; 57445 };
57446 /* Background Rendering 57447 ------------------------------------------------------------------------------------------------------------------*/ 57448 DayTableMixin.prototype.renderBgTrHtml = function (row) { 57449 return '' + 57450 '<tr>' + 57451 (this.isRTL ? '' : this.renderBgIntroHtml(row)) + 57452 this.renderBgCellsHtml(row) + 57453 (this.isRTL ? this.renderBgIntroHtml(row) : '') + 57454 '</tr>'; 57455 }; 57456 DayTableMixin.prototype.renderBgIntroHtml = function (row) { 57457 return this.renderIntroHtml(); // fall back to generic 57458 }; 57459 DayTableMixin.prototype.renderBgCellsHtml = function (row) { 57460 var htmls = []; 57461 var col; 57462 var date; 57463 for (col = 0; col < this.colCnt; col++) { 57464 date = this.getCellDate(row, col); 57465 htmls.push(this.renderBgCellHtml(date)); 57466 } 57467 return htmls.join(''); 57468 }; 57469 DayTableMixin.prototype.renderBgCellHtml = function (date, otherAttrs) { 57470 var t = this; 57471 var view = t.view; 57472 var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. 57473 var classes = t.getDayClasses(date); 57474 classes.unshift('fc-day', view.calendar.theme.getClass('widgetContent')); 57475 return '<td class="' + classes.join(' ') + '"' + 57476 (isDateValid ? 57477 ' data-date="' + date.format('YYYY-MM-DD') + '"' : // if date has a time, won't format it 57478 '') + 57479 (otherAttrs ? 57480 ' ' + otherAttrs : 57481 '') + 57482 '></td>'; 57483 }; 57484 /* Generic 57485 ------------------------------------------------------------------------------------------------------------------*/ 57486 DayTableMixin.prototype.renderIntroHtml = function () { 57487 // Generates the default HTML intro for any row. User classes should override 57488 }; 57489 // TODO: a generic method for dealing with <tr>, RTL, intro 57490 // when increment internalApiVersion 57491 // wrapTr (scheduler) 57492 /* Utils 57493 ------------------------------------------------------------------------------------------------------------------*/ 57494 // Applies the generic "intro" and "outro" HTML to the given cells. 57495 // Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro. 57496 DayTableMixin.prototype.bookendCells = function (trEl) { 57497 var introHtml = this.renderIntroHtml(); 57498 if (introHtml) { 57499 if (this.isRTL) { 57500 trEl.append(introHtml); 57501 } 57502 else { 57503 trEl.prepend(introHtml); 57504 } 57505 } 57506 }; 57507 return DayTableMixin; 57508}(Mixin_1.default)); 57509exports.default = DayTableMixin; 57510 57511 57512/***/ }), 57513/* 56 */ 57514/***/ (function(module, exports) { 57515 57516Object.defineProperty(exports, "__esModule", { value: true }); 57517var BusinessHourRenderer = /** @class */ (function () { 57518 /* 57519 component implements: 57520 - eventRangesToEventFootprints 57521 - eventFootprintsToSegs 57522 */ 57523 function BusinessHourRenderer(component, fillRenderer) { 57524 this.component = component; 57525 this.fillRenderer = fillRenderer; 57526 } 57527 BusinessHourRenderer.prototype.render = function (businessHourGenerator) { 57528 var component = this.component; 57529 var unzonedRange = component._getDateProfile().activeUnzonedRange; 57530 var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(component.hasAllDayBusinessHours, unzonedRange); 57531 var eventFootprints = eventInstanceGroup ? 57532 component.eventRangesToEventFootprints(eventInstanceGroup.sliceRenderRanges(unzonedRange)) : 57533 []; 57534 this.renderEventFootprints(eventFootprints); 57535 }; 57536 BusinessHourRenderer.prototype.renderEventFootprints = function (eventFootprints) { 57537 var segs = this.component.eventFootprintsToSegs(eventFootprints); 57538 this.renderSegs(segs); 57539 this.segs = segs; 57540 }; 57541 BusinessHourRenderer.prototype.renderSegs = function (segs) { 57542 if (this.fillRenderer) { 57543 this.fillRenderer.renderSegs('businessHours', segs, { 57544 getClasses: function (seg) { 57545 return ['fc-nonbusiness', 'fc-bgevent']; 57546 } 57547 }); 57548 } 57549 }; 57550 BusinessHourRenderer.prototype.unrender = function () { 57551 if (this.fillRenderer) { 57552 this.fillRenderer.unrender('businessHours'); 57553 } 57554 this.segs = null; 57555 }; 57556 BusinessHourRenderer.prototype.getSegs = function () { 57557 return this.segs || []; 57558 }; 57559 return BusinessHourRenderer; 57560}()); 57561exports.default = BusinessHourRenderer; 57562 57563 57564/***/ }), 57565/* 57 */ 57566/***/ (function(module, exports, __webpack_require__) { 57567 57568Object.defineProperty(exports, "__esModule", { value: true });
57569var $ = __webpack_require__(3); 57570var util_1 = __webpack_require__(4); 57571var FillRenderer = /** @class */ (function () { 57572 function FillRenderer(component) { 57573 this.fillSegTag = 'div'; 57574 this.component = component; 57575 this.elsByFill = {}; 57576 } 57577 FillRenderer.prototype.renderFootprint = function (type, componentFootprint, props) { 57578 this.renderSegs(type, this.component.componentFootprintToSegs(componentFootprint), props); 57579 }; 57580 FillRenderer.prototype.renderSegs = function (type, segs, props) { 57581 var els; 57582 segs = this.buildSegEls(type, segs, props); // assignes `.el` to each seg. returns successfully rendered segs 57583 els = this.attachSegEls(type, segs); 57584 if (els) { 57585 this.reportEls(type, els); 57586 } 57587 return segs; 57588 }; 57589 // Unrenders a specific type of fill that is currently rendered on the grid 57590 FillRenderer.prototype.unrender = function (type) { 57591 var el = this.elsByFill[type]; 57592 if (el) { 57593 el.remove(); 57594 delete this.elsByFill[type]; 57595 } 57596 }; 57597 // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types. 57598 // Only returns segments that successfully rendered. 57599 FillRenderer.prototype.buildSegEls = function (type, segs, props) { 57600 var _this = this; 57601 var html = ''; 57602 var renderedSegs = []; 57603 var i; 57604 if (segs.length) { 57605 // build a large concatenation of segment HTML 57606 for (i = 0; i < segs.length; i++) { 57607 html += this.buildSegHtml(type, segs[i], props); 57608 } 57609 // Grab individual elements from the combined HTML string. Use each as the default rendering. 57610 // Then, compute the 'el' for each segment. 57611 $(html).each(function (i, node) { 57612 var seg = segs[i]; 57613 var el = $(node); 57614 // allow custom filter methods per-type 57615 if (props.filterEl) { 57616 el = props.filterEl(seg, el); 57617 } 57618 if (el) { 57619 el = $(el); // allow custom filter to return raw DOM node 57620 // correct element type? (would be bad if a non-TD were inserted into a table for example) 57621 if (el.is(_this.fillSegTag)) { 57622 seg.el = el; 57623 renderedSegs.push(seg); 57624 } 57625 } 57626 }); 57627 } 57628 return renderedSegs; 57629 }; 57630 // Builds the HTML needed for one fill segment. Generic enough to work with different types. 57631 FillRenderer.prototype.buildSegHtml = function (type, seg, props) { 57632 // custom hooks per-type 57633 var classes = props.getClasses ? props.getClasses(seg) : []; 57634 var css = util_1.cssToStr(props.getCss ? props.getCss(seg) : {}); 57635 return '<' + this.fillSegTag + 57636 (classes.length ? ' class="' + classes.join(' ') + '"' : '') + 57637 (css ? ' style="' + css + '"' : '') + 57638 ' />'; 57639 }; 57640 // Should return wrapping DOM structure 57641 FillRenderer.prototype.attachSegEls = function (type, segs) { 57642 // subclasses must implement 57643 }; 57644 FillRenderer.prototype.reportEls = function (type, nodes) { 57645 if (this.elsByFill[type]) { 57646 this.elsByFill[type] = this.elsByFill[type].add(nodes); 57647 } 57648 else { 57649 this.elsByFill[type] = $(nodes); 57650 } 57651 }; 57652 return FillRenderer; 57653}()); 57654exports.default = FillRenderer; 57655 57656 57657/***/ }), 57658/* 58 */ 57659/***/ (function(module, exports, __webpack_require__) { 57660 57661Object.defineProperty(exports, "__esModule", { value: true }); 57662var SingleEventDef_1 = __webpack_require__(13); 57663var EventFootprint_1 = __webpack_require__(36); 57664var EventSource_1 = __webpack_require__(6); 57665var HelperRenderer = /** @class */ (function () { 57666 function HelperRenderer(component, eventRenderer) { 57667 this.view = component._getView(); 57668 this.component = component; 57669 this.eventRenderer = eventRenderer; 57670 } 57671 HelperRenderer.prototype.renderComponentFootprint = function (componentFootprint) { 57672 this.renderEventFootprints([ 57673 this.fabricateEventFootprint(componentFootprint) 57674 ]); 57675 }; 57676 HelperRenderer.prototype.renderEventDraggingFootprints = function (eventFootprints, sourceSeg, isTouch) { 57677 this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-dragging', isTouch ? null : this.view.opt('dragOpacity')); 57678 }; 57679 HelperRenderer.prototype.renderEventResizingFootprints = function (eventFootprints, sourceSeg, isTouch) { 57680 this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-resizing'); 57681 }; 57682 HelperRenderer.prototype.renderEventFootprints = function (eventFootprints, sourceSeg, extraClassNames, opacity) { 57683 var segs = this.component.eventFootprintsToSegs(eventFootprints); 57684 var classNames = 'fc-helper ' + (extraClassNames || ''); 57685 var i; 57686 // assigns each seg's el and returns a subset of segs that were rendered 57687 segs = this.eventRenderer.renderFgSegEls(segs); 57688 for (i = 0; i < segs.length; i++) { 57689 segs[i].el.addClass(classNames); 57690 } 57691 if (opacity != null) { 57692 for (i = 0; i < segs.length; i++) { 57693 segs[i].el.css('opacity', opacity); 57694 } 57695 } 57696 this.helperEls = this.renderSegs(segs, sourceSeg); 57697 }; 57698 /* 57699 Must return all mock event elements 57700 */ 57701 HelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { 57702 // Subclasses must implement 57703 }; 57704 HelperRenderer.prototype.unrender = function () { 57705 if (this.helperEls) { 57706 this.helperEls.remove(); 57707 this.helperEls = null; 57708 } 57709 }; 57710 HelperRenderer.prototype.fabricateEventFootprint = function (componentFootprint) { 57711 var calendar = this.view.calendar; 57712 var eventDateProfile = calendar.footprintToDateProfile(componentFootprint); 57713 var dummyEvent = new SingleEventDef_1.default(new EventSource_1.default(calendar)); 57714 var dummyInstance; 57715 dummyEvent.dateProfile = eventDateProfile; 57716 dummyInstance = dummyEvent.buildInstance(); 57717 return new EventFootprint_1.default(componentFootprint, dummyEvent, dummyInstance); 57718 }; 57719 return HelperRenderer; 57720}()); 57721exports.default = HelperRenderer; 57722 57723 57724/***/ }), 57725/* 59 */ 57726/***/ (function(module, exports, __webpack_require__) { 57727 57728Object.defineProperty(exports, "__esModule", { value: true });
57729var tslib_1 = __webpack_require__(2); 57730var GlobalEmitter_1 = __webpack_require__(21); 57731var Interaction_1 = __webpack_require__(15); 57732var EventPointing = /** @class */ (function (_super) { 57733 tslib_1.__extends(EventPointing, _super); 57734 function EventPointing() { 57735 return _super !== null && _super.apply(this, arguments) || this; 57736 } 57737 /* 57738 component must implement: 57739 - publiclyTrigger 57740 */ 57741 EventPointing.prototype.bindToEl = function (el) { 57742 var component = this.component; 57743 component.bindSegHandlerToEl(el, 'click', this.handleClick.bind(this)); 57744 component.bindSegHandlerToEl(el, 'mouseenter', this.handleMouseover.bind(this)); 57745 component.bindSegHandlerToEl(el, 'mouseleave', this.handleMouseout.bind(this)); 57746 }; 57747 EventPointing.prototype.handleClick = function (seg, ev) { 57748 var res = this.component.publiclyTrigger('eventClick', { 57749 context: seg.el[0], 57750 args: [seg.footprint.getEventLegacy(), ev, this.view] 57751 }); 57752 if (res === false) { 57753 ev.preventDefault(); 57754 } 57755 }; 57756 // Updates internal state and triggers handlers for when an event element is moused over 57757 EventPointing.prototype.handleMouseover = function (seg, ev) { 57758 if (!GlobalEmitter_1.default.get().shouldIgnoreMouse() && 57759 !this.mousedOverSeg) { 57760 this.mousedOverSeg = seg; 57761 // TODO: move to EventSelecting's responsibility 57762 if (this.view.isEventDefResizable(seg.footprint.eventDef)) { 57763 seg.el.addClass('fc-allow-mouse-resize'); 57764 } 57765 this.component.publiclyTrigger('eventMouseover', { 57766 context: seg.el[0], 57767 args: [seg.footprint.getEventLegacy(), ev, this.view] 57768 }); 57769 } 57770 }; 57771 // Updates internal state and triggers handlers for when an event element is moused out. 57772 // Can be given no arguments, in which case it will mouseout the segment that was previously moused over. 57773 EventPointing.prototype.handleMouseout = function (seg, ev) { 57774 if (this.mousedOverSeg) { 57775 this.mousedOverSeg = null; 57776 // TODO: move to EventSelecting's responsibility 57777 if (this.view.isEventDefResizable(seg.footprint.eventDef)) { 57778 seg.el.removeClass('fc-allow-mouse-resize'); 57779 } 57780 this.component.publiclyTrigger('eventMouseout', { 57781 context: seg.el[0], 57782 args: [ 57783 seg.footprint.getEventLegacy(), 57784 ev || {}, 57785 this.view 57786 ] 57787 }); 57788 } 57789 }; 57790 EventPointing.prototype.end = function () { 57791 if (this.mousedOverSeg) { 57792 this.handleMouseout(this.mousedOverSeg); 57793 } 57794 }; 57795 return EventPointing; 57796}(Interaction_1.default)); 57797exports.default = EventPointing; 57798 57799 57800/***/ }), 57801/* 60 */ 57802/***/ (function(module, exports, __webpack_require__) { 57803 57804Object.defineProperty(exports, "__esModule", { value: true }); 57805var tslib_1 = __webpack_require__(2); 57806var Mixin_1 = __webpack_require__(14); 57807var DateClicking_1 = __webpack_require__(245); 57808var DateSelecting_1 = __webpack_require__(225); 57809var EventPointing_1 = __webpack_require__(59); 57810var EventDragging_1 = __webpack_require__(224); 57811var EventResizing_1 = __webpack_require__(223);
57812var ExternalDropping_1 = __webpack_require__(222); 57813var StandardInteractionsMixin = /** @class */ (function (_super) { 57814 tslib_1.__extends(StandardInteractionsMixin, _super); 57815 function StandardInteractionsMixin() { 57816 return _super !== null && _super.apply(this, arguments) || this; 57817 } 57818 return StandardInteractionsMixin; 57819}(Mixin_1.default)); 57820exports.default = StandardInteractionsMixin; 57821StandardInteractionsMixin.prototype.dateClickingClass = DateClicking_1.default; 57822StandardInteractionsMixin.prototype.dateSelectingClass = DateSelecting_1.default; 57823StandardInteractionsMixin.prototype.eventPointingClass = EventPointing_1.default; 57824StandardInteractionsMixin.prototype.eventDraggingClass = EventDragging_1.default; 57825StandardInteractionsMixin.prototype.eventResizingClass = EventResizing_1.default; 57826StandardInteractionsMixin.prototype.externalDroppingClass = ExternalDropping_1.default; 57827 57828 57829/***/ }), 57830/* 61 */ 57831/***/ (function(module, exports, __webpack_require__) { 57832 57833Object.defineProperty(exports, "__esModule", { value: true }); 57834var tslib_1 = __webpack_require__(2); 57835var $ = __webpack_require__(3); 57836var util_1 = __webpack_require__(4); 57837var CoordCache_1 = __webpack_require__(53); 57838var Popover_1 = __webpack_require__(249); 57839var UnzonedRange_1 = __webpack_require__(5); 57840var ComponentFootprint_1 = __webpack_require__(12); 57841var EventFootprint_1 = __webpack_require__(36); 57842var BusinessHourRenderer_1 = __webpack_require__(56); 57843var StandardInteractionsMixin_1 = __webpack_require__(60); 57844var InteractiveDateComponent_1 = __webpack_require__(40); 57845var DayTableMixin_1 = __webpack_require__(55); 57846var DayGridEventRenderer_1 = __webpack_require__(250); 57847var DayGridHelperRenderer_1 = __webpack_require__(251); 57848var DayGridFillRenderer_1 = __webpack_require__(252); 57849/* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week. 57850----------------------------------------------------------------------------------------------------------------------*/ 57851var DayGrid = /** @class */ (function (_super) { 57852 tslib_1.__extends(DayGrid, _super); 57853 function DayGrid(view) { 57854 var _this = _super.call(this, view) || this; 57855 _this.cellWeekNumbersVisible = false; // display week numbers in day cell? 57856 _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid 57857 // isRigid determines whether the individual rows should ignore the contents and be a constant height. 57858 // Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient. 57859 _this.isRigid = false; 57860 _this.hasAllDayBusinessHours = true; 57861 return _this; 57862 } 57863 // Slices up the given span (unzoned start/end with other misc data) into an array of segments 57864 DayGrid.prototype.componentFootprintToSegs = function (componentFootprint) { 57865 var segs = this.sliceRangeByRow(componentFootprint.unzonedRange); 57866 var i; 57867 var seg; 57868 for (i = 0; i < segs.length; i++) { 57869 seg = segs[i]; 57870 if (this.isRTL) { 57871 seg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex; 57872 seg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex; 57873 } 57874 else { 57875 seg.leftCol = seg.firstRowDayIndex; 57876 seg.rightCol = seg.lastRowDayIndex; 57877 } 57878 } 57879 return segs; 57880 }; 57881 /* Date Rendering 57882 ------------------------------------------------------------------------------------------------------------------*/ 57883 DayGrid.prototype.renderDates = function (dateProfile) { 57884 this.dateProfile = dateProfile; 57885 this.updateDayTable(); 57886 this.renderGrid(); 57887 }; 57888 DayGrid.prototype.unrenderDates = function () { 57889 this.removeSegPopover(); 57890 }; 57891 // Renders the rows and columns into the component's `this.el`, which should already be assigned. 57892 DayGrid.prototype.renderGrid = function () { 57893 var view = this.view; 57894 var rowCnt = this.rowCnt; 57895 var colCnt = this.colCnt; 57896 var html = ''; 57897 var row; 57898 var col; 57899 if (this.headContainerEl) { 57900 this.headContainerEl.html(this.renderHeadHtml()); 57901 } 57902 for (row = 0; row < rowCnt; row++) { 57903 html += this.renderDayRowHtml(row, this.isRigid); 57904 } 57905 this.el.html(html); 57906 this.rowEls = this.el.find('.fc-row'); 57907 this.cellEls = this.el.find('.fc-day, .fc-disabled-day');
57908 this.rowCoordCache = new CoordCache_1.default({ 57909 els: this.rowEls, 57910 isVertical: true 57911 }); 57912 this.colCoordCache = new CoordCache_1.default({ 57913 els: this.cellEls.slice(0, this.colCnt), 57914 isHorizontal: true 57915 }); 57916 // trigger dayRender with each cell's element 57917 for (row = 0; row < rowCnt; row++) { 57918 for (col = 0; col < colCnt; col++) { 57919 this.publiclyTrigger('dayRender', { 57920 context: view, 57921 args: [ 57922 this.getCellDate(row, col), 57923 this.getCellEl(row, col), 57924 view 57925 ] 57926 }); 57927 } 57928 } 57929 }; 57930 // Generates the HTML for a single row, which is a div that wraps a table. 57931 // `row` is the row number. 57932 DayGrid.prototype.renderDayRowHtml = function (row, isRigid) { 57933 var theme = this.view.calendar.theme; 57934 var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')]; 57935 if (isRigid) { 57936 classes.push('fc-rigid'); 57937 } 57938 return '' + 57939 '<div class="' + classes.join(' ') + '">' + 57940 '<div class="fc-bg">' + 57941 '<table class="' + theme.getClass('tableGrid') + '">' + 57942 this.renderBgTrHtml(row) + 57943 '</table>' + 57944 '</div>' + 57945 '<div class="fc-content-skeleton">' + 57946 '<table>' + 57947 (this.getIsNumbersVisible() ? 57948 '<thead>' + 57949 this.renderNumberTrHtml(row) + 57950 '</thead>' : 57951 '') + 57952 '</table>' + 57953 '</div>' + 57954 '</div>'; 57955 }; 57956 DayGrid.prototype.getIsNumbersVisible = function () { 57957 return this.getIsDayNumbersVisible() || this.cellWeekNumbersVisible; 57958 }; 57959 DayGrid.prototype.getIsDayNumbersVisible = function () { 57960 return this.rowCnt > 1; 57961 }; 57962 /* Grid Number Rendering 57963 ------------------------------------------------------------------------------------------------------------------*/ 57964 DayGrid.prototype.renderNumberTrHtml = function (row) { 57965 return '' + 57966 '<tr>' + 57967 (this.isRTL ? '' : this.renderNumberIntroHtml(row)) + 57968 this.renderNumberCellsHtml(row) + 57969 (this.isRTL ? this.renderNumberIntroHtml(row) : '') + 57970 '</tr>'; 57971 }; 57972 DayGrid.prototype.renderNumberIntroHtml = function (row) { 57973 return this.renderIntroHtml(); 57974 }; 57975 DayGrid.prototype.renderNumberCellsHtml = function (row) { 57976 var htmls = []; 57977 var col; 57978 var date; 57979 for (col = 0; col < this.colCnt; col++) { 57980 date = this.getCellDate(row, col); 57981 htmls.push(this.renderNumberCellHtml(date)); 57982 } 57983 return htmls.join(''); 57984 }; 57985 // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton. 57986 // The number row will only exist if either day numbers or week numbers are turned on. 57987 DayGrid.prototype.renderNumberCellHtml = function (date) { 57988 var view = this.view; 57989 var html = ''; 57990 var isDateValid = this.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. 57991 var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid; 57992 var classes; 57993 var weekCalcFirstDoW; 57994 if (!isDayNumberVisible && !this.cellWeekNumbersVisible) { 57995 // no numbers in day cell (week number must be along the side) 57996 return '<td/>'; // will create an empty space above events :( 57997 } 57998 classes = this.getDayClasses(date); 57999 classes.unshift('fc-day-top'); 58000 if (this.cellWeekNumbersVisible) { 58001 // To determine the day of week number change under ISO, we cannot 58002 // rely on moment.js methods such as firstDayOfWeek() or weekday(), 58003 // because they rely on the locale's dow (possibly overridden by 58004 // our firstDay option), which may not be Monday. We cannot change 58005 // dow, because that would affect the calendar start day as well. 58006 if (date._locale._fullCalendar_weekCalc === 'ISO') { 58007 weekCalcFirstDoW = 1; // Monday by ISO 8601 definition 58008 } 58009 else { 58010 weekCalcFirstDoW = date._locale.firstDayOfWeek(); 58011 } 58012 } 58013 html += '<td class="' + classes.join(' ') + '"' + 58014 (isDateValid ? 58015 ' data-date="' + date.format() + '"' : 58016 '') + 58017 '>'; 58018 if (this.cellWeekNumbersVisible && (date.day() === weekCalcFirstDoW)) { 58019 html += view.buildGotoAnchorHtml({ date: date, type: 'week' }, { 'class': 'fc-week-number' }, date.format('w') // inner HTML 58020 ); 58021 } 58022 if (isDayNumberVisible) { 58023 html += view.buildGotoAnchorHtml(date, { 'class': 'fc-day-number' }, date.format('D') // inner HTML 58024 ); 58025 } 58026 html += '</td>'; 58027 return html; 58028 }; 58029 /* Hit System 58030 ------------------------------------------------------------------------------------------------------------------*/ 58031 DayGrid.prototype.prepareHits = function () { 58032 this.colCoordCache.build(); 58033 this.rowCoordCache.build(); 58034 this.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack 58035 }; 58036 DayGrid.prototype.releaseHits = function () { 58037 this.colCoordCache.clear(); 58038 this.rowCoordCache.clear(); 58039 }; 58040 DayGrid.prototype.queryHit = function (leftOffset, topOffset) { 58041 if (this.colCoordCache.isLeftInBounds(leftOffset) && this.rowCoordCache.isTopInBounds(topOffset)) { 58042 var col = this.colCoordCache.getHorizontalIndex(leftOffset); 58043 var row = this.rowCoordCache.getVerticalIndex(topOffset); 58044 if (row != null && col != null) { 58045 return this.getCellHit(row, col); 58046 } 58047 } 58048 }; 58049 DayGrid.prototype.getHitFootprint = function (hit) { 58050 var range = this.getCellRange(hit.row, hit.col); 58051 return new ComponentFootprint_1.default(new UnzonedRange_1.default(range.start, range.end), true // all-day? 58052 ); 58053 }; 58054 DayGrid.prototype.getHitEl = function (hit) { 58055 return this.getCellEl(hit.row, hit.col); 58056 }; 58057 /* Cell System 58058 ------------------------------------------------------------------------------------------------------------------*/ 58059 // FYI: the first column is the leftmost column, regardless of date 58060 DayGrid.prototype.getCellHit = function (row, col) { 58061 return { 58062 row: row, 58063 col: col, 58064 component: this, 58065 left: this.colCoordCache.getLeftOffset(col), 58066 right: this.colCoordCache.getRightOffset(col), 58067 top: this.rowCoordCache.getTopOffset(row), 58068 bottom: this.rowCoordCache.getBottomOffset(row) 58069 }; 58070 }; 58071 DayGrid.prototype.getCellEl = function (row, col) { 58072 return this.cellEls.eq(row * this.colCnt + col); 58073 }; 58074 /* Event Rendering 58075 ------------------------------------------------------------------------------------------------------------------*/ 58076 // Unrenders all events currently rendered on the grid 58077 DayGrid.prototype.executeEventUnrender = function () { 58078 this.removeSegPopover(); // removes the "more.." events popover 58079 _super.prototype.executeEventUnrender.call(this); 58080 }; 58081 // Retrieves all rendered segment objects currently rendered on the grid 58082 DayGrid.prototype.getOwnEventSegs = function () { 58083 // append the segments from the "more..." popover 58084 return _super.prototype.getOwnEventSegs.call(this).concat(this.popoverSegs || []); 58085 }; 58086 /* Event Drag Visualization 58087 ------------------------------------------------------------------------------------------------------------------*/ 58088 // Renders a visual indication of an event or external element being dragged. 58089 // `eventLocation` has zoned start and end (optional) 58090 DayGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) { 58091 var i; 58092 for (i = 0; i < eventFootprints.length; i++) { 58093 this.renderHighlight(eventFootprints[i].componentFootprint); 58094 } 58095 // render drags from OTHER components as helpers 58096 if (eventFootprints.length && seg && seg.component !== this) { 58097 this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch); 58098 return true; // signal helpers rendered 58099 } 58100 }; 58101 // Unrenders any visual indication of a hovering event 58102 DayGrid.prototype.unrenderDrag = function () { 58103 this.unrenderHighlight(); 58104 this.helperRenderer.unrender(); 58105 }; 58106 /* Event Resize Visualization 58107 ------------------------------------------------------------------------------------------------------------------*/ 58108 // Renders a visual indication of an event being resized 58109 DayGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { 58110 var i; 58111 for (i = 0; i < eventFootprints.length; i++) { 58112 this.renderHighlight(eventFootprints[i].componentFootprint); 58113 } 58114 this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch); 58115 }; 58116 // Unrenders a visual indication of an event being resized 58117 DayGrid.prototype.unrenderEventResize = function () { 58118 this.unrenderHighlight(); 58119 this.helperRenderer.unrender(); 58120 }; 58121 /* More+ Link Popover 58122 ------------------------------------------------------------------------------------------------------------------*/ 58123 DayGrid.prototype.removeSegPopover = function () { 58124 if (this.segPopover) { 58125 this.segPopover.hide(); // in handler, will call segPopover's removeElement 58126 } 58127 }; 58128 // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid. 58129 // `levelLimit` can be false (don't limit), a number, or true (should be computed). 58130 DayGrid.prototype.limitRows = function (levelLimit) { 58131 var rowStructs = this.eventRenderer.rowStructs || []; 58132 var row; // row # 58133 var rowLevelLimit; 58134 for (row = 0; row < rowStructs.length; row++) { 58135 this.unlimitRow(row);
58136 if (!levelLimit) { 58137 rowLevelLimit = false; 58138 } 58139 else if (typeof levelLimit === 'number') { 58140 rowLevelLimit = levelLimit; 58141 } 58142 else { 58143 rowLevelLimit = this.computeRowLevelLimit(row); 58144 } 58145 if (rowLevelLimit !== false) { 58146 this.limitRow(row, rowLevelLimit); 58147 } 58148 } 58149 }; 58150 // Computes the number of levels a row will accomodate without going outside its bounds. 58151 // Assumes the row is "rigid" (maintains a constant height regardless of what is inside). 58152 // `row` is the row number. 58153 DayGrid.prototype.computeRowLevelLimit = function (row) { 58154 var rowEl = this.rowEls.eq(row); // the containing "fake" row div 58155 var rowHeight = rowEl.height(); // TODO: cache somehow? 58156 var trEls = this.eventRenderer.rowStructs[row].tbodyEl.children(); 58157 var i; 58158 var trEl; 58159 var trHeight; 58160 function iterInnerHeights(i, childNode) { 58161 trHeight = Math.max(trHeight, $(childNode).outerHeight()); 58162 } 58163 // Reveal one level <tr> at a time and stop when we find one out of bounds 58164 for (i = 0; i < trEls.length; i++) { 58165 trEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal) 58166 // with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell, 58167 // so instead, find the tallest inner content element. 58168 trHeight = 0; 58169 trEl.find('> td > :first-child').each(iterInnerHeights); 58170 if (trEl.position().top + trHeight > rowHeight) { 58171 return i; 58172 } 58173 } 58174 return false; // should not limit at all 58175 }; 58176 // Limits the given grid row to the maximum number of levels and injects "more" links if necessary. 58177 // `row` is the row number. 58178 // `levelLimit` is a number for the maximum (inclusive) number of levels allowed. 58179 DayGrid.prototype.limitRow = function (row, levelLimit) { 58180 var _this = this; 58181 var rowStruct = this.eventRenderer.rowStructs[row]; 58182 var moreNodes = []; // array of "more" <a> links and <td> DOM nodes 58183 var col = 0; // col #, left-to-right (not chronologically) 58184 var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right 58185 var cellMatrix; // a matrix (by level, then column) of all <td> jQuery elements in the row 58186 var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes 58187 var i; 58188 var seg; 58189 var segsBelow; // array of segment objects below `seg` in the current `col` 58190 var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies 58191 var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column) 58192 var td; 58193 var rowspan; 58194 var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell 58195 var j; 58196 var moreTd; 58197 var moreWrap; 58198 var moreLink; 58199 // Iterates through empty level cells and places "more" links inside if need be 58200 var emptyCellsUntil = function (endCol) { 58201 while (col < endCol) { 58202 segsBelow = _this.getCellSegs(row, col, levelLimit); 58203 if (segsBelow.length) { 58204 td = cellMatrix[levelLimit - 1][col]; 58205 moreLink = _this.renderMoreLink(row, col, segsBelow); 58206 moreWrap = $('<div/>').append(moreLink); 58207 td.append(moreWrap); 58208 moreNodes.push(moreWrap[0]); 58209 } 58210 col++; 58211 } 58212 }; 58213 if (levelLimit && levelLimit < rowStruct.segLevels.length) { 58214 levelSegs = rowStruct.segLevels[levelLimit - 1]; 58215 cellMatrix = rowStruct.cellMatrix; 58216 limitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level <tr> elements past the limit 58217 .addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array 58218 // iterate though segments in the last allowable level 58219 for (i = 0; i < levelSegs.length; i++) { 58220 seg = levelSegs[i]; 58221 emptyCellsUntil(seg.leftCol); // process empty cells before the segment 58222 // determine *all* segments below `seg` that occupy the same columns 58223 colSegsBelow = []; 58224 totalSegsBelow = 0; 58225 while (col <= seg.rightCol) { 58226 segsBelow = this.getCellSegs(row, col, levelLimit); 58227 colSegsBelow.push(segsBelow);
58228 totalSegsBelow += segsBelow.length; 58229 col++; 58230 } 58231 if (totalSegsBelow) { 58232 td = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell 58233 rowspan = td.attr('rowspan') || 1; 58234 segMoreNodes = []; 58235 // make a replacement <td> for each column the segment occupies. will be one for each colspan 58236 for (j = 0; j < colSegsBelow.length; j++) { 58237 moreTd = $('<td class="fc-more-cell"/>').attr('rowspan', rowspan); 58238 segsBelow = colSegsBelow[j]; 58239 moreLink = this.renderMoreLink(row, seg.leftCol + j, [seg].concat(segsBelow) // count seg as hidden too 58240 ); 58241 moreWrap = $('<div/>').append(moreLink); 58242 moreTd.append(moreWrap); 58243 segMoreNodes.push(moreTd[0]); 58244 moreNodes.push(moreTd[0]); 58245 } 58246 td.addClass('fc-limited').after($(segMoreNodes)); // hide original <td> and inject replacements 58247 limitedNodes.push(td[0]); 58248 } 58249 } 58250 emptyCellsUntil(this.colCnt); // finish off the level 58251 rowStruct.moreEls = $(moreNodes); // for easy undoing later 58252 rowStruct.limitedEls = $(limitedNodes); // for easy undoing later 58253 } 58254 }; 58255 // Reveals all levels and removes all "more"-related elements for a grid's row. 58256 // `row` is a row number. 58257 DayGrid.prototype.unlimitRow = function (row) { 58258 var rowStruct = this.eventRenderer.rowStructs[row]; 58259 if (rowStruct.moreEls) { 58260 rowStruct.moreEls.remove(); 58261 rowStruct.moreEls = null; 58262 } 58263 if (rowStruct.limitedEls) { 58264 rowStruct.limitedEls.removeClass('fc-limited'); 58265 rowStruct.limitedEls = null; 58266 } 58267 }; 58268 // Renders an <a> element that represents hidden event element for a cell. 58269 // Responsible for attaching click handler as well. 58270 DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) { 58271 var _this = this; 58272 var view = this.view; 58273 return $('<a class="fc-more"/>') 58274 .text(this.getMoreLinkText(hiddenSegs.length)) 58275 .on('click', function (ev) { 58276 var clickOption = _this.opt('eventLimitClick'); 58277 var date = _this.getCellDate(row, col); 58278 var moreEl = $(ev.currentTarget); 58279 var dayEl = _this.getCellEl(row, col); 58280 var allSegs = _this.getCellSegs(row, col); 58281 // rescope the segments to be within the cell's date 58282 var reslicedAllSegs = _this.resliceDaySegs(allSegs, date); 58283 var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date); 58284 if (typeof clickOption === 'function') { 58285 // the returned value can be an atomic option 58286 clickOption = _this.publiclyTrigger('eventLimitClick', { 58287 context: view, 58288 args: [ 58289 { 58290 date: date.clone(), 58291 dayEl: dayEl, 58292 moreEl: moreEl, 58293 segs: reslicedAllSegs, 58294 hiddenSegs: reslicedHiddenSegs 58295 }, 58296 ev, 58297 view 58298 ] 58299 }); 58300 } 58301 if (clickOption === 'popover') { 58302 _this.showSegPopover(row, col, moreEl, reslicedAllSegs); 58303 } 58304 else if (typeof clickOption === 'string') { 58305 view.calendar.zoomTo(date, clickOption); 58306 } 58307 }); 58308 }; 58309 // Reveals the popover that displays all events within a cell 58310 DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) { 58311 var _this = this; 58312 var view = this.view; 58313 var moreWrap = moreLink.parent(); // the <div> wrapper around the <a> 58314 var topEl; // the element we want to match the top coordinate of 58315 var options; 58316 if (this.rowCnt === 1) { 58317 topEl = view.el; // will cause the popover to cover any sort of header 58318 } 58319 else { 58320 topEl = this.rowEls.eq(row); // will align with top of row 58321 } 58322 options = { 58323 className: 'fc-more-popover ' + view.calendar.theme.getClass('popover'), 58324 content: this.renderSegPopoverContent(row, col, segs), 58325 parentEl: view.el, 58326 top: topEl.offset().top, 58327 autoHide: true, 58328 viewportConstrain: this.opt('popoverViewportConstrain'), 58329 hide: function () { 58330 // kill everything when the popover is hidden 58331 // notify events to be removed 58332 if (_this.popoverSegs) { 58333 _this.triggerBeforeEventSegsDestroyed(_this.popoverSegs); 58334 } 58335 _this.segPopover.removeElement(); 58336 _this.segPopover = null; 58337 _this.popoverSegs = null; 58338 } 58339 }; 58340 // Determine horizontal coordinate. 58341 // We use the moreWrap instead of the <td> to avoid border confusion. 58342 if (this.isRTL) { 58343 options.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border 58344 } 58345 else { 58346 options.left = moreWrap.offset().left - 1; // -1 to be over cell border 58347 } 58348 this.segPopover = new Popover_1.default(options); 58349 this.segPopover.show(); 58350 // the popover doesn't live within the grid's container element, and thus won't get the event 58351 // delegated-handlers for free. attach event-related handlers to the popover. 58352 this.bindAllSegHandlersToEl(this.segPopover.el); 58353 this.triggerAfterEventSegsRendered(segs); 58354 }; 58355 // Builds the inner DOM contents of the segment popover 58356 DayGrid.prototype.renderSegPopoverContent = function (row, col, segs) { 58357 var view = this.view; 58358 var theme = view.calendar.theme; 58359 var title = this.getCellDate(row, col).format(this.opt('dayPopoverFormat'));
58360 var content = $('<div class="fc-header ' + theme.getClass('popoverHeader') + '">' + 58361 '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' + 58362 '<span class="fc-title">' + 58363 util_1.htmlEscape(title) + 58364 '</span>' + 58365 '<div class="fc-clear"/>' + 58366 '</div>' + 58367 '<div class="fc-body ' + theme.getClass('popoverContent') + '">' + 58368 '<div class="fc-event-container"></div>' + 58369 '</div>'); 58370 var segContainer = content.find('.fc-event-container'); 58371 var i; 58372 // render each seg's `el` and only return the visible segs 58373 segs = this.eventRenderer.renderFgSegEls(segs, true); // disableResizing=true 58374 this.popoverSegs = segs; 58375 for (i = 0; i < segs.length; i++) { 58376 // because segments in the popover are not part of a grid coordinate system, provide a hint to any 58377 // grids that want to do drag-n-drop about which cell it came from 58378 this.hitsNeeded(); 58379 segs[i].hit = this.getCellHit(row, col); 58380 this.hitsNotNeeded(); 58381 segContainer.append(segs[i].el); 58382 } 58383 return content; 58384 }; 58385 // Given the events within an array of segment objects, reslice them to be in a single day 58386 DayGrid.prototype.resliceDaySegs = function (segs, dayDate) { 58387 var dayStart = dayDate.clone(); 58388 var dayEnd = dayStart.clone().add(1, 'days'); 58389 var dayRange = new UnzonedRange_1.default(dayStart, dayEnd); 58390 var newSegs = []; 58391 var i; 58392 var seg; 58393 var slicedRange; 58394 for (i = 0; i < segs.length; i++) { 58395 seg = segs[i]; 58396 slicedRange = seg.footprint.componentFootprint.unzonedRange.intersect(dayRange); 58397 if (slicedRange) { 58398 newSegs.push($.extend({}, seg, { 58399 footprint: new EventFootprint_1.default(new ComponentFootprint_1.default(slicedRange, seg.footprint.componentFootprint.isAllDay), seg.footprint.eventDef, seg.footprint.eventInstance), 58400 isStart: seg.isStart && slicedRange.isStart, 58401 isEnd: seg.isEnd && slicedRange.isEnd 58402 })); 58403 } 58404 } 58405 // force an order because eventsToSegs doesn't guarantee one 58406 // TODO: research if still needed 58407 this.eventRenderer.sortEventSegs(newSegs); 58408 return newSegs; 58409 }; 58410 // Generates the text that should be inside a "more" link, given the number of events it represents 58411 DayGrid.prototype.getMoreLinkText = function (num) { 58412 var opt = this.opt('eventLimitText'); 58413 if (typeof opt === 'function') { 58414 return opt(num); 58415 } 58416 else { 58417 return '+' + num + ' ' + opt; 58418 } 58419 }; 58420 // Returns segments within a given cell. 58421 // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs. 58422 DayGrid.prototype.getCellSegs = function (row, col, startLevel) { 58423 var segMatrix = this.eventRenderer.rowStructs[row].segMatrix; 58424 var level = startLevel || 0; 58425 var segs = []; 58426 var seg; 58427 while (level < segMatrix.length) { 58428 seg = segMatrix[level][col]; 58429 if (seg) { 58430 segs.push(seg); 58431 } 58432 level++; 58433 } 58434 return segs; 58435 }; 58436 return DayGrid; 58437}(InteractiveDateComponent_1.default)); 58438exports.default = DayGrid; 58439DayGrid.prototype.eventRendererClass = DayGridEventRenderer_1.default; 58440DayGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default; 58441DayGrid.prototype.helperRendererClass = DayGridHelperRenderer_1.default; 58442DayGrid.prototype.fillRendererClass = DayGridFillRenderer_1.default; 58443StandardInteractionsMixin_1.default.mixInto(DayGrid); 58444DayTableMixin_1.default.mixInto(DayGrid); 58445 58446 58447/***/ }), 58448/* 62 */ 58449/***/ (function(module, exports, __webpack_require__) { 58450 58451Object.defineProperty(exports, "__esModule", { value: true }); 58452var tslib_1 = __webpack_require__(2); 58453var $ = __webpack_require__(3); 58454var util_1 = __webpack_require__(4); 58455var Scroller_1 = __webpack_require__(39); 58456var View_1 = __webpack_require__(41); 58457var BasicViewDateProfileGenerator_1 = __webpack_require__(228); 58458var DayGrid_1 = __webpack_require__(61); 58459/* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells. 58460----------------------------------------------------------------------------------------------------------------------*/ 58461// It is a manager for a DayGrid subcomponent, which does most of the heavy lifting. 58462// It is responsible for managing width/height. 58463var BasicView = /** @class */ (function (_super) { 58464 tslib_1.__extends(BasicView, _super); 58465 function BasicView(calendar, viewSpec) { 58466 var _this = _super.call(this, calendar, viewSpec) || this; 58467 _this.dayGrid = _this.instantiateDayGrid(); 58468 _this.dayGrid.isRigid = _this.hasRigidRows(); 58469 if (_this.opt('weekNumbers')) { 58470 if (_this.opt('weekNumbersWithinDays')) { 58471 _this.dayGrid.cellWeekNumbersVisible = true; 58472 _this.dayGrid.colWeekNumbersVisible = false; 58473 } 58474 else { 58475 _this.dayGrid.cellWeekNumbersVisible = false; 58476 _this.dayGrid.colWeekNumbersVisible = true; 58477 } 58478 } 58479 _this.addChild(_this.dayGrid); 58480 _this.scroller = new Scroller_1.default({ 58481 overflowX: 'hidden', 58482 overflowY: 'auto' 58483 }); 58484 return _this; 58485 } 58486 // Generates the DayGrid object this view needs. Draws from this.dayGridClass 58487 BasicView.prototype.instantiateDayGrid = function () { 58488 // generate a subclass on the fly with BasicView-specific behavior 58489 // TODO: cache this subclass 58490 var subclass = makeDayGridSubclass(this.dayGridClass); 58491 return new subclass(this); 58492 }; 58493 BasicView.prototype.executeDateRender = function (dateProfile) { 58494 this.dayGrid.breakOnWeeks = /year|month|week/.test(dateProfile.currentRangeUnit); 58495 _super.prototype.executeDateRender.call(this, dateProfile); 58496 }; 58497 BasicView.prototype.renderSkeleton = function () { 58498 var dayGridContainerEl; 58499 var dayGridEl; 58500 this.el.addClass('fc-basic-view').html(this.renderSkeletonHtml()); 58501 this.scroller.render(); 58502 dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container');
58503 dayGridEl = $('<div class="fc-day-grid" />').appendTo(dayGridContainerEl); 58504 this.el.find('.fc-body > tr > td').append(dayGridContainerEl); 58505 this.dayGrid.headContainerEl = this.el.find('.fc-head-container'); 58506 this.dayGrid.setElement(dayGridEl); 58507 }; 58508 BasicView.prototype.unrenderSkeleton = function () { 58509 this.dayGrid.removeElement(); 58510 this.scroller.destroy(); 58511 }; 58512 // Builds the HTML skeleton for the view. 58513 // The day-grid component will render inside of a container defined by this HTML. 58514 BasicView.prototype.renderSkeletonHtml = function () { 58515 var theme = this.calendar.theme; 58516 return '' + 58517 '<table class="' + theme.getClass('tableGrid') + '">' + 58518 (this.opt('columnHeader') ? 58519 '<thead class="fc-head">' + 58520 '<tr>' + 58521 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + 58522 '</tr>' + 58523 '</thead>' : 58524 '') + 58525 '<tbody class="fc-body">' + 58526 '<tr>' + 58527 '<td class="' + theme.getClass('widgetContent') + '"></td>' + 58528 '</tr>' + 58529 '</tbody>' + 58530 '</table>'; 58531 }; 58532 // Generates an HTML attribute string for setting the width of the week number column, if it is known 58533 BasicView.prototype.weekNumberStyleAttr = function () { 58534 if (this.weekNumberWidth != null) { 58535 return 'style="width:' + this.weekNumberWidth + 'px"'; 58536 } 58537 return ''; 58538 }; 58539 // Determines whether each row should have a constant height 58540 BasicView.prototype.hasRigidRows = function () { 58541 var eventLimit = this.opt('eventLimit'); 58542 return eventLimit && typeof eventLimit !== 'number'; 58543 }; 58544 /* Dimensions 58545 ------------------------------------------------------------------------------------------------------------------*/ 58546 // Refreshes the horizontal dimensions of the view 58547 BasicView.prototype.updateSize = function (totalHeight, isAuto, isResize) { 58548 var eventLimit = this.opt('eventLimit'); 58549 var headRowEl = this.dayGrid.headContainerEl.find('.fc-row'); 58550 var scrollerHeight; 58551 var scrollbarWidths; 58552 // hack to give the view some height prior to dayGrid's columns being rendered 58553 // TODO: separate setting height from scroller VS dayGrid. 58554 if (!this.dayGrid.rowEls) { 58555 if (!isAuto) { 58556 scrollerHeight = this.computeScrollerHeight(totalHeight); 58557 this.scroller.setHeight(scrollerHeight); 58558 } 58559 return; 58560 } 58561 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 58562 if (this.dayGrid.colWeekNumbersVisible) { 58563 // Make sure all week number cells running down the side have the same width. 58564 // Record the width for cells created later. 58565 this.weekNumberWidth = util_1.matchCellWidths(this.el.find('.fc-week-number')); 58566 } 58567 // reset all heights to be natural 58568 this.scroller.clear(); 58569 util_1.uncompensateScroll(headRowEl); 58570 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed 58571 // is the event limit a constant level number? 58572 if (eventLimit && typeof eventLimit === 'number') { 58573 this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after 58574 } 58575 // distribute the height to the rows 58576 // (totalHeight is a "recommended" value if isAuto) 58577 scrollerHeight = this.computeScrollerHeight(totalHeight); 58578 this.setGridHeight(scrollerHeight, isAuto); 58579 // is the event limit dynamically calculated? 58580 if (eventLimit && typeof eventLimit !== 'number') { 58581 this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set 58582 } 58583 if (!isAuto) { 58584 this.scroller.setHeight(scrollerHeight);
58585 scrollbarWidths = this.scroller.getScrollbarWidths(); 58586 if (scrollbarWidths.left || scrollbarWidths.right) { 58587 util_1.compensateScroll(headRowEl, scrollbarWidths); 58588 // doing the scrollbar compensation might have created text overflow which created more height. redo 58589 scrollerHeight = this.computeScrollerHeight(totalHeight); 58590 this.scroller.setHeight(scrollerHeight); 58591 } 58592 // guarantees the same scrollbar widths 58593 this.scroller.lockOverflow(scrollbarWidths); 58594 } 58595 }; 58596 // given a desired total height of the view, returns what the height of the scroller should be 58597 BasicView.prototype.computeScrollerHeight = function (totalHeight) { 58598 return totalHeight - 58599 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 58600 }; 58601 // Sets the height of just the DayGrid component in this view 58602 BasicView.prototype.setGridHeight = function (height, isAuto) { 58603 if (isAuto) { 58604 util_1.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding 58605 } 58606 else { 58607 util_1.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows 58608 } 58609 }; 58610 /* Scroll 58611 ------------------------------------------------------------------------------------------------------------------*/ 58612 BasicView.prototype.computeInitialDateScroll = function () { 58613 return { top: 0 }; 58614 }; 58615 BasicView.prototype.queryDateScroll = function () { 58616 return { top: this.scroller.getScrollTop() }; 58617 }; 58618 BasicView.prototype.applyDateScroll = function (scroll) { 58619 if (scroll.top !== undefined) { 58620 this.scroller.setScrollTop(scroll.top); 58621 } 58622 }; 58623 return BasicView; 58624}(View_1.default)); 58625exports.default = BasicView; 58626BasicView.prototype.dateProfileGeneratorClass = BasicViewDateProfileGenerator_1.default; 58627BasicView.prototype.dayGridClass = DayGrid_1.default; 58628// customize the rendering behavior of BasicView's dayGrid 58629function makeDayGridSubclass(SuperClass) { 58630 return /** @class */ (function (_super) { 58631 tslib_1.__extends(SubClass, _super); 58632 function SubClass() { 58633 var _this = _super !== null && _super.apply(this, arguments) || this; 58634 _this.colWeekNumbersVisible = false; // display week numbers along the side? 58635 return _this; 58636 } 58637 // Generates the HTML that will go before the day-of week header cells 58638 SubClass.prototype.renderHeadIntroHtml = function () { 58639 var view = this.view; 58640 if (this.colWeekNumbersVisible) { 58641 return '' + 58642 '<th class="fc-week-number ' + view.calendar.theme.getClass('widgetHeader') + '" ' + view.weekNumberStyleAttr() + '>' + 58643 '<span>' + // needed for matchCellWidths 58644 util_1.htmlEscape(this.opt('weekNumberTitle')) + 58645 '</span>' + 58646 '</th>'; 58647 } 58648 return ''; 58649 }; 58650 // Generates the HTML that will go before content-skeleton cells that display the day/week numbers 58651 SubClass.prototype.renderNumberIntroHtml = function (row) { 58652 var view = this.view; 58653 var weekStart = this.getCellDate(row, 0); 58654 if (this.colWeekNumbersVisible) { 58655 return '' + 58656 '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '>' + 58657 view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths 58658 { date: weekStart, type: 'week', forceOff: this.colCnt === 1 }, weekStart.format('w') // inner HTML 58659 ) + 58660 '</td>'; 58661 } 58662 return ''; 58663 }; 58664 // Generates the HTML that goes before the day bg cells for each day-row 58665 SubClass.prototype.renderBgIntroHtml = function () { 58666 var view = this.view; 58667 if (this.colWeekNumbersVisible) { 58668 return '<td class="fc-week-number ' + view.calendar.theme.getClass('widgetContent') + '" ' + 58669 view.weekNumberStyleAttr() + '></td>'; 58670 } 58671 return ''; 58672 }; 58673 // Generates the HTML that goes before every other type of row generated by DayGrid. 58674 // Affects helper-skeleton and highlight-skeleton rows. 58675 SubClass.prototype.renderIntroHtml = function () { 58676 var view = this.view; 58677 if (this.colWeekNumbersVisible) { 58678 return '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '></td>'; 58679 } 58680 return ''; 58681 }; 58682 SubClass.prototype.getIsNumbersVisible = function () { 58683 return DayGrid_1.default.prototype.getIsNumbersVisible.apply(this, arguments) || this.colWeekNumbersVisible; 58684 }; 58685 return SubClass; 58686 }(SuperClass)); 58687} 58688 58689 58690/***/ }), 58691/* 63 */, 58692/* 64 */, 58693/* 65 */, 58694/* 66 */, 58695/* 67 */, 58696/* 68 */, 58697/* 69 */, 58698/* 70 */, 58699/* 71 */, 58700/* 72 */, 58701/* 73 */, 58702/* 74 */, 58703/* 75 */, 58704/* 76 */, 58705/* 77 */, 58706/* 78 */, 58707/* 79 */, 58708/* 80 */, 58709/* 81 */, 58710/* 82 */, 58711/* 83 */, 58712/* 84 */, 58713/* 85 */, 58714/* 86 */, 58715/* 87 */, 58716/* 88 */, 58717/* 89 */, 58718/* 90 */, 58719/* 91 */, 58720/* 92 */, 58721/* 93 */, 58722/* 94 */, 58723/* 95 */, 58724/* 96 */, 58725/* 97 */, 58726/* 98 */, 58727/* 99 */, 58728/* 100 */, 58729/* 101 */, 58730/* 102 */, 58731/* 103 */, 58732/* 104 */, 58733/* 105 */, 58734/* 106 */, 58735/* 107 */, 58736/* 108 */, 58737/* 109 */, 58738/* 110 */, 58739/* 111 */, 58740/* 112 */, 58741/* 113 */, 58742/* 114 */, 58743/* 115 */, 58744/* 116 */, 58745/* 117 */, 58746/* 118 */, 58747/* 119 */, 58748/* 120 */, 58749/* 121 */, 58750/* 122 */, 58751/* 123 */, 58752/* 124 */, 58753/* 125 */, 58754/* 126 */, 58755/* 127 */, 58756/* 128 */, 58757/* 129 */, 58758/* 130 */, 58759/* 131 */, 58760/* 132 */, 58761/* 133 */, 58762/* 134 */, 58763/* 135 */, 58764/* 136 */, 58765/* 137 */, 58766/* 138 */, 58767/* 139 */, 58768/* 140 */, 58769/* 141 */, 58770/* 142 */, 58771/* 143 */, 58772/* 144 */, 58773/* 145 */, 58774/* 146 */, 58775/* 147 */, 58776/* 148 */, 58777/* 149 */, 58778/* 150 */, 58779/* 151 */, 58780/* 152 */, 58781/* 153 */, 58782/* 154 */, 58783/* 155 */, 58784/* 156 */, 58785/* 157 */, 58786/* 158 */, 58787/* 159 */, 58788/* 160 */, 58789/* 161 */, 58790/* 162 */, 58791/* 163 */, 58792/* 164 */, 58793/* 165 */, 58794/* 166 */, 58795/* 167 */, 58796/* 168 */, 58797/* 169 */, 58798/* 170 */, 58799/* 171 */, 58800/* 172 */, 58801/* 173 */, 58802/* 174 */, 58803/* 175 */, 58804/* 176 */, 58805/* 177 */, 58806/* 178 */, 58807/* 179 */, 58808/* 180 */, 58809/* 181 */, 58810/* 182 */, 58811/* 183 */, 58812/* 184 */, 58813/* 185 */, 58814/* 186 */, 58815/* 187 */, 58816/* 188 */, 58817/* 189 */, 58818/* 190 */, 58819/* 191 */, 58820/* 192 */, 58821/* 193 */, 58822/* 194 */, 58823/* 195 */, 58824/* 196 */, 58825/* 197 */, 58826/* 198 */, 58827/* 199 */, 58828/* 200 */, 58829/* 201 */, 58830/* 202 */, 58831/* 203 */, 58832/* 204 */, 58833/* 205 */, 58834/* 206 */, 58835/* 207 */ 58836/***/ (function(module, exports, __webpack_require__) { 58837 58838Object.defineProperty(exports, "__esModule", { value: true });
58839var UnzonedRange_1 = __webpack_require__(5); 58840var ComponentFootprint_1 = __webpack_require__(12); 58841var EventDefParser_1 = __webpack_require__(49); 58842var EventSource_1 = __webpack_require__(6); 58843var util_1 = __webpack_require__(35); 58844var Constraints = /** @class */ (function () { 58845 function Constraints(eventManager, _calendar) { 58846 this.eventManager = eventManager; 58847 this._calendar = _calendar; 58848 } 58849 Constraints.prototype.opt = function (name) { 58850 return this._calendar.opt(name); 58851 }; 58852 /* 58853 determines if eventInstanceGroup is allowed, 58854 in relation to other EVENTS and business hours. 58855 */ 58856 Constraints.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) { 58857 var eventDef = eventInstanceGroup.getEventDef(); 58858 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); 58859 var i; 58860 var peerEventInstances = this.getPeerEventInstances(eventDef); 58861 var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange); 58862 var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges); 58863 var constraintVal = eventDef.getConstraint(); 58864 var overlapVal = eventDef.getOverlap(); 58865 var eventAllowFunc = this.opt('eventAllow'); 58866 for (i = 0; i < eventFootprints.length; i++) { 58867 if (!this.isFootprintAllowed(eventFootprints[i].componentFootprint, peerEventFootprints, constraintVal, overlapVal, eventFootprints[i].eventInstance)) { 58868 return false; 58869 } 58870 } 58871 if (eventAllowFunc) { 58872 for (i = 0; i < eventFootprints.length; i++) { 58873 if (eventAllowFunc(eventFootprints[i].componentFootprint.toLegacy(this._calendar), eventFootprints[i].getEventLegacy()) === false) { 58874 return false; 58875 } 58876 } 58877 } 58878 return true; 58879 }; 58880 Constraints.prototype.getPeerEventInstances = function (eventDef) { 58881 return this.eventManager.getEventInstancesWithoutId(eventDef.id); 58882 }; 58883 Constraints.prototype.isSelectionFootprintAllowed = function (componentFootprint) { 58884 var peerEventInstances = this.eventManager.getEventInstances(); 58885 var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange); 58886 var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges); 58887 var selectAllowFunc; 58888 if (this.isFootprintAllowed(componentFootprint, peerEventFootprints, this.opt('selectConstraint'), this.opt('selectOverlap'))) { 58889 selectAllowFunc = this.opt('selectAllow'); 58890 if (selectAllowFunc) { 58891 return selectAllowFunc(componentFootprint.toLegacy(this._calendar)) !== false; 58892 } 58893 else { 58894 return true; 58895 } 58896 } 58897 return false; 58898 }; 58899 Constraints.prototype.isFootprintAllowed = function (componentFootprint, peerEventFootprints, constraintVal, overlapVal, subjectEventInstance // optional 58900 ) { 58901 var constraintFootprints; // ComponentFootprint[] 58902 var overlapEventFootprints; // EventFootprint[] 58903 if (constraintVal != null) { 58904 constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay); 58905 if (!this.isFootprintWithinConstraints(componentFootprint, constraintFootprints)) { 58906 return false; 58907 } 58908 } 58909 overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint); 58910 if (overlapVal === false) { 58911 if (overlapEventFootprints.length) { 58912 return false; 58913 } 58914 } 58915 else if (typeof overlapVal === 'function') { 58916 if (!isOverlapsAllowedByFunc(overlapEventFootprints, overlapVal, subjectEventInstance)) { 58917 return false; 58918 } 58919 } 58920 if (subjectEventInstance) { 58921 if (!isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance)) { 58922 return false; 58923 } 58924 } 58925 return true; 58926 }; 58927 // Constraint 58928 // ------------------------------------------------------------------------------------------------ 58929 Constraints.prototype.isFootprintWithinConstraints = function (componentFootprint, constraintFootprints) { 58930 var i; 58931 for (i = 0; i < constraintFootprints.length; i++) { 58932 if (this.footprintContainsFootprint(constraintFootprints[i], componentFootprint)) { 58933 return true; 58934 } 58935 } 58936 return false; 58937 }; 58938 Constraints.prototype.constraintValToFootprints = function (constraintVal, isAllDay) { 58939 var eventInstances; 58940 if (constraintVal === 'businessHours') { 58941 return this.buildCurrentBusinessFootprints(isAllDay); 58942 } 58943 else if (typeof constraintVal === 'object') { 58944 eventInstances = this.parseEventDefToInstances(constraintVal); // handles recurring events 58945 if (!eventInstances) { 58946 return this.parseFootprints(constraintVal); 58947 } 58948 else { 58949 return this.eventInstancesToFootprints(eventInstances); 58950 } 58951 } 58952 else if (constraintVal != null) { 58953 eventInstances = this.eventManager.getEventInstancesWithId(constraintVal); 58954 return this.eventInstancesToFootprints(eventInstances); 58955 } 58956 }; 58957 // returns ComponentFootprint[] 58958 // uses current view's range 58959 Constraints.prototype.buildCurrentBusinessFootprints = function (isAllDay) { 58960 var view = this._calendar.view; 58961 var businessHourGenerator = view.get('businessHourGenerator'); 58962 var unzonedRange = view.dateProfile.activeUnzonedRange; 58963 var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange); 58964 if (eventInstanceGroup) { 58965 return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances); 58966 } 58967 else { 58968 return []; 58969 } 58970 }; 58971 // conversion util 58972 Constraints.prototype.eventInstancesToFootprints = function (eventInstances) { 58973 var eventRanges = eventInstances.map(util_1.eventInstanceToEventRange); 58974 var eventFootprints = this.eventRangesToEventFootprints(eventRanges); 58975 return eventFootprints.map(util_1.eventFootprintToComponentFootprint); 58976 }; 58977 // Overlap 58978 // ------------------------------------------------------------------------------------------------ 58979 Constraints.prototype.collectOverlapEventFootprints = function (peerEventFootprints, targetFootprint) { 58980 var overlapEventFootprints = []; 58981 var i; 58982 for (i = 0; i < peerEventFootprints.length; i++) { 58983 if (this.footprintsIntersect(targetFootprint, peerEventFootprints[i].componentFootprint)) { 58984 overlapEventFootprints.push(peerEventFootprints[i]); 58985 } 58986 } 58987 return overlapEventFootprints; 58988 }; 58989 // Conversion: eventDefs -> eventInstances -> eventRanges -> eventFootprints -> componentFootprints 58990 // ------------------------------------------------------------------------------------------------ 58991 // NOTE: this might seem like repetitive code with the Grid class, however, this code is related to 58992 // constraints whereas the Grid code is related to rendering. Each approach might want to convert 58993 // eventRanges -> eventFootprints in a different way. Regardless, there are opportunities to make 58994 // this more DRY. 58995 /*
58996 Returns false on invalid input. 58997 */ 58998 Constraints.prototype.parseEventDefToInstances = function (eventInput) { 58999 var eventManager = this.eventManager; 59000 var eventDef = EventDefParser_1.default.parse(eventInput, new EventSource_1.default(this._calendar)); 59001 if (!eventDef) { 59002 return false; 59003 } 59004 return eventDef.buildInstances(eventManager.currentPeriod.unzonedRange); 59005 }; 59006 Constraints.prototype.eventRangesToEventFootprints = function (eventRanges) { 59007 var i; 59008 var eventFootprints = []; 59009 for (i = 0; i < eventRanges.length; i++) { 59010 eventFootprints.push.apply(// footprints 59011 eventFootprints, this.eventRangeToEventFootprints(eventRanges[i])); 59012 } 59013 return eventFootprints; 59014 }; 59015 Constraints.prototype.eventRangeToEventFootprints = function (eventRange) { 59016 return [util_1.eventRangeToEventFootprint(eventRange)]; 59017 }; 59018 /* 59019 Parses footprints directly. 59020 Very similar to EventDateProfile::parse :( 59021 */ 59022 Constraints.prototype.parseFootprints = function (rawInput) { 59023 var start; 59024 var end; 59025 if (rawInput.start) { 59026 start = this._calendar.moment(rawInput.start); 59027 if (!start.isValid()) { 59028 start = null; 59029 } 59030 } 59031 if (rawInput.end) { 59032 end = this._calendar.moment(rawInput.end); 59033 if (!end.isValid()) { 59034 end = null; 59035 } 59036 } 59037 return [ 59038 new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), (start && !start.hasTime()) || (end && !end.hasTime()) // isAllDay 59039 ) 59040 ]; 59041 }; 59042 // Footprint Utils 59043 // ---------------------------------------------------------------------------------------- 59044 Constraints.prototype.footprintContainsFootprint = function (outerFootprint, innerFootprint) { 59045 return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange); 59046 }; 59047 Constraints.prototype.footprintsIntersect = function (footprint0, footprint1) { 59048 return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange); 59049 }; 59050 return Constraints; 59051}()); 59052exports.default = Constraints; 59053// optional subjectEventInstance 59054function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEventInstance) { 59055 var i; 59056 for (i = 0; i < overlapEventFootprints.length; i++) { 59057 if (!overlapFunc(overlapEventFootprints[i].eventInstance.toLegacy(), subjectEventInstance ? subjectEventInstance.toLegacy() : null)) { 59058 return false; 59059 } 59060 } 59061 return true; 59062} 59063function isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance) { 59064 var subjectLegacyInstance = subjectEventInstance.toLegacy(); 59065 var i; 59066 var overlapEventInstance; 59067 var overlapEventDef; 59068 var overlapVal; 59069 for (i = 0; i < overlapEventFootprints.length; i++) { 59070 overlapEventInstance = overlapEventFootprints[i].eventInstance; 59071 overlapEventDef = overlapEventInstance.def; 59072 // don't need to pass in calendar, because don't want to consider global eventOverlap property, 59073 // because we already considered that earlier in the process. 59074 overlapVal = overlapEventDef.getOverlap(); 59075 if (overlapVal === false) { 59076 return false; 59077 } 59078 else if (typeof overlapVal === 'function') { 59079 if (!overlapVal(overlapEventInstance.toLegacy(), subjectLegacyInstance)) { 59080 return false; 59081 } 59082 } 59083 } 59084 return true; 59085} 59086 59087 59088/***/ }), 59089/* 208 */ 59090/***/ (function(module, exports, __webpack_require__) { 59091 59092/* 59093USAGE: 59094 import { default as ParsableModelMixin, ParsableModelInterface } from './ParsableModelMixin' 59095in class: 59096 applyProps: ParsableModelInterface['applyProps'] 59097 applyManualStandardProps: ParsableModelInterface['applyManualStandardProps'] 59098 applyMiscProps: ParsableModelInterface['applyMiscProps'] 59099 isStandardProp: ParsableModelInterface['isStandardProp'] 59100 static defineStandardProps = ParsableModelMixin.defineStandardProps 59101 static copyVerbatimStandardProps = ParsableModelMixin.copyVerbatimStandardProps 59102after class: 59103 ParsableModelMixin.mixInto(TheClass) 59104*/ 59105Object.defineProperty(exports, "__esModule", { value: true });
59106var tslib_1 = __webpack_require__(2); 59107var util_1 = __webpack_require__(4); 59108var Mixin_1 = __webpack_require__(14); 59109var ParsableModelMixin = /** @class */ (function (_super) { 59110 tslib_1.__extends(ParsableModelMixin, _super); 59111 function ParsableModelMixin() { 59112 return _super !== null && _super.apply(this, arguments) || this; 59113 } 59114 ParsableModelMixin.defineStandardProps = function (propDefs) { 59115 var proto = this.prototype; 59116 if (!proto.hasOwnProperty('standardPropMap')) { 59117 proto.standardPropMap = Object.create(proto.standardPropMap); 59118 } 59119 util_1.copyOwnProps(propDefs, proto.standardPropMap); 59120 }; 59121 ParsableModelMixin.copyVerbatimStandardProps = function (src, dest) { 59122 var map = this.prototype.standardPropMap; 59123 var propName; 59124 for (propName in map) { 59125 if (src[propName] != null && // in the src object? 59126 map[propName] === true // false means "copy verbatim" 59127 ) { 59128 dest[propName] = src[propName]; 59129 } 59130 } 59131 }; 59132 /* 59133 Returns true/false for success. 59134 Meant to be only called ONCE, at object creation. 59135 */ 59136 ParsableModelMixin.prototype.applyProps = function (rawProps) { 59137 var standardPropMap = this.standardPropMap; 59138 var manualProps = {}; 59139 var miscProps = {}; 59140 var propName; 59141 for (propName in rawProps) { 59142 if (standardPropMap[propName] === true) { 59143 this[propName] = rawProps[propName]; 59144 } 59145 else if (standardPropMap[propName] === false) { 59146 manualProps[propName] = rawProps[propName]; 59147 } 59148 else { 59149 miscProps[propName] = rawProps[propName]; 59150 } 59151 } 59152 this.applyMiscProps(miscProps); 59153 return this.applyManualStandardProps(manualProps); 59154 }; 59155 /* 59156 If subclasses override, they must call this supermethod and return the boolean response. 59157 Meant to be only called ONCE, at object creation. 59158 */ 59159 ParsableModelMixin.prototype.applyManualStandardProps = function (rawProps) { 59160 return true; 59161 }; 59162 /* 59163 Can be called even after initial object creation. 59164 */ 59165 ParsableModelMixin.prototype.applyMiscProps = function (rawProps) { 59166 // subclasses can implement 59167 }; 59168 /* 59169 TODO: why is this a method when defineStandardProps is static 59170 */ 59171 ParsableModelMixin.prototype.isStandardProp = function (propName) { 59172 return propName in this.standardPropMap; 59173 }; 59174 return ParsableModelMixin; 59175}(Mixin_1.default)); 59176exports.default = ParsableModelMixin; 59177ParsableModelMixin.prototype.standardPropMap = {}; // will be cloned by defineStandardProps 59178 59179 59180/***/ }), 59181/* 209 */ 59182/***/ (function(module, exports) { 59183 59184Object.defineProperty(exports, "__esModule", { value: true }); 59185var EventInstance = /** @class */ (function () { 59186 function EventInstance(def, dateProfile) { 59187 this.def = def; 59188 this.dateProfile = dateProfile; 59189 } 59190 EventInstance.prototype.toLegacy = function () { 59191 var dateProfile = this.dateProfile; 59192 var obj = this.def.toLegacy(); 59193 obj.start = dateProfile.start.clone(); 59194 obj.end = dateProfile.end ? dateProfile.end.clone() : null; 59195 return obj; 59196 }; 59197 return EventInstance; 59198}()); 59199exports.default = EventInstance; 59200 59201 59202/***/ }), 59203/* 210 */ 59204/***/ (function(module, exports, __webpack_require__) { 59205 59206Object.defineProperty(exports, "__esModule", { value: true }); 59207var tslib_1 = __webpack_require__(2); 59208var $ = __webpack_require__(3); 59209var moment = __webpack_require__(0); 59210var EventDef_1 = __webpack_require__(34); 59211var EventInstance_1 = __webpack_require__(209); 59212var EventDateProfile_1 = __webpack_require__(17); 59213var RecurringEventDef = /** @class */ (function (_super) { 59214 tslib_1.__extends(RecurringEventDef, _super); 59215 function RecurringEventDef() { 59216 return _super !== null && _super.apply(this, arguments) || this; 59217 } 59218 RecurringEventDef.prototype.isAllDay = function () { 59219 return !this.startTime && !this.endTime; 59220 }; 59221 RecurringEventDef.prototype.buildInstances = function (unzonedRange) { 59222 var calendar = this.source.calendar; 59223 var unzonedDate = unzonedRange.getStart(); 59224 var unzonedEnd = unzonedRange.getEnd(); 59225 var zonedDayStart; 59226 var instanceStart; 59227 var instanceEnd; 59228 var instances = []; 59229 while (unzonedDate.isBefore(unzonedEnd)) { 59230 // if everyday, or this particular day-of-week 59231 if (!this.dowHash || this.dowHash[unzonedDate.day()]) { 59232 zonedDayStart = calendar.applyTimezone(unzonedDate); 59233 instanceStart = zonedDayStart.clone(); 59234 instanceEnd = null; 59235 if (this.startTime) { 59236 instanceStart.time(this.startTime); 59237 } 59238 else { 59239 instanceStart.stripTime(); 59240 } 59241 if (this.endTime) { 59242 instanceEnd = zonedDayStart.clone().time(this.endTime); 59243 } 59244 instances.push(new EventInstance_1.default(this, // definition 59245 new EventDateProfile_1.default(instanceStart, instanceEnd, calendar))); 59246 } 59247 unzonedDate.add(1, 'days'); 59248 } 59249 return instances; 59250 }; 59251 RecurringEventDef.prototype.setDow = function (dowNumbers) { 59252 if (!this.dowHash) { 59253 this.dowHash = {}; 59254 } 59255 for (var i = 0; i < dowNumbers.length; i++) { 59256 this.dowHash[dowNumbers[i]] = true; 59257 } 59258 }; 59259 RecurringEventDef.prototype.clone = function () { 59260 var def = _super.prototype.clone.call(this); 59261 if (def.startTime) { 59262 def.startTime = moment.duration(this.startTime); 59263 } 59264 if (def.endTime) { 59265 def.endTime = moment.duration(this.endTime); 59266 } 59267 if (this.dowHash) { 59268 def.dowHash = $.extend({}, this.dowHash); 59269 } 59270 return def; 59271 }; 59272 return RecurringEventDef; 59273}(EventDef_1.default)); 59274exports.default = RecurringEventDef; 59275/* 59276HACK to work with TypeScript mixins 59277NOTE: if super-method fails, should still attempt to apply 59278*/ 59279RecurringEventDef.prototype.applyProps = function (rawProps) { 59280 var superSuccess = EventDef_1.default.prototype.applyProps.call(this, rawProps); 59281 if (rawProps.start) { 59282 this.startTime = moment.duration(rawProps.start); 59283 } 59284 if (rawProps.end) { 59285 this.endTime = moment.duration(rawProps.end); 59286 } 59287 if (rawProps.dow) { 59288 this.setDow(rawProps.dow); 59289 } 59290 return superSuccess; 59291}; 59292// Parsing 59293// --------------------------------------------------------------------------------------------------------------------- 59294RecurringEventDef.defineStandardProps({ 59295 start: false, 59296 end: false, 59297 dow: false 59298}); 59299 59300 59301/***/ }), 59302/* 211 */
59303/***/ (function(module, exports) { 59304 59305Object.defineProperty(exports, "__esModule", { value: true }); 59306var EventRange = /** @class */ (function () { 59307 function EventRange(unzonedRange, eventDef, eventInstance) { 59308 this.unzonedRange = unzonedRange; 59309 this.eventDef = eventDef; 59310 if (eventInstance) { 59311 this.eventInstance = eventInstance; 59312 } 59313 } 59314 return EventRange; 59315}()); 59316exports.default = EventRange; 59317 59318 59319/***/ }), 59320/* 212 */ 59321/***/ (function(module, exports, __webpack_require__) { 59322 59323Object.defineProperty(exports, "__esModule", { value: true }); 59324var $ = __webpack_require__(3); 59325var util_1 = __webpack_require__(35); 59326var EventInstanceGroup_1 = __webpack_require__(18); 59327var RecurringEventDef_1 = __webpack_require__(210); 59328var EventSource_1 = __webpack_require__(6); 59329var BUSINESS_HOUR_EVENT_DEFAULTS = { 59330 start: '09:00', 59331 end: '17:00', 59332 dow: [1, 2, 3, 4, 5], 59333 rendering: 'inverse-background' 59334 // classNames are defined in businessHoursSegClasses 59335}; 59336var BusinessHourGenerator = /** @class */ (function () { 59337 function BusinessHourGenerator(rawComplexDef, calendar) { 59338 this.rawComplexDef = rawComplexDef; 59339 this.calendar = calendar; 59340 } 59341 BusinessHourGenerator.prototype.buildEventInstanceGroup = function (isAllDay, unzonedRange) { 59342 var eventDefs = this.buildEventDefs(isAllDay); 59343 var eventInstanceGroup; 59344 if (eventDefs.length) { 59345 eventInstanceGroup = new EventInstanceGroup_1.default(util_1.eventDefsToEventInstances(eventDefs, unzonedRange)); 59346 // so that inverse-background rendering can happen even when no eventRanges in view 59347 eventInstanceGroup.explicitEventDef = eventDefs[0]; 59348 return eventInstanceGroup; 59349 } 59350 }; 59351 BusinessHourGenerator.prototype.buildEventDefs = function (isAllDay) { 59352 var rawComplexDef = this.rawComplexDef; 59353 var rawDefs = []; 59354 var requireDow = false; 59355 var i; 59356 var defs = []; 59357 if (rawComplexDef === true) { 59358 rawDefs = [{}]; // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim 59359 } 59360 else if ($.isPlainObject(rawComplexDef)) { 59361 rawDefs = [rawComplexDef]; 59362 } 59363 else if ($.isArray(rawComplexDef)) { 59364 rawDefs = rawComplexDef; 59365 requireDow = true; // every sub-definition NEEDS a day-of-week 59366 } 59367 for (i = 0; i < rawDefs.length; i++) { 59368 if (!requireDow || rawDefs[i].dow) { 59369 defs.push(this.buildEventDef(isAllDay, rawDefs[i])); 59370 } 59371 } 59372 return defs; 59373 }; 59374 BusinessHourGenerator.prototype.buildEventDef = function (isAllDay, rawDef) { 59375 var fullRawDef = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef); 59376 if (isAllDay) { 59377 fullRawDef.start = null; 59378 fullRawDef.end = null; 59379 } 59380 return RecurringEventDef_1.default.parse(fullRawDef, new EventSource_1.default(this.calendar) // dummy source 59381 ); 59382 }; 59383 return BusinessHourGenerator; 59384}()); 59385exports.default = BusinessHourGenerator; 59386 59387 59388/***/ }), 59389/* 213 */ 59390/***/ (function(module, exports, __webpack_require__) { 59391 59392Object.defineProperty(exports, "__esModule", { value: true }); 59393var tslib_1 = __webpack_require__(2); 59394var Theme_1 = __webpack_require__(19); 59395var StandardTheme = /** @class */ (function (_super) { 59396 tslib_1.__extends(StandardTheme, _super); 59397 function StandardTheme() { 59398 return _super !== null && _super.apply(this, arguments) || this; 59399 } 59400 return StandardTheme; 59401}(Theme_1.default)); 59402exports.default = StandardTheme; 59403StandardTheme.prototype.classes = { 59404 widget: 'fc-unthemed', 59405 widgetHeader: 'fc-widget-header', 59406 widgetContent: 'fc-widget-content', 59407 buttonGroup: 'fc-button-group', 59408 button: 'fc-button', 59409 cornerLeft: 'fc-corner-left', 59410 cornerRight: 'fc-corner-right', 59411 stateDefault: 'fc-state-default', 59412 stateActive: 'fc-state-active', 59413 stateDisabled: 'fc-state-disabled', 59414 stateHover: 'fc-state-hover', 59415 stateDown: 'fc-state-down', 59416 popoverHeader: 'fc-widget-header', 59417 popoverContent: 'fc-widget-content', 59418 // day grid 59419 headerRow: 'fc-widget-header', 59420 dayRow: 'fc-widget-content', 59421 // list view 59422 listView: 'fc-widget-content' 59423}; 59424StandardTheme.prototype.baseIconClass = 'fc-icon'; 59425StandardTheme.prototype.iconClasses = { 59426 close: 'fc-icon-x', 59427 prev: 'fc-icon-left-single-arrow', 59428 next: 'fc-icon-right-single-arrow', 59429 prevYear: 'fc-icon-left-double-arrow', 59430 nextYear: 'fc-icon-right-double-arrow' 59431}; 59432StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; 59433StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 59434StandardTheme.prototype.iconOverridePrefix = 'fc-icon-'; 59435 59436 59437/***/ }), 59438/* 214 */ 59439/***/ (function(module, exports, __webpack_require__) { 59440 59441Object.defineProperty(exports, "__esModule", { value: true });
59442var tslib_1 = __webpack_require__(2); 59443var Theme_1 = __webpack_require__(19); 59444var JqueryUiTheme = /** @class */ (function (_super) { 59445 tslib_1.__extends(JqueryUiTheme, _super); 59446 function JqueryUiTheme() { 59447 return _super !== null && _super.apply(this, arguments) || this; 59448 } 59449 return JqueryUiTheme; 59450}(Theme_1.default)); 59451exports.default = JqueryUiTheme; 59452JqueryUiTheme.prototype.classes = { 59453 widget: 'ui-widget', 59454 widgetHeader: 'ui-widget-header', 59455 widgetContent: 'ui-widget-content', 59456 buttonGroup: 'fc-button-group', 59457 button: 'ui-button', 59458 cornerLeft: 'ui-corner-left', 59459 cornerRight: 'ui-corner-right', 59460 stateDefault: 'ui-state-default', 59461 stateActive: 'ui-state-active', 59462 stateDisabled: 'ui-state-disabled', 59463 stateHover: 'ui-state-hover', 59464 stateDown: 'ui-state-down', 59465 today: 'ui-state-highlight', 59466 popoverHeader: 'ui-widget-header', 59467 popoverContent: 'ui-widget-content', 59468 // day grid 59469 headerRow: 'ui-widget-header', 59470 dayRow: 'ui-widget-content', 59471 // list view 59472 listView: 'ui-widget-content' 59473}; 59474JqueryUiTheme.prototype.baseIconClass = 'ui-icon'; 59475JqueryUiTheme.prototype.iconClasses = { 59476 close: 'ui-icon-closethick', 59477 prev: 'ui-icon-circle-triangle-w', 59478 next: 'ui-icon-circle-triangle-e', 59479 prevYear: 'ui-icon-seek-prev', 59480 nextYear: 'ui-icon-seek-next' 59481}; 59482JqueryUiTheme.prototype.iconOverrideOption = 'themeButtonIcons'; 59483JqueryUiTheme.prototype.iconOverrideCustomButtonOption = 'themeIcon'; 59484JqueryUiTheme.prototype.iconOverridePrefix = 'ui-icon-'; 59485 59486 59487/***/ }), 59488/* 215 */ 59489/***/ (function(module, exports, __webpack_require__) { 59490 59491Object.defineProperty(exports, "__esModule", { value: true }); 59492var tslib_1 = __webpack_require__(2); 59493var $ = __webpack_require__(3); 59494var Promise_1 = __webpack_require__(20); 59495var EventSource_1 = __webpack_require__(6); 59496var FuncEventSource = /** @class */ (function (_super) { 59497 tslib_1.__extends(FuncEventSource, _super); 59498 function FuncEventSource() { 59499 return _super !== null && _super.apply(this, arguments) || this; 59500 } 59501 FuncEventSource.parse = function (rawInput, calendar) { 59502 var rawProps; 59503 // normalize raw input 59504 if ($.isFunction(rawInput.events)) { 59505 rawProps = rawInput; 59506 } 59507 else if ($.isFunction(rawInput)) { 59508 rawProps = { events: rawInput }; 59509 } 59510 if (rawProps) { 59511 return EventSource_1.default.parse.call(this, rawProps, calendar); 59512 } 59513 return false; 59514 }; 59515 FuncEventSource.prototype.fetch = function (start, end, timezone) { 59516 var _this = this; 59517 this.calendar.pushLoading(); 59518 return Promise_1.default.construct(function (onResolve) { 59519 _this.func.call(_this.calendar, start.clone(), end.clone(), timezone, function (rawEventDefs) { 59520 _this.calendar.popLoading(); 59521 onResolve(_this.parseEventDefs(rawEventDefs)); 59522 }); 59523 }); 59524 }; 59525 FuncEventSource.prototype.getPrimitive = function () { 59526 return this.func; 59527 }; 59528 FuncEventSource.prototype.applyManualStandardProps = function (rawProps) { 59529 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); 59530 this.func = rawProps.events; 59531 return superSuccess; 59532 }; 59533 return FuncEventSource; 59534}(EventSource_1.default)); 59535exports.default = FuncEventSource; 59536FuncEventSource.defineStandardProps({ 59537 events: false // don't automatically transfer 59538}); 59539 59540 59541/***/ }), 59542/* 216 */ 59543/***/ (function(module, exports, __webpack_require__) { 59544 59545Object.defineProperty(exports, "__esModule", { value: true }); 59546var tslib_1 = __webpack_require__(2); 59547var $ = __webpack_require__(3); 59548var util_1 = __webpack_require__(4); 59549var Promise_1 = __webpack_require__(20); 59550var EventSource_1 = __webpack_require__(6); 59551var JsonFeedEventSource = /** @class */ (function (_super) { 59552 tslib_1.__extends(JsonFeedEventSource, _super); 59553 function JsonFeedEventSource() { 59554 return _super !== null && _super.apply(this, arguments) || this; 59555 } 59556 JsonFeedEventSource.parse = function (rawInput, calendar) { 59557 var rawProps; 59558 // normalize raw input 59559 if (typeof rawInput.url === 'string') { 59560 rawProps = rawInput; 59561 } 59562 else if (typeof rawInput === 'string') { 59563 rawProps = { url: rawInput }; 59564 } 59565 if (rawProps) { 59566 return EventSource_1.default.parse.call(this, rawProps, calendar); 59567 } 59568 return false; 59569 }; 59570 JsonFeedEventSource.prototype.fetch = function (start, end, timezone) { 59571 var _this = this; 59572 var ajaxSettings = this.ajaxSettings; 59573 var onSuccess = ajaxSettings.success; 59574 var onError = ajaxSettings.error;
59575 var requestParams = this.buildRequestParams(start, end, timezone); 59576 // todo: eventually handle the promise's then, 59577 // don't intercept success/error 59578 // tho will be a breaking API change 59579 this.calendar.pushLoading(); 59580 return Promise_1.default.construct(function (onResolve, onReject) { 59581 $.ajax($.extend({}, // destination 59582 JsonFeedEventSource.AJAX_DEFAULTS, ajaxSettings, { 59583 url: _this.url, 59584 data: requestParams, 59585 success: function (rawEventDefs, status, xhr) { 59586 var callbackRes; 59587 _this.calendar.popLoading(); 59588 if (rawEventDefs) { 59589 callbackRes = util_1.applyAll(onSuccess, _this, [rawEventDefs, status, xhr]); // redirect `this` 59590 if ($.isArray(callbackRes)) { 59591 rawEventDefs = callbackRes; 59592 } 59593 onResolve(_this.parseEventDefs(rawEventDefs)); 59594 } 59595 else { 59596 onReject(); 59597 } 59598 }, 59599 error: function (xhr, statusText, errorThrown) { 59600 _this.calendar.popLoading(); 59601 util_1.applyAll(onError, _this, [xhr, statusText, errorThrown]); // redirect `this` 59602 onReject(); 59603 } 59604 })); 59605 }); 59606 }; 59607 JsonFeedEventSource.prototype.buildRequestParams = function (start, end, timezone) { 59608 var calendar = this.calendar; 59609 var ajaxSettings = this.ajaxSettings; 59610 var startParam; 59611 var endParam; 59612 var timezoneParam;
59613 var customRequestParams; 59614 var params = {}; 59615 startParam = this.startParam; 59616 if (startParam == null) { 59617 startParam = calendar.opt('startParam'); 59618 } 59619 endParam = this.endParam; 59620 if (endParam == null) { 59621 endParam = calendar.opt('endParam'); 59622 } 59623 timezoneParam = this.timezoneParam; 59624 if (timezoneParam == null) { 59625 timezoneParam = calendar.opt('timezoneParam'); 59626 } 59627 // retrieve any outbound GET/POST $.ajax data from the options 59628 if ($.isFunction(ajaxSettings.data)) { 59629 // supplied as a function that returns a key/value object 59630 customRequestParams = ajaxSettings.data(); 59631 } 59632 else { 59633 // probably supplied as a straight key/value object 59634 customRequestParams = ajaxSettings.data || {}; 59635 } 59636 $.extend(params, customRequestParams); 59637 params[startParam] = start.format(); 59638 params[endParam] = end.format(); 59639 if (timezone && timezone !== 'local') { 59640 params[timezoneParam] = timezone; 59641 } 59642 return params; 59643 }; 59644 JsonFeedEventSource.prototype.getPrimitive = function () { 59645 return this.url; 59646 }; 59647 JsonFeedEventSource.prototype.applyMiscProps = function (rawProps) { 59648 this.ajaxSettings = rawProps; 59649 }; 59650 JsonFeedEventSource.AJAX_DEFAULTS = { 59651 dataType: 'json', 59652 cache: false 59653 }; 59654 return JsonFeedEventSource; 59655}(EventSource_1.default)); 59656exports.default = JsonFeedEventSource; 59657JsonFeedEventSource.defineStandardProps({ 59658 // automatically transfer (true)... 59659 url: true, 59660 startParam: true, 59661 endParam: true, 59662 timezoneParam: true 59663}); 59664 59665 59666/***/ }), 59667/* 217 */ 59668/***/ (function(module, exports, __webpack_require__) { 59669 59670Object.defineProperty(exports, "__esModule", { value: true }); 59671var EmitterMixin_1 = __webpack_require__(11); 59672var TaskQueue = /** @class */ (function () { 59673 function TaskQueue() { 59674 this.q = []; 59675 this.isPaused = false; 59676 this.isRunning = false; 59677 } 59678 TaskQueue.prototype.queue = function () { 59679 var args = []; 59680 for (var _i = 0; _i < arguments.length; _i++) { 59681 args[_i] = arguments[_i]; 59682 } 59683 this.q.push.apply(this.q, args); // append 59684 this.tryStart(); 59685 }; 59686 TaskQueue.prototype.pause = function () { 59687 this.isPaused = true; 59688 }; 59689 TaskQueue.prototype.resume = function () { 59690 this.isPaused = false; 59691 this.tryStart(); 59692 }; 59693 TaskQueue.prototype.getIsIdle = function () { 59694 return !this.isRunning && !this.isPaused; 59695 }; 59696 TaskQueue.prototype.tryStart = function () { 59697 if (!this.isRunning && this.canRunNext()) { 59698 this.isRunning = true; 59699 this.trigger('start'); 59700 this.runRemaining(); 59701 } 59702 }; 59703 TaskQueue.prototype.canRunNext = function () { 59704 return !this.isPaused && this.q.length; 59705 }; 59706 TaskQueue.prototype.runRemaining = function () { 59707 var _this = this; 59708 var task; 59709 var res; 59710 do { 59711 task = this.q.shift(); // always freshly reference q. might have been reassigned. 59712 res = this.runTask(task); 59713 if (res && res.then) { 59714 res.then(function () { 59715 if (_this.canRunNext()) { 59716 _this.runRemaining(); 59717 } 59718 }); 59719 return; // prevent marking as stopped 59720 } 59721 } while (this.canRunNext()); 59722 this.trigger('stop'); // not really a 'stop' ... more of a 'drained' 59723 this.isRunning = false; 59724 // if 'stop' handler added more tasks.... TODO: write test for this 59725 this.tryStart(); 59726 }; 59727 TaskQueue.prototype.runTask = function (task) { 59728 return task(); // task *is* the function, but subclasses can change the format of a task 59729 }; 59730 return TaskQueue; 59731}()); 59732exports.default = TaskQueue; 59733EmitterMixin_1.default.mixInto(TaskQueue); 59734 59735 59736/***/ }), 59737/* 218 */ 59738/***/ (function(module, exports, __webpack_require__) { 59739 59740Object.defineProperty(exports, "__esModule", { value: true });
59741var tslib_1 = __webpack_require__(2); 59742var TaskQueue_1 = __webpack_require__(217); 59743var RenderQueue = /** @class */ (function (_super) { 59744 tslib_1.__extends(RenderQueue, _super); 59745 function RenderQueue(waitsByNamespace) { 59746 var _this = _super.call(this) || this; 59747 _this.waitsByNamespace = waitsByNamespace || {}; 59748 return _this; 59749 } 59750 RenderQueue.prototype.queue = function (taskFunc, namespace, type) { 59751 var task = { 59752 func: taskFunc, 59753 namespace: namespace, 59754 type: type 59755 }; 59756 var waitMs; 59757 if (namespace) { 59758 waitMs = this.waitsByNamespace[namespace]; 59759 } 59760 if (this.waitNamespace) { 59761 if (namespace === this.waitNamespace && waitMs != null) { 59762 this.delayWait(waitMs); 59763 } 59764 else { 59765 this.clearWait(); 59766 this.tryStart(); 59767 } 59768 } 59769 if (this.compoundTask(task)) { 59770 if (!this.waitNamespace && waitMs != null) { 59771 this.startWait(namespace, waitMs); 59772 } 59773 else { 59774 this.tryStart(); 59775 } 59776 } 59777 }; 59778 RenderQueue.prototype.startWait = function (namespace, waitMs) { 59779 this.waitNamespace = namespace; 59780 this.spawnWait(waitMs); 59781 }; 59782 RenderQueue.prototype.delayWait = function (waitMs) { 59783 clearTimeout(this.waitId); 59784 this.spawnWait(waitMs); 59785 }; 59786 RenderQueue.prototype.spawnWait = function (waitMs) { 59787 var _this = this; 59788 this.waitId = setTimeout(function () { 59789 _this.waitNamespace = null; 59790 _this.tryStart(); 59791 }, waitMs); 59792 }; 59793 RenderQueue.prototype.clearWait = function () { 59794 if (this.waitNamespace) { 59795 clearTimeout(this.waitId); 59796 this.waitId = null; 59797 this.waitNamespace = null; 59798 } 59799 }; 59800 RenderQueue.prototype.canRunNext = function () { 59801 if (!_super.prototype.canRunNext.call(this)) { 59802 return false; 59803 } 59804 // waiting for a certain namespace to stop receiving tasks? 59805 if (this.waitNamespace) { 59806 var q = this.q; 59807 // if there was a different namespace task in the meantime, 59808 // that forces all previously-waiting tasks to suddenly execute.
59809 // TODO: find a way to do this in constant time. 59810 for (var i = 0; i < q.length; i++) { 59811 if (q[i].namespace !== this.waitNamespace) { 59812 return true; // allow execution 59813 } 59814 } 59815 return false; 59816 } 59817 return true; 59818 }; 59819 RenderQueue.prototype.runTask = function (task) { 59820 task.func(); 59821 }; 59822 RenderQueue.prototype.compoundTask = function (newTask) { 59823 var q = this.q; 59824 var shouldAppend = true; 59825 var i; 59826 var task; 59827 if (newTask.namespace && newTask.type === 'destroy') { 59828 // remove all init/add/remove ops with same namespace, regardless of order 59829 for (i = q.length - 1; i >= 0; i--) { 59830 task = q[i]; 59831 switch (task.type) { 59832 case 'init': 59833 shouldAppend = false; 59834 // the latest destroy is cancelled out by not doing the init 59835 /* falls through */ 59836 case 'add': 59837 /* falls through */ 59838 case 'remove': 59839 q.splice(i, 1); // remove task 59840 } 59841 } 59842 } 59843 if (shouldAppend) { 59844 q.push(newTask); 59845 } 59846 return shouldAppend; 59847 }; 59848 return RenderQueue; 59849}(TaskQueue_1.default)); 59850exports.default = RenderQueue; 59851 59852 59853/***/ }), 59854/* 219 */ 59855/***/ (function(module, exports, __webpack_require__) { 59856 59857Object.defineProperty(exports, "__esModule", { value: true }); 59858var tslib_1 = __webpack_require__(2); 59859var $ = __webpack_require__(3); 59860var moment = __webpack_require__(0); 59861var util_1 = __webpack_require__(4); 59862var moment_ext_1 = __webpack_require__(10); 59863var date_formatting_1 = __webpack_require__(47); 59864var Component_1 = __webpack_require__(237); 59865var util_2 = __webpack_require__(35); 59866var DateComponent = /** @class */ (function (_super) { 59867 tslib_1.__extends(DateComponent, _super); 59868 function DateComponent(_view, _options) { 59869 var _this = _super.call(this) || this; 59870 _this.isRTL = false; // frequently accessed options 59871 _this.hitsNeededDepth = 0; // necessary because multiple callers might need the same hits 59872 _this.hasAllDayBusinessHours = false; // TODO: unify with largeUnit and isTimeScale? 59873 _this.isDatesRendered = false; 59874 // hack to set options prior to the this.opt calls 59875 if (_view) { 59876 _this['view'] = _view; 59877 } 59878 if (_options) { 59879 _this['options'] = _options; 59880 } 59881 _this.uid = String(DateComponent.guid++); 59882 _this.childrenByUid = {}; 59883 _this.nextDayThreshold = moment.duration(_this.opt('nextDayThreshold')); 59884 _this.isRTL = _this.opt('isRTL'); 59885 if (_this.fillRendererClass) { 59886 _this.fillRenderer = new _this.fillRendererClass(_this); 59887 } 59888 if (_this.eventRendererClass) { 59889 _this.eventRenderer = new _this.eventRendererClass(_this, _this.fillRenderer); 59890 } 59891 if (_this.helperRendererClass && _this.eventRenderer) { 59892 _this.helperRenderer = new _this.helperRendererClass(_this, _this.eventRenderer); 59893 } 59894 if (_this.businessHourRendererClass && _this.fillRenderer) { 59895 _this.businessHourRenderer = new _this.businessHourRendererClass(_this, _this.fillRenderer); 59896 } 59897 return _this; 59898 } 59899 DateComponent.prototype.addChild = function (child) { 59900 if (!this.childrenByUid[child.uid]) { 59901 this.childrenByUid[child.uid] = child; 59902 return true; 59903 } 59904 return false; 59905 }; 59906 DateComponent.prototype.removeChild = function (child) { 59907 if (this.childrenByUid[child.uid]) { 59908 delete this.childrenByUid[child.uid]; 59909 return true; 59910 } 59911 return false; 59912 }; 59913 // TODO: only do if isInDom? 59914 // TODO: make part of Component, along with children/batch-render system? 59915 DateComponent.prototype.updateSize = function (totalHeight, isAuto, isResize) { 59916 this.callChildren('updateSize', arguments); 59917 }; 59918 // Options 59919 // ----------------------------------------------------------------------------------------------------------------- 59920 DateComponent.prototype.opt = function (name) { 59921 return this._getView().opt(name); // default implementation 59922 }; 59923 DateComponent.prototype.publiclyTrigger = function () { 59924 var args = []; 59925 for (var _i = 0; _i < arguments.length; _i++) { 59926 args[_i] = arguments[_i]; 59927 }
59928 var calendar = this._getCalendar(); 59929 return calendar.publiclyTrigger.apply(calendar, args); 59930 }; 59931 DateComponent.prototype.hasPublicHandlers = function () { 59932 var args = []; 59933 for (var _i = 0; _i < arguments.length; _i++) { 59934 args[_i] = arguments[_i]; 59935 } 59936 var calendar = this._getCalendar(); 59937 return calendar.hasPublicHandlers.apply(calendar, args); 59938 }; 59939 // Date 59940 // ----------------------------------------------------------------------------------------------------------------- 59941 DateComponent.prototype.executeDateRender = function (dateProfile) { 59942 this.dateProfile = dateProfile; // for rendering 59943 this.renderDates(dateProfile); 59944 this.isDatesRendered = true; 59945 this.callChildren('executeDateRender', arguments); 59946 }; 59947 DateComponent.prototype.executeDateUnrender = function () { 59948 this.callChildren('executeDateUnrender', arguments); 59949 this.dateProfile = null; 59950 this.unrenderDates(); 59951 this.isDatesRendered = false; 59952 }; 59953 // date-cell content only 59954 DateComponent.prototype.renderDates = function (dateProfile) { 59955 // subclasses should implement 59956 }; 59957 // date-cell content only 59958 DateComponent.prototype.unrenderDates = function () { 59959 // subclasses should override 59960 }; 59961 // Now-Indicator 59962 // ----------------------------------------------------------------------------------------------------------------- 59963 // Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator 59964 // should be refreshed. If something falsy is returned, no time indicator is rendered at all. 59965 DateComponent.prototype.getNowIndicatorUnit = function () { 59966 // subclasses should implement 59967 }; 59968 // Renders a current time indicator at the given datetime 59969 DateComponent.prototype.renderNowIndicator = function (date) { 59970 this.callChildren('renderNowIndicator', arguments); 59971 }; 59972 // Undoes the rendering actions from renderNowIndicator 59973 DateComponent.prototype.unrenderNowIndicator = function () { 59974 this.callChildren('unrenderNowIndicator', arguments); 59975 }; 59976 // Business Hours 59977 // --------------------------------------------------------------------------------------------------------------- 59978 DateComponent.prototype.renderBusinessHours = function (businessHourGenerator) { 59979 if (this.businessHourRenderer) { 59980 this.businessHourRenderer.render(businessHourGenerator); 59981 } 59982 this.callChildren('renderBusinessHours', arguments); 59983 }; 59984 // Unrenders previously-rendered business-hours 59985 DateComponent.prototype.unrenderBusinessHours = function () { 59986 this.callChildren('unrenderBusinessHours', arguments); 59987 if (this.businessHourRenderer) { 59988 this.businessHourRenderer.unrender(); 59989 } 59990 }; 59991 // Event Displaying 59992 // ----------------------------------------------------------------------------------------------------------------- 59993 DateComponent.prototype.executeEventRender = function (eventsPayload) { 59994 if (this.eventRenderer) { 59995 this.eventRenderer.rangeUpdated(); // poorly named now 59996 this.eventRenderer.render(eventsPayload); 59997 } 59998 else if (this['renderEvents']) { 59999 this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload)); 60000 } 60001 this.callChildren('executeEventRender', arguments); 60002 }; 60003 DateComponent.prototype.executeEventUnrender = function () { 60004 this.callChildren('executeEventUnrender', arguments); 60005 if (this.eventRenderer) { 60006 this.eventRenderer.unrender(); 60007 } 60008 else if (this['destroyEvents']) { 60009 this['destroyEvents'](); 60010 } 60011 }; 60012 DateComponent.prototype.getBusinessHourSegs = function () { 60013 var segs = this.getOwnBusinessHourSegs(); 60014 this.iterChildren(function (child) { 60015 segs.push.apply(segs, child.getBusinessHourSegs()); 60016 }); 60017 return segs; 60018 }; 60019 DateComponent.prototype.getOwnBusinessHourSegs = function () { 60020 if (this.businessHourRenderer) { 60021 return this.businessHourRenderer.getSegs(); 60022 } 60023 return []; 60024 }; 60025 DateComponent.prototype.getEventSegs = function () { 60026 var segs = this.getOwnEventSegs(); 60027 this.iterChildren(function (child) { 60028 segs.push.apply(segs, child.getEventSegs()); 60029 }); 60030 return segs; 60031 }; 60032 DateComponent.prototype.getOwnEventSegs = function () { 60033 if (this.eventRenderer) { 60034 return this.eventRenderer.getSegs(); 60035 } 60036 return []; 60037 }; 60038 // Event Rendering Triggering 60039 // ----------------------------------------------------------------------------------------------------------------- 60040 DateComponent.prototype.triggerAfterEventsRendered = function () { 60041 this.triggerAfterEventSegsRendered(this.getEventSegs()); 60042 this.publiclyTrigger('eventAfterAllRender', { 60043 context: this, 60044 args: [this] 60045 }); 60046 }; 60047 DateComponent.prototype.triggerAfterEventSegsRendered = function (segs) { 60048 var _this = this; 60049 // an optimization, because getEventLegacy is expensive 60050 if (this.hasPublicHandlers('eventAfterRender')) {
60051 segs.forEach(function (seg) { 60052 var legacy; 60053 if (seg.el) { 60054 legacy = seg.footprint.getEventLegacy(); 60055 _this.publiclyTrigger('eventAfterRender', { 60056 context: legacy, 60057 args: [legacy, seg.el, _this] 60058 }); 60059 } 60060 }); 60061 } 60062 }; 60063 DateComponent.prototype.triggerBeforeEventsDestroyed = function () { 60064 this.triggerBeforeEventSegsDestroyed(this.getEventSegs()); 60065 }; 60066 DateComponent.prototype.triggerBeforeEventSegsDestroyed = function (segs) { 60067 var _this = this; 60068 if (this.hasPublicHandlers('eventDestroy')) { 60069 segs.forEach(function (seg) { 60070 var legacy; 60071 if (seg.el) { 60072 legacy = seg.footprint.getEventLegacy(); 60073 _this.publiclyTrigger('eventDestroy', { 60074 context: legacy, 60075 args: [legacy, seg.el, _this] 60076 }); 60077 } 60078 }); 60079 } 60080 }; 60081 // Event Rendering Utils 60082 // ----------------------------------------------------------------------------------------------------------------- 60083 // Hides all rendered event segments linked to the given event 60084 // RECURSIVE with subcomponents 60085 DateComponent.prototype.showEventsWithId = function (eventDefId) { 60086 this.getEventSegs().forEach(function (seg) { 60087 if (seg.footprint.eventDef.id === eventDefId && 60088 seg.el // necessary? 60089 ) { 60090 seg.el.css('visibility', ''); 60091 } 60092 }); 60093 this.callChildren('showEventsWithId', arguments); 60094 }; 60095 // Shows all rendered event segments linked to the given event 60096 // RECURSIVE with subcomponents 60097 DateComponent.prototype.hideEventsWithId = function (eventDefId) { 60098 this.getEventSegs().forEach(function (seg) { 60099 if (seg.footprint.eventDef.id === eventDefId && 60100 seg.el // necessary? 60101 ) { 60102 seg.el.css('visibility', 'hidden'); 60103 } 60104 }); 60105 this.callChildren('hideEventsWithId', arguments); 60106 }; 60107 // Drag-n-Drop Rendering (for both events and external elements) 60108 // --------------------------------------------------------------------------------------------------------------- 60109 // Renders a visual indication of a event or external-element drag over the given drop zone. 60110 // If an external-element, seg will be `null`. 60111 // Must return elements used for any mock events. 60112 DateComponent.prototype.renderDrag = function (eventFootprints, seg, isTouch) { 60113 var renderedHelper = false; 60114 this.iterChildren(function (child) { 60115 if (child.renderDrag(eventFootprints, seg, isTouch)) { 60116 renderedHelper = true; 60117 } 60118 }); 60119 return renderedHelper; 60120 }; 60121 // Unrenders a visual indication of an event or external-element being dragged. 60122 DateComponent.prototype.unrenderDrag = function () { 60123 this.callChildren('unrenderDrag', arguments); 60124 }; 60125 // Event Resizing 60126 // --------------------------------------------------------------------------------------------------------------- 60127 // Renders a visual indication of an event being resized. 60128 DateComponent.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { 60129 this.callChildren('renderEventResize', arguments); 60130 }; 60131 // Unrenders a visual indication of an event being resized. 60132 DateComponent.prototype.unrenderEventResize = function () { 60133 this.callChildren('unrenderEventResize', arguments); 60134 }; 60135 // Selection 60136 // --------------------------------------------------------------------------------------------------------------- 60137 // Renders a visual indication of the selection 60138 // TODO: rename to `renderSelection` after legacy is gone 60139 DateComponent.prototype.renderSelectionFootprint = function (componentFootprint) { 60140 this.renderHighlight(componentFootprint); 60141 this.callChildren('renderSelectionFootprint', arguments); 60142 }; 60143 // Unrenders a visual indication of selection 60144 DateComponent.prototype.unrenderSelection = function () { 60145 this.unrenderHighlight(); 60146 this.callChildren('unrenderSelection', arguments); 60147 }; 60148 // Highlight 60149 // --------------------------------------------------------------------------------------------------------------- 60150 // Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data) 60151 DateComponent.prototype.renderHighlight = function (componentFootprint) { 60152 if (this.fillRenderer) { 60153 this.fillRenderer.renderFootprint('highlight', componentFootprint, { 60154 getClasses: function () { 60155 return ['fc-highlight']; 60156 } 60157 }); 60158 } 60159 this.callChildren('renderHighlight', arguments); 60160 }; 60161 // Unrenders the emphasis on a date range 60162 DateComponent.prototype.unrenderHighlight = function () { 60163 if (this.fillRenderer) { 60164 this.fillRenderer.unrender('highlight'); 60165 } 60166 this.callChildren('unrenderHighlight', arguments); 60167 }; 60168 // Hit Areas 60169 // --------------------------------------------------------------------------------------------------------------- 60170 // just because all DateComponents support this interface
60171 // doesn't mean they need to have their own internal coord system. they can defer to sub-components. 60172 DateComponent.prototype.hitsNeeded = function () { 60173 if (!(this.hitsNeededDepth++)) { 60174 this.prepareHits(); 60175 } 60176 this.callChildren('hitsNeeded', arguments); 60177 }; 60178 DateComponent.prototype.hitsNotNeeded = function () { 60179 if (this.hitsNeededDepth && !(--this.hitsNeededDepth)) { 60180 this.releaseHits(); 60181 } 60182 this.callChildren('hitsNotNeeded', arguments); 60183 }; 60184 DateComponent.prototype.prepareHits = function () { 60185 // subclasses can implement 60186 }; 60187 DateComponent.prototype.releaseHits = function () { 60188 // subclasses can implement 60189 }; 60190 // Given coordinates from the topleft of the document, return data about the date-related area underneath. 60191 // Can return an object with arbitrary properties (although top/right/left/bottom are encouraged). 60192 // Must have a `grid` property, a reference to this current grid. TODO: avoid this 60193 // The returned object will be processed by getHitFootprint and getHitEl. 60194 DateComponent.prototype.queryHit = function (leftOffset, topOffset) { 60195 var childrenByUid = this.childrenByUid; 60196 var uid; 60197 var hit; 60198 for (uid in childrenByUid) { 60199 hit = childrenByUid[uid].queryHit(leftOffset, topOffset); 60200 if (hit) { 60201 break; 60202 } 60203 } 60204 return hit; 60205 }; 60206 DateComponent.prototype.getSafeHitFootprint = function (hit) { 60207 var footprint = this.getHitFootprint(hit); 60208 if (!this.dateProfile.activeUnzonedRange.containsRange(footprint.unzonedRange)) { 60209 return null; 60210 } 60211 return footprint; 60212 }; 60213 DateComponent.prototype.getHitFootprint = function (hit) { 60214 // what about being abstract!? 60215 }; 60216 // Given position-level information about a date-related area within the grid, 60217 // should return a jQuery element that best represents it. passed to dayClick callback. 60218 DateComponent.prototype.getHitEl = function (hit) { 60219 // what about being abstract!? 60220 }; 60221 /* Converting eventRange -> eventFootprint 60222 ------------------------------------------------------------------------------------------------------------------*/ 60223 DateComponent.prototype.eventRangesToEventFootprints = function (eventRanges) { 60224 var eventFootprints = []; 60225 var i; 60226 for (i = 0; i < eventRanges.length; i++) { 60227 eventFootprints.push.apply(// append 60228 eventFootprints, this.eventRangeToEventFootprints(eventRanges[i])); 60229 } 60230 return eventFootprints; 60231 }; 60232 DateComponent.prototype.eventRangeToEventFootprints = function (eventRange) { 60233 return [util_2.eventRangeToEventFootprint(eventRange)]; 60234 }; 60235 /* Converting componentFootprint/eventFootprint -> segs 60236 ------------------------------------------------------------------------------------------------------------------*/ 60237 DateComponent.prototype.eventFootprintsToSegs = function (eventFootprints) { 60238 var segs = []; 60239 var i; 60240 for (i = 0; i < eventFootprints.length; i++) { 60241 segs.push.apply(segs, this.eventFootprintToSegs(eventFootprints[i])); 60242 } 60243 return segs; 60244 }; 60245 // Given an event's span (unzoned start/end and other misc data), and the event itself, 60246 // slices into segments and attaches event-derived properties to them. 60247 // eventSpan - { start, end, isStart, isEnd, otherthings... } 60248 DateComponent.prototype.eventFootprintToSegs = function (eventFootprint) { 60249 var unzonedRange = eventFootprint.componentFootprint.unzonedRange; 60250 var segs; 60251 var i; 60252 var seg; 60253 segs = this.componentFootprintToSegs(eventFootprint.componentFootprint); 60254 for (i = 0; i < segs.length; i++) { 60255 seg = segs[i]; 60256 if (!unzonedRange.isStart) { 60257 seg.isStart = false; 60258 } 60259 if (!unzonedRange.isEnd) { 60260 seg.isEnd = false; 60261 } 60262 seg.footprint = eventFootprint; 60263 // TODO: rename to seg.eventFootprint 60264 } 60265 return segs; 60266 }; 60267 DateComponent.prototype.componentFootprintToSegs = function (componentFootprint) { 60268 return []; 60269 }; 60270 // Utils 60271 // --------------------------------------------------------------------------------------------------------------- 60272 DateComponent.prototype.callChildren = function (methodName, args) { 60273 this.iterChildren(function (child) { 60274 child[methodName].apply(child, args); 60275 }); 60276 }; 60277 DateComponent.prototype.iterChildren = function (func) { 60278 var childrenByUid = this.childrenByUid; 60279 var uid; 60280 for (uid in childrenByUid) { 60281 func(childrenByUid[uid]); 60282 } 60283 }; 60284 DateComponent.prototype._getCalendar = function () { 60285 var t = this; 60286 return t.calendar || t.view.calendar; 60287 }; 60288 DateComponent.prototype._getView = function () { 60289 return this.view; 60290 }; 60291 DateComponent.prototype._getDateProfile = function () { 60292 return this._getView().get('dateProfile'); 60293 }; 60294 // Generates HTML for an anchor to another view into the calendar. 60295 // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings. 60296 // `gotoOptions` can either be a moment input, or an object with the form: 60297 // { date, type, forceOff } 60298 // `type` is a view-type like "day" or "week". default value is "day". 60299 // `attrs` and `innerHtml` are use to generate the rest of the HTML tag. 60300 DateComponent.prototype.buildGotoAnchorHtml = function (gotoOptions, attrs, innerHtml) { 60301 var date; 60302 var type; 60303 var forceOff; 60304 var finalOptions; 60305 if ($.isPlainObject(gotoOptions)) { 60306 date = gotoOptions.date; 60307 type = gotoOptions.type; 60308 forceOff = gotoOptions.forceOff; 60309 } 60310 else { 60311 date = gotoOptions; // a single moment input 60312 } 60313 date = moment_ext_1.default(date); // if a string, parse it 60314 finalOptions = { 60315 date: date.format('YYYY-MM-DD'), 60316 type: type || 'day' 60317 }; 60318 if (typeof attrs === 'string') { 60319 innerHtml = attrs; 60320 attrs = null; 60321 } 60322 attrs = attrs ? ' ' + util_1.attrsToStr(attrs) : ''; // will have a leading space 60323 innerHtml = innerHtml || ''; 60324 if (!forceOff && this.opt('navLinks')) { 60325 return '<a' + attrs + 60326 ' data-goto="' + util_1.htmlEscape(JSON.stringify(finalOptions)) + '">' + 60327 innerHtml + 60328 '</a>'; 60329 } 60330 else { 60331 return '<span' + attrs + '>' + 60332 innerHtml + 60333 '</span>'; 60334 } 60335 }; 60336 DateComponent.prototype.getAllDayHtml = function () { 60337 return this.opt('allDayHtml') || util_1.htmlEscape(this.opt('allDayText'));
60338 }; 60339 // Computes HTML classNames for a single-day element 60340 DateComponent.prototype.getDayClasses = function (date, noThemeHighlight) { 60341 var view = this._getView(); 60342 var classes = []; 60343 var today; 60344 if (!this.dateProfile.activeUnzonedRange.containsDate(date)) { 60345 classes.push('fc-disabled-day'); // TODO: jQuery UI theme? 60346 } 60347 else { 60348 classes.push('fc-' + util_1.dayIDs[date.day()]); 60349 if (view.isDateInOtherMonth(date, this.dateProfile)) { 60350 classes.push('fc-other-month'); 60351 } 60352 today = view.calendar.getNow(); 60353 if (date.isSame(today, 'day')) { 60354 classes.push('fc-today'); 60355 if (noThemeHighlight !== true) { 60356 classes.push(view.calendar.theme.getClass('today')); 60357 } 60358 } 60359 else if (date < today) { 60360 classes.push('fc-past'); 60361 } 60362 else { 60363 classes.push('fc-future'); 60364 } 60365 } 60366 return classes; 60367 }; 60368 // Utility for formatting a range. Accepts a range object, formatting string, and optional separator. 60369 // Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account. 60370 // The timezones of the dates within `range` will be respected. 60371 DateComponent.prototype.formatRange = function (range, isAllDay, formatStr, separator) { 60372 var end = range.end; 60373 if (isAllDay) { 60374 end = end.clone().subtract(1); // convert to inclusive. last ms of previous day 60375 } 60376 return date_formatting_1.formatRange(range.start, end, formatStr, separator, this.isRTL); 60377 }; 60378 // Compute the number of the give units in the "current" range. 60379 // Will return a floating-point number. Won't round. 60380 DateComponent.prototype.currentRangeAs = function (unit) { 60381 return this._getDateProfile().currentUnzonedRange.as(unit); 60382 }; 60383 // Returns the date range of the full days the given range visually appears to occupy. 60384 // Returns a plain object with start/end, NOT an UnzonedRange! 60385 DateComponent.prototype.computeDayRange = function (unzonedRange) { 60386 var calendar = this._getCalendar(); 60387 var startDay = calendar.msToUtcMoment(unzonedRange.startMs, true); // the beginning of the day the range starts 60388 var end = calendar.msToUtcMoment(unzonedRange.endMs); 60389 var endTimeMS = +end.time(); // # of milliseconds into `endDay` 60390 var endDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends 60391 // If the end time is actually inclusively part of the next day and is equal to or 60392 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`. 60393 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`. 60394 if (endTimeMS && endTimeMS >= this.nextDayThreshold) { 60395 endDay.add(1, 'days'); 60396 } 60397 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day. 60398 if (endDay <= startDay) { 60399 endDay = startDay.clone().add(1, 'days'); 60400 } 60401 return { start: startDay, end: endDay }; 60402 }; 60403 // Does the given range visually appear to occupy more than one day? 60404 DateComponent.prototype.isMultiDayRange = function (unzonedRange) { 60405 var dayRange = this.computeDayRange(unzonedRange); 60406 return dayRange.end.diff(dayRange.start, 'days') > 1; 60407 }; 60408 DateComponent.guid = 0; // TODO: better system for this? 60409 return DateComponent; 60410}(Component_1.default)); 60411exports.default = DateComponent; 60412// legacy 60413function convertEventsPayloadToLegacyArray(eventsPayload) { 60414 var eventDefId; 60415 var eventInstances; 60416 var legacyEvents = []; 60417 var i; 60418 for (eventDefId in eventsPayload) { 60419 eventInstances = eventsPayload[eventDefId].eventInstances; 60420 for (i = 0; i < eventInstances.length; i++) { 60421 legacyEvents.push(eventInstances[i].toLegacy()); 60422 } 60423 } 60424 return legacyEvents; 60425} 60426 60427 60428/***/ }), 60429/* 220 */ 60430/***/ (function(module, exports, __webpack_require__) { 60431 60432Object.defineProperty(exports, "__esModule", { value: true });
60433var $ = __webpack_require__(3); 60434var moment = __webpack_require__(0); 60435var util_1 = __webpack_require__(4); 60436var options_1 = __webpack_require__(32); 60437var Iterator_1 = __webpack_require__(238); 60438var GlobalEmitter_1 = __webpack_require__(21); 60439var EmitterMixin_1 = __webpack_require__(11); 60440var ListenerMixin_1 = __webpack_require__(7); 60441var Toolbar_1 = __webpack_require__(239); 60442var OptionsManager_1 = __webpack_require__(240); 60443var ViewSpecManager_1 = __webpack_require__(241); 60444var Constraints_1 = __webpack_require__(207); 60445var locale_1 = __webpack_require__(31); 60446var moment_ext_1 = __webpack_require__(10); 60447var UnzonedRange_1 = __webpack_require__(5); 60448var ComponentFootprint_1 = __webpack_require__(12); 60449var EventDateProfile_1 = __webpack_require__(17); 60450var EventManager_1 = __webpack_require__(242); 60451var BusinessHourGenerator_1 = __webpack_require__(212); 60452var EventSourceParser_1 = __webpack_require__(38); 60453var EventDefParser_1 = __webpack_require__(49); 60454var SingleEventDef_1 = __webpack_require__(13); 60455var EventDefMutation_1 = __webpack_require__(37); 60456var EventSource_1 = __webpack_require__(6); 60457var ThemeRegistry_1 = __webpack_require__(51); 60458var Calendar = /** @class */ (function () { 60459 function Calendar(el, overrides) { 60460 this.loadingLevel = 0; // number of simultaneous loading tasks 60461 this.ignoreUpdateViewSize = 0; 60462 this.freezeContentHeightDepth = 0; 60463 // declare the current calendar instance relies on GlobalEmitter. needed for garbage collection. 60464 // unneeded() is called in destroy. 60465 GlobalEmitter_1.default.needed(); 60466 this.el = el; 60467 this.viewsByType = {}; 60468 this.optionsManager = new OptionsManager_1.default(this, overrides); 60469 this.viewSpecManager = new ViewSpecManager_1.default(this.optionsManager, this); 60470 this.initMomentInternals(); // needs to happen after options hash initialized 60471 this.initCurrentDate(); 60472 this.initEventManager(); 60473 this.constraints = new Constraints_1.default(this.eventManager, this); 60474 this.constructed(); 60475 } 60476 Calendar.prototype.constructed = function () { 60477 // useful for monkeypatching. used? 60478 }; 60479 Calendar.prototype.getView = function () { 60480 return this.view; 60481 }; 60482 Calendar.prototype.publiclyTrigger = function (name, triggerInfo) { 60483 var optHandler = this.opt(name); 60484 var context; 60485 var args; 60486 if ($.isPlainObject(triggerInfo)) { 60487 context = triggerInfo.context; 60488 args = triggerInfo.args; 60489 } 60490 else if ($.isArray(triggerInfo)) { 60491 args = triggerInfo; 60492 } 60493 if (context == null) { 60494 context = this.el[0]; // fallback context 60495 } 60496 if (!args) { 60497 args = []; 60498 } 60499 this.triggerWith(name, context, args); // Emitter's method 60500 if (optHandler) { 60501 return optHandler.apply(context, args); 60502 } 60503 }; 60504 Calendar.prototype.hasPublicHandlers = function (name) { 60505 return this.hasHandlers(name) || 60506 this.opt(name); // handler specified in options 60507 }; 60508 // Options Public API 60509 // ----------------------------------------------------------------------------------------------------------------- 60510 // public getter/setter 60511 Calendar.prototype.option = function (name, value) { 60512 var newOptionHash; 60513 if (typeof name === 'string') { 60514 if (value === undefined) { 60515 return this.optionsManager.get(name); 60516 } 60517 else { 60518 newOptionHash = {}; 60519 newOptionHash[name] = value; 60520 this.optionsManager.add(newOptionHash); 60521 } 60522 } 60523 else if (typeof name === 'object') { 60524 this.optionsManager.add(name); 60525 } 60526 }; 60527 // private getter 60528 Calendar.prototype.opt = function (name) { 60529 return this.optionsManager.get(name); 60530 }; 60531 // View 60532 // -----------------------------------------------------------------------------------------------------------------
60533 // Given a view name for a custom view or a standard view, creates a ready-to-go View object 60534 Calendar.prototype.instantiateView = function (viewType) { 60535 var spec = this.viewSpecManager.getViewSpec(viewType); 60536 if (!spec) { 60537 throw new Error("View type \"" + viewType + "\" is not valid"); 60538 } 60539 return new spec['class'](this, spec); 60540 }; 60541 // Returns a boolean about whether the view is okay to instantiate at some point 60542 Calendar.prototype.isValidViewType = function (viewType) { 60543 return Boolean(this.viewSpecManager.getViewSpec(viewType)); 60544 }; 60545 Calendar.prototype.changeView = function (viewName, dateOrRange) { 60546 if (dateOrRange) { 60547 if (dateOrRange.start && dateOrRange.end) { 60548 this.optionsManager.recordOverrides({ 60549 visibleRange: dateOrRange 60550 }); 60551 } 60552 else { 60553 this.currentDate = this.moment(dateOrRange).stripZone(); // just like gotoDate 60554 } 60555 } 60556 this.renderView(viewName); 60557 }; 60558 // Forces navigation to a view for the given date. 60559 // `viewType` can be a specific view name or a generic one like "week" or "day". 60560 Calendar.prototype.zoomTo = function (newDate, viewType) { 60561 var spec; 60562 viewType = viewType || 'day'; // day is default zoom 60563 spec = this.viewSpecManager.getViewSpec(viewType) || 60564 this.viewSpecManager.getUnitViewSpec(viewType); 60565 this.currentDate = newDate.clone(); 60566 this.renderView(spec ? spec.type : null); 60567 }; 60568 // Current Date 60569 // ----------------------------------------------------------------------------------------------------------------- 60570 Calendar.prototype.initCurrentDate = function () { 60571 var defaultDateInput = this.opt('defaultDate'); 60572 // compute the initial ambig-timezone date 60573 if (defaultDateInput != null) { 60574 this.currentDate = this.moment(defaultDateInput).stripZone(); 60575 } 60576 else { 60577 this.currentDate = this.getNow(); // getNow already returns unzoned 60578 } 60579 }; 60580 Calendar.prototype.prev = function () { 60581 var view = this.view; 60582 var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile')); 60583 if (prevInfo.isValid) { 60584 this.currentDate = prevInfo.date; 60585 this.renderView(); 60586 } 60587 }; 60588 Calendar.prototype.next = function () { 60589 var view = this.view; 60590 var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile')); 60591 if (nextInfo.isValid) { 60592 this.currentDate = nextInfo.date; 60593 this.renderView(); 60594 } 60595 }; 60596 Calendar.prototype.prevYear = function () { 60597 this.currentDate.add(-1, 'years'); 60598 this.renderView(); 60599 }; 60600 Calendar.prototype.nextYear = function () { 60601 this.currentDate.add(1, 'years'); 60602 this.renderView(); 60603 }; 60604 Calendar.prototype.today = function () { 60605 this.currentDate = this.getNow(); // should deny like prev/next? 60606 this.renderView(); 60607 }; 60608 Calendar.prototype.gotoDate = function (zonedDateInput) { 60609 this.currentDate = this.moment(zonedDateInput).stripZone(); 60610 this.renderView(); 60611 }; 60612 Calendar.prototype.incrementDate = function (delta) { 60613 this.currentDate.add(moment.duration(delta)); 60614 this.renderView(); 60615 }; 60616 // for external API 60617 Calendar.prototype.getDate = function () { 60618 return this.applyTimezone(this.currentDate); // infuse the calendar's timezone 60619 }; 60620 // Loading Triggering 60621 // ----------------------------------------------------------------------------------------------------------------- 60622 // Should be called when any type of async data fetching begins 60623 Calendar.prototype.pushLoading = function () { 60624 if (!(this.loadingLevel++)) { 60625 this.publiclyTrigger('loading', [true, this.view]); 60626 } 60627 }; 60628 // Should be called when any type of async data fetching completes 60629 Calendar.prototype.popLoading = function () { 60630 if (!(--this.loadingLevel)) { 60631 this.publiclyTrigger('loading', [false, this.view]); 60632 } 60633 }; 60634 // High-level Rendering 60635 // ----------------------------------------------------------------------------------- 60636 Calendar.prototype.render = function () { 60637 if (!this.contentEl) { 60638 this.initialRender(); 60639 } 60640 else if (this.elementVisible()) { 60641 // mainly for the public API 60642 this.calcSize(); 60643 this.updateViewSize(); 60644 } 60645 }; 60646 Calendar.prototype.initialRender = function () { 60647 var _this = this; 60648 var el = this.el; 60649 el.addClass('fc'); 60650 // event delegation for nav links 60651 el.on('click.fc', 'a[data-goto]', function (ev) { 60652 var anchorEl = $(ev.currentTarget); 60653 var gotoOptions = anchorEl.data('goto'); // will automatically parse JSON 60654 var date = _this.moment(gotoOptions.date); 60655 var viewType = gotoOptions.type; 60656 // property like "navLinkDayClick". might be a string or a function 60657 var customAction = _this.view.opt('navLink' + util_1.capitaliseFirstLetter(viewType) + 'Click'); 60658 if (typeof customAction === 'function') { 60659 customAction(date, ev); 60660 } 60661 else { 60662 if (typeof customAction === 'string') { 60663 viewType = customAction; 60664 } 60665 _this.zoomTo(date, viewType); 60666 } 60667 });
60668 // called immediately, and upon option change 60669 this.optionsManager.watch('settingTheme', ['?theme', '?themeSystem'], function (opts) { 60670 var themeClass = ThemeRegistry_1.getThemeSystemClass(opts.themeSystem || opts.theme); 60671 var theme = new themeClass(_this.optionsManager); 60672 var widgetClass = theme.getClass('widget'); 60673 _this.theme = theme; 60674 if (widgetClass) { 60675 el.addClass(widgetClass); 60676 } 60677 }, function () { 60678 var widgetClass = _this.theme.getClass('widget'); 60679 _this.theme = null; 60680 if (widgetClass) { 60681 el.removeClass(widgetClass); 60682 } 60683 }); 60684 this.optionsManager.watch('settingBusinessHourGenerator', ['?businessHours'], function (deps) { 60685 _this.businessHourGenerator = new BusinessHourGenerator_1.default(deps.businessHours, _this); 60686 if (_this.view) { 60687 _this.view.set('businessHourGenerator', _this.businessHourGenerator); 60688 } 60689 }, function () { 60690 _this.businessHourGenerator = null; 60691 }); 60692 // called immediately, and upon option change. 60693 // HACK: locale often affects isRTL, so we explicitly listen to that too. 60694 this.optionsManager.watch('applyingDirClasses', ['?isRTL', '?locale'], function (opts) { 60695 el.toggleClass('fc-ltr', !opts.isRTL); 60696 el.toggleClass('fc-rtl', opts.isRTL); 60697 }); 60698 this.contentEl = $("<div class='fc-view-container'/>").prependTo(el); 60699 this.initToolbars(); 60700 this.renderHeader(); 60701 this.renderFooter(); 60702 this.renderView(this.opt('defaultView')); 60703 if (this.opt('handleWindowResize')) { 60704 $(window).resize(this.windowResizeProxy = util_1.debounce(// prevents rapid calls 60705 this.windowResize.bind(this), this.opt('windowResizeDelay'))); 60706 } 60707 }; 60708 Calendar.prototype.destroy = function () { 60709 if (this.view) { 60710 this.clearView(); 60711 } 60712 this.toolbarsManager.proxyCall('removeElement'); 60713 this.contentEl.remove(); 60714 this.el.removeClass('fc fc-ltr fc-rtl'); 60715 // removes theme-related root className 60716 this.optionsManager.unwatch('settingTheme'); 60717 this.optionsManager.unwatch('settingBusinessHourGenerator'); 60718 this.el.off('.fc'); // unbind nav link handlers 60719 if (this.windowResizeProxy) { 60720 $(window).unbind('resize', this.windowResizeProxy); 60721 this.windowResizeProxy = null; 60722 } 60723 GlobalEmitter_1.default.unneeded(); 60724 }; 60725 Calendar.prototype.elementVisible = function () { 60726 return this.el.is(':visible'); 60727 }; 60728 // Render Queue 60729 // ----------------------------------------------------------------------------------------------------------------- 60730 Calendar.prototype.bindViewHandlers = function (view) { 60731 var _this = this; 60732 view.watch('titleForCalendar', ['title'], function (deps) { 60733 if (view === _this.view) { 60734 _this.setToolbarsTitle(deps.title); 60735 } 60736 }); 60737 view.watch('dateProfileForCalendar', ['dateProfile'], function (deps) { 60738 if (view === _this.view) { 60739 _this.currentDate = deps.dateProfile.date; // might have been constrained by view dates 60740 _this.updateToolbarButtons(deps.dateProfile); 60741 } 60742 }); 60743 }; 60744 Calendar.prototype.unbindViewHandlers = function (view) { 60745 view.unwatch('titleForCalendar'); 60746 view.unwatch('dateProfileForCalendar'); 60747 }; 60748 // View Rendering 60749 // ----------------------------------------------------------------------------------- 60750 // Renders a view because of a date change, view-type change, or for the first time. 60751 // If not given a viewType, keep the current view but render different dates. 60752 // Accepts an optional scroll state to restore to. 60753 Calendar.prototype.renderView = function (viewType) { 60754 var oldView = this.view; 60755 var newView; 60756 this.freezeContentHeight(); 60757 if (oldView && viewType && oldView.type !== viewType) { 60758 this.clearView(); 60759 } 60760 // if viewType changed, or the view was never created, create a fresh view 60761 if (!this.view && viewType) { 60762 newView = this.view = 60763 this.viewsByType[viewType] || 60764 (this.viewsByType[viewType] = this.instantiateView(viewType)); 60765 this.bindViewHandlers(newView); 60766 newView.startBatchRender(); // so that setElement+setDate rendering are joined 60767 newView.setElement($("<div class='fc-view fc-" + viewType + "-view' />").appendTo(this.contentEl)); 60768 this.toolbarsManager.proxyCall('activateButton', viewType); 60769 } 60770 if (this.view) { 60771 // prevent unnecessary change firing 60772 if (this.view.get('businessHourGenerator') !== this.businessHourGenerator) { 60773 this.view.set('businessHourGenerator', this.businessHourGenerator); 60774 } 60775 this.view.setDate(this.currentDate); 60776 if (newView) { 60777 newView.stopBatchRender(); 60778 } 60779 } 60780 this.thawContentHeight(); 60781 }; 60782 // Unrenders the current view and reflects this change in the Header. 60783 // Unregsiters the `view`, but does not remove from viewByType hash. 60784 Calendar.prototype.clearView = function () { 60785 var currentView = this.view; 60786 this.toolbarsManager.proxyCall('deactivateButton', currentView.type); 60787 this.unbindViewHandlers(currentView); 60788 currentView.removeElement(); 60789 currentView.unsetDate(); // so bindViewHandlers doesn't fire with old values next time 60790 this.view = null; 60791 }; 60792 // Destroys the view, including the view object. Then, re-instantiates it and renders it. 60793 // Maintains the same scroll state. 60794 // TODO: maintain any other user-manipulated state. 60795 Calendar.prototype.reinitView = function () { 60796 var oldView = this.view; 60797 var scroll = oldView.queryScroll(); // wouldn't be so complicated if Calendar owned the scroll 60798 this.freezeContentHeight(); 60799 this.clearView(); 60800 this.calcSize(); 60801 this.renderView(oldView.type); // needs the type to freshly render
60802 this.view.applyScroll(scroll); 60803 this.thawContentHeight(); 60804 }; 60805 // Resizing 60806 // ----------------------------------------------------------------------------------- 60807 Calendar.prototype.getSuggestedViewHeight = function () { 60808 if (this.suggestedViewHeight == null) { 60809 this.calcSize(); 60810 } 60811 return this.suggestedViewHeight; 60812 }; 60813 Calendar.prototype.isHeightAuto = function () { 60814 return this.opt('contentHeight') === 'auto' || this.opt('height') === 'auto'; 60815 }; 60816 Calendar.prototype.updateViewSize = function (isResize) { 60817 if (isResize === void 0) { isResize = false; } 60818 var view = this.view; 60819 var scroll; 60820 if (!this.ignoreUpdateViewSize && view) { 60821 if (isResize) { 60822 this.calcSize(); 60823 scroll = view.queryScroll(); 60824 } 60825 this.ignoreUpdateViewSize++; 60826 view.updateSize(this.getSuggestedViewHeight(), this.isHeightAuto(), isResize); 60827 this.ignoreUpdateViewSize--; 60828 if (isResize) { 60829 view.applyScroll(scroll); 60830 } 60831 return true; // signal success 60832 } 60833 }; 60834 Calendar.prototype.calcSize = function () { 60835 if (this.elementVisible()) { 60836 this._calcSize(); 60837 } 60838 }; 60839 Calendar.prototype._calcSize = function () { 60840 var contentHeightInput = this.opt('contentHeight'); 60841 var heightInput = this.opt('height'); 60842 if (typeof contentHeightInput === 'number') { 60843 this.suggestedViewHeight = contentHeightInput; 60844 } 60845 else if (typeof contentHeightInput === 'function') { 60846 this.suggestedViewHeight = contentHeightInput(); 60847 } 60848 else if (typeof heightInput === 'number') { 60849 this.suggestedViewHeight = heightInput - this.queryToolbarsHeight(); 60850 } 60851 else if (typeof heightInput === 'function') { 60852 this.suggestedViewHeight = heightInput() - this.queryToolbarsHeight(); 60853 } 60854 else if (heightInput === 'parent') { 60855 this.suggestedViewHeight = this.el.parent().height() - this.queryToolbarsHeight(); 60856 } 60857 else { 60858 this.suggestedViewHeight = Math.round(this.contentEl.width() / 60859 Math.max(this.opt('aspectRatio'), .5)); 60860 } 60861 }; 60862 Calendar.prototype.windowResize = function (ev) { 60863 if ( 60864 // the purpose: so we don't process jqui "resize" events that have bubbled up 60865 // cast to any because .target, which is Element, can't be compared to window for some reason. 60866 ev.target === window && 60867 this.view && 60868 this.view.isDatesRendered) { 60869 if (this.updateViewSize(true)) { 60870 this.publiclyTrigger('windowResize', [this.view]); 60871 } 60872 } 60873 }; 60874 /* Height "Freezing" 60875 -----------------------------------------------------------------------------*/ 60876 Calendar.prototype.freezeContentHeight = function () { 60877 if (!(this.freezeContentHeightDepth++)) { 60878 this.forceFreezeContentHeight(); 60879 } 60880 }; 60881 Calendar.prototype.forceFreezeContentHeight = function () { 60882 this.contentEl.css({ 60883 width: '100%', 60884 height: this.contentEl.height(), 60885 overflow: 'hidden' 60886 }); 60887 }; 60888 Calendar.prototype.thawContentHeight = function () { 60889 this.freezeContentHeightDepth--; 60890 // always bring back to natural height 60891 this.contentEl.css({ 60892 width: '', 60893 height: '', 60894 overflow: '' 60895 }); 60896 // but if there are future thaws, re-freeze 60897 if (this.freezeContentHeightDepth) { 60898 this.forceFreezeContentHeight(); 60899 } 60900 }; 60901 // Toolbar 60902 // ----------------------------------------------------------------------------------------------------------------- 60903 Calendar.prototype.initToolbars = function () { 60904 this.header = new Toolbar_1.default(this, this.computeHeaderOptions()); 60905 this.footer = new Toolbar_1.default(this, this.computeFooterOptions()); 60906 this.toolbarsManager = new Iterator_1.default([this.header, this.footer]); 60907 }; 60908 Calendar.prototype.computeHeaderOptions = function () { 60909 return {
60910 extraClasses: 'fc-header-toolbar', 60911 layout: this.opt('header') 60912 }; 60913 }; 60914 Calendar.prototype.computeFooterOptions = function () { 60915 return { 60916 extraClasses: 'fc-footer-toolbar', 60917 layout: this.opt('footer') 60918 }; 60919 }; 60920 // can be called repeatedly and Header will rerender 60921 Calendar.prototype.renderHeader = function () { 60922 var header = this.header; 60923 header.setToolbarOptions(this.computeHeaderOptions()); 60924 header.render(); 60925 if (header.el) { 60926 this.el.prepend(header.el); 60927 } 60928 }; 60929 // can be called repeatedly and Footer will rerender 60930 Calendar.prototype.renderFooter = function () { 60931 var footer = this.footer; 60932 footer.setToolbarOptions(this.computeFooterOptions()); 60933 footer.render(); 60934 if (footer.el) { 60935 this.el.append(footer.el); 60936 } 60937 }; 60938 Calendar.prototype.setToolbarsTitle = function (title) { 60939 this.toolbarsManager.proxyCall('updateTitle', title); 60940 }; 60941 Calendar.prototype.updateToolbarButtons = function (dateProfile) { 60942 var now = this.getNow(); 60943 var view = this.view; 60944 var todayInfo = view.dateProfileGenerator.build(now); 60945 var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile')); 60946 var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile')); 60947 this.toolbarsManager.proxyCall((todayInfo.isValid && !dateProfile.currentUnzonedRange.containsDate(now)) ? 60948 'enableButton' : 60949 'disableButton', 'today'); 60950 this.toolbarsManager.proxyCall(prevInfo.isValid ? 60951 'enableButton' : 60952 'disableButton', 'prev'); 60953 this.toolbarsManager.proxyCall(nextInfo.isValid ? 60954 'enableButton' : 60955 'disableButton', 'next'); 60956 }; 60957 Calendar.prototype.queryToolbarsHeight = function () { 60958 return this.toolbarsManager.items.reduce(function (accumulator, toolbar) { 60959 var toolbarHeight = toolbar.el ? toolbar.el.outerHeight(true) : 0; // includes margin 60960 return accumulator + toolbarHeight; 60961 }, 0); 60962 }; 60963 // Selection 60964 // ----------------------------------------------------------------------------------------------------------------- 60965 // this public method receives start/end dates in any format, with any timezone 60966 Calendar.prototype.select = function (zonedStartInput, zonedEndInput) { 60967 this.view.select(this.buildSelectFootprint.apply(this, arguments)); 60968 }; 60969 Calendar.prototype.unselect = function () { 60970 if (this.view) { 60971 this.view.unselect(); 60972 } 60973 }; 60974 // Given arguments to the select method in the API, returns a span (unzoned start/end and other info) 60975 Calendar.prototype.buildSelectFootprint = function (zonedStartInput, zonedEndInput) { 60976 var start = this.moment(zonedStartInput).stripZone(); 60977 var end; 60978 if (zonedEndInput) { 60979 end = this.moment(zonedEndInput).stripZone(); 60980 } 60981 else if (start.hasTime()) { 60982 end = start.clone().add(this.defaultTimedEventDuration); 60983 } 60984 else { 60985 end = start.clone().add(this.defaultAllDayEventDuration); 60986 } 60987 return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), !start.hasTime()); 60988 }; 60989 // Date Utils 60990 // ----------------------------------------------------------------------------------------------------------------- 60991 Calendar.prototype.initMomentInternals = function () { 60992 var _this = this; 60993 this.defaultAllDayEventDuration = moment.duration(this.opt('defaultAllDayEventDuration')); 60994 this.defaultTimedEventDuration = moment.duration(this.opt('defaultTimedEventDuration')); 60995 // Called immediately, and when any of the options change. 60996 // Happens before any internal objects rebuild or rerender, because this is very core. 60997 this.optionsManager.watch('buildingMomentLocale', [ 60998 '?locale', '?monthNames', '?monthNamesShort', '?dayNames', '?dayNamesShort', 60999 '?firstDay', '?weekNumberCalculation' 61000 ], function (opts) { 61001 var weekNumberCalculation = opts.weekNumberCalculation; 61002 var firstDay = opts.firstDay; 61003 var _week; 61004 // normalize
61005 if (weekNumberCalculation === 'iso') { 61006 weekNumberCalculation = 'ISO'; // normalize 61007 } 61008 var localeData = Object.create(// make a cheap copy 61009 locale_1.getMomentLocaleData(opts.locale) // will fall back to en 61010 ); 61011 if (opts.monthNames) { 61012 localeData._months = opts.monthNames; 61013 } 61014 if (opts.monthNamesShort) { 61015 localeData._monthsShort = opts.monthNamesShort; 61016 } 61017 if (opts.dayNames) { 61018 localeData._weekdays = opts.dayNames; 61019 } 61020 if (opts.dayNamesShort) { 61021 localeData._weekdaysShort = opts.dayNamesShort; 61022 } 61023 if (firstDay == null && weekNumberCalculation === 'ISO') { 61024 firstDay = 1; 61025 } 61026 if (firstDay != null) { 61027 _week = Object.create(localeData._week); // _week: { dow: # } 61028 _week.dow = firstDay; 61029 localeData._week = _week; 61030 } 61031 if (weekNumberCalculation === 'ISO' || 61032 weekNumberCalculation === 'local' || 61033 typeof weekNumberCalculation === 'function') { 61034 localeData._fullCalendar_weekCalc = weekNumberCalculation; // moment-ext will know what to do with it 61035 } 61036 _this.localeData = localeData; 61037 // If the internal current date object already exists, move to new locale. 61038 // We do NOT need to do this technique for event dates, because this happens when converting to "segments". 61039 if (_this.currentDate) { 61040 _this.localizeMoment(_this.currentDate); // sets to localeData 61041 } 61042 }); 61043 }; 61044 // Builds a moment using the settings of the current calendar: timezone and locale. 61045 // Accepts anything the vanilla moment() constructor accepts. 61046 Calendar.prototype.moment = function () { 61047 var args = []; 61048 for (var _i = 0; _i < arguments.length; _i++) { 61049 args[_i] = arguments[_i]; 61050 } 61051 var mom; 61052 if (this.opt('timezone') === 'local') { 61053 mom = moment_ext_1.default.apply(null, args); 61054 // Force the moment to be local, because momentExt doesn't guarantee it. 61055 if (mom.hasTime()) { 61056 mom.local(); 61057 } 61058 } 61059 else if (this.opt('timezone') === 'UTC') { 61060 mom = moment_ext_1.default.utc.apply(null, args); // process as UTC 61061 } 61062 else { 61063 mom = moment_ext_1.default.parseZone.apply(null, args); // let the input decide the zone 61064 } 61065 this.localizeMoment(mom); // TODO 61066 return mom; 61067 }; 61068 Calendar.prototype.msToMoment = function (ms, forceAllDay) { 61069 var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC 61070 if (forceAllDay) { 61071 mom.stripTime(); 61072 } 61073 else { 61074 mom = this.applyTimezone(mom); // may or may not apply locale 61075 } 61076 this.localizeMoment(mom); 61077 return mom; 61078 }; 61079 Calendar.prototype.msToUtcMoment = function (ms, forceAllDay) { 61080 var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC 61081 if (forceAllDay) { 61082 mom.stripTime(); 61083 } 61084 this.localizeMoment(mom); 61085 return mom; 61086 }; 61087 // Updates the given moment's locale settings to the current calendar locale settings. 61088 Calendar.prototype.localizeMoment = function (mom) { 61089 mom._locale = this.localeData; 61090 }; 61091 // Returns a boolean about whether or not the calendar knows how to calculate 61092 // the timezone offset of arbitrary dates in the current timezone. 61093 Calendar.prototype.getIsAmbigTimezone = function () { 61094 return this.opt('timezone') !== 'local' && this.opt('timezone') !== 'UTC'; 61095 }; 61096 // Returns a copy of the given date in the current timezone. Has no effect on dates without times. 61097 Calendar.prototype.applyTimezone = function (date) { 61098 if (!date.hasTime()) { 61099 return date.clone(); 61100 } 61101 var zonedDate = this.moment(date.toArray()); 61102 var timeAdjust = date.time().asMilliseconds() - zonedDate.time().asMilliseconds(); 61103 var adjustedZonedDate; 61104 // Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396) 61105 if (timeAdjust) { 61106 adjustedZonedDate = zonedDate.clone().add(timeAdjust); // add milliseconds 61107 if (date.time().asMilliseconds() - adjustedZonedDate.time().asMilliseconds() === 0) { 61108 zonedDate = adjustedZonedDate; 61109 } 61110 } 61111 return zonedDate; 61112 }; 61113 /* 61114 Assumes the footprint is non-open-ended. 61115 */ 61116 Calendar.prototype.footprintToDateProfile = function (componentFootprint, ignoreEnd) { 61117 if (ignoreEnd === void 0) { ignoreEnd = false; } 61118 var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs); 61119 var end; 61120 if (!ignoreEnd) { 61121 end = moment_ext_1.default.utc(componentFootprint.unzonedRange.endMs); 61122 } 61123 if (componentFootprint.isAllDay) { 61124 start.stripTime(); 61125 if (end) { 61126 end.stripTime(); 61127 } 61128 } 61129 else { 61130 start = this.applyTimezone(start); 61131 if (end) { 61132 end = this.applyTimezone(end); 61133 } 61134 } 61135 return new EventDateProfile_1.default(start, end, this); 61136 }; 61137 // Returns a moment for the current date, as defined by the client's computer or from the `now` option. 61138 // Will return an moment with an ambiguous timezone. 61139 Calendar.prototype.getNow = function () { 61140 var now = this.opt('now'); 61141 if (typeof now === 'function') { 61142 now = now(); 61143 } 61144 return this.moment(now).stripZone(); 61145 }; 61146 // Produces a human-readable string for the given duration. 61147 // Side-effect: changes the locale of the given duration. 61148 Calendar.prototype.humanizeDuration = function (duration) { 61149 return duration.locale(this.opt('locale')).humanize(); 61150 }; 61151 // will return `null` if invalid range 61152 Calendar.prototype.parseUnzonedRange = function (rangeInput) { 61153 var start = null; 61154 var end = null; 61155 if (rangeInput.start) { 61156 start = this.moment(rangeInput.start).stripZone(); 61157 } 61158 if (rangeInput.end) {
61159 end = this.moment(rangeInput.end).stripZone(); 61160 } 61161 if (!start && !end) { 61162 return null; 61163 } 61164 if (start && end && end.isBefore(start)) { 61165 return null; 61166 } 61167 return new UnzonedRange_1.default(start, end); 61168 }; 61169 // Event-Date Utilities 61170 // ----------------------------------------------------------------------------------------------------------------- 61171 Calendar.prototype.initEventManager = function () { 61172 var _this = this; 61173 var eventManager = new EventManager_1.default(this); 61174 var rawSources = this.opt('eventSources') || []; 61175 var singleRawSource = this.opt('events'); 61176 this.eventManager = eventManager; 61177 if (singleRawSource) { 61178 rawSources.unshift(singleRawSource); 61179 } 61180 eventManager.on('release', function (eventsPayload) { 61181 _this.trigger('eventsReset', eventsPayload); 61182 }); 61183 eventManager.freeze(); 61184 rawSources.forEach(function (rawSource) { 61185 var source = EventSourceParser_1.default.parse(rawSource, _this); 61186 if (source) { 61187 eventManager.addSource(source); 61188 } 61189 }); 61190 eventManager.thaw(); 61191 }; 61192 Calendar.prototype.requestEvents = function (start, end) { 61193 return this.eventManager.requestEvents(start, end, this.opt('timezone'), !this.opt('lazyFetching')); 61194 }; 61195 // Get an event's normalized end date. If not present, calculate it from the defaults. 61196 Calendar.prototype.getEventEnd = function (event) { 61197 if (event.end) { 61198 return event.end.clone(); 61199 } 61200 else { 61201 return this.getDefaultEventEnd(event.allDay, event.start); 61202 } 61203 }; 61204 // Given an event's allDay status and start date, return what its fallback end date should be. 61205 // TODO: rename to computeDefaultEventEnd 61206 Calendar.prototype.getDefaultEventEnd = function (allDay, zonedStart) { 61207 var end = zonedStart.clone(); 61208 if (allDay) { 61209 end.stripTime().add(this.defaultAllDayEventDuration); 61210 } 61211 else { 61212 end.add(this.defaultTimedEventDuration); 61213 } 61214 if (this.getIsAmbigTimezone()) { 61215 end.stripZone(); // we don't know what the tzo should be 61216 } 61217 return end; 61218 }; 61219 // Public Events API 61220 // ----------------------------------------------------------------------------------------------------------------- 61221 Calendar.prototype.rerenderEvents = function () { 61222 this.view.flash('displayingEvents'); 61223 }; 61224 Calendar.prototype.refetchEvents = function () { 61225 this.eventManager.refetchAllSources(); 61226 }; 61227 Calendar.prototype.renderEvents = function (eventInputs, isSticky) { 61228 this.eventManager.freeze(); 61229 for (var i = 0; i < eventInputs.length; i++) { 61230 this.renderEvent(eventInputs[i], isSticky); 61231 } 61232 this.eventManager.thaw(); 61233 }; 61234 Calendar.prototype.renderEvent = function (eventInput, isSticky) { 61235 if (isSticky === void 0) { isSticky = false; } 61236 var eventManager = this.eventManager; 61237 var eventDef = EventDefParser_1.default.parse(eventInput, eventInput.source || eventManager.stickySource); 61238 if (eventDef) { 61239 eventManager.addEventDef(eventDef, isSticky); 61240 } 61241 }; 61242 // legacyQuery operates on legacy event instance objects 61243 Calendar.prototype.removeEvents = function (legacyQuery) { 61244 var eventManager = this.eventManager; 61245 var legacyInstances = []; 61246 var idMap = {}; 61247 var eventDef; 61248 var i; 61249 if (legacyQuery == null) { 61250 eventManager.removeAllEventDefs(); // persist=true 61251 } 61252 else { 61253 eventManager.getEventInstances().forEach(function (eventInstance) { 61254 legacyInstances.push(eventInstance.toLegacy()); 61255 }); 61256 legacyInstances = filterLegacyEventInstances(legacyInstances, legacyQuery); 61257 // compute unique IDs 61258 for (i = 0; i < legacyInstances.length; i++) { 61259 eventDef = this.eventManager.getEventDefByUid(legacyInstances[i]._id); 61260 idMap[eventDef.id] = true; 61261 } 61262 eventManager.freeze(); 61263 for (i in idMap) { 61264 eventManager.removeEventDefsById(i); // persist=true 61265 } 61266 eventManager.thaw(); 61267 } 61268 }; 61269 // legacyQuery operates on legacy event instance objects 61270 Calendar.prototype.clientEvents = function (legacyQuery) { 61271 var legacyEventInstances = [];
61272 this.eventManager.getEventInstances().forEach(function (eventInstance) { 61273 legacyEventInstances.push(eventInstance.toLegacy()); 61274 }); 61275 return filterLegacyEventInstances(legacyEventInstances, legacyQuery); 61276 }; 61277 Calendar.prototype.updateEvents = function (eventPropsArray) { 61278 this.eventManager.freeze(); 61279 for (var i = 0; i < eventPropsArray.length; i++) { 61280 this.updateEvent(eventPropsArray[i]); 61281 } 61282 this.eventManager.thaw(); 61283 }; 61284 Calendar.prototype.updateEvent = function (eventProps) { 61285 var eventDef = this.eventManager.getEventDefByUid(eventProps._id); 61286 var eventInstance; 61287 var eventDefMutation; 61288 if (eventDef instanceof SingleEventDef_1.default) { 61289 eventInstance = eventDef.buildInstance(); 61290 eventDefMutation = EventDefMutation_1.default.createFromRawProps(eventInstance, eventProps, // raw props 61291 null // largeUnit -- who uses it? 61292 ); 61293 this.eventManager.mutateEventsWithId(eventDef.id, eventDefMutation); // will release 61294 } 61295 }; 61296 // Public Event Sources API 61297 // ------------------------------------------------------------------------------------ 61298 Calendar.prototype.getEventSources = function () { 61299 return this.eventManager.otherSources.slice(); // clone 61300 }; 61301 Calendar.prototype.getEventSourceById = function (id) { 61302 return this.eventManager.getSourceById(EventSource_1.default.normalizeId(id)); 61303 }; 61304 Calendar.prototype.addEventSource = function (sourceInput) { 61305 var source = EventSourceParser_1.default.parse(sourceInput, this); 61306 if (source) { 61307 this.eventManager.addSource(source); 61308 } 61309 }; 61310 Calendar.prototype.removeEventSources = function (sourceMultiQuery) { 61311 var eventManager = this.eventManager; 61312 var sources; 61313 var i; 61314 if (sourceMultiQuery == null) { 61315 this.eventManager.removeAllSources(); 61316 } 61317 else { 61318 sources = eventManager.multiQuerySources(sourceMultiQuery); 61319 eventManager.freeze(); 61320 for (i = 0; i < sources.length; i++) { 61321 eventManager.removeSource(sources[i]); 61322 } 61323 eventManager.thaw(); 61324 } 61325 }; 61326 Calendar.prototype.removeEventSource = function (sourceQuery) { 61327 var eventManager = this.eventManager; 61328 var sources = eventManager.querySources(sourceQuery); 61329 var i; 61330 eventManager.freeze(); 61331 for (i = 0; i < sources.length; i++) { 61332 eventManager.removeSource(sources[i]); 61333 } 61334 eventManager.thaw(); 61335 }; 61336 Calendar.prototype.refetchEventSources = function (sourceMultiQuery) { 61337 var eventManager = this.eventManager; 61338 var sources = eventManager.multiQuerySources(sourceMultiQuery); 61339 var i; 61340 eventManager.freeze(); 61341 for (i = 0; i < sources.length; i++) { 61342 eventManager.refetchSource(sources[i]); 61343 } 61344 eventManager.thaw(); 61345 }; 61346 // not for internal use. use options module directly instead. 61347 Calendar.defaults = options_1.globalDefaults; 61348 Calendar.englishDefaults = options_1.englishDefaults; 61349 Calendar.rtlDefaults = options_1.rtlDefaults; 61350 return Calendar; 61351}()); 61352exports.default = Calendar; 61353EmitterMixin_1.default.mixInto(Calendar); 61354ListenerMixin_1.default.mixInto(Calendar); 61355function filterLegacyEventInstances(legacyEventInstances, legacyQuery) { 61356 if (legacyQuery == null) { 61357 return legacyEventInstances; 61358 } 61359 else if ($.isFunction(legacyQuery)) { 61360 return legacyEventInstances.filter(legacyQuery); 61361 } 61362 else { 61363 legacyQuery += ''; // normalize to string 61364 return legacyEventInstances.filter(function (legacyEventInstance) { 61365 // soft comparison because id not be normalized to string 61366 // tslint:disable-next-line 61367 return legacyEventInstance.id == legacyQuery || 61368 legacyEventInstance._id === legacyQuery; // can specify internal id, but must exactly match 61369 }); 61370 } 61371} 61372 61373 61374/***/ }), 61375/* 221 */ 61376/***/ (function(module, exports, __webpack_require__) { 61377 61378Object.defineProperty(exports, "__esModule", { value: true });
61379var moment = __webpack_require__(0); 61380var util_1 = __webpack_require__(4); 61381var UnzonedRange_1 = __webpack_require__(5); 61382var DateProfileGenerator = /** @class */ (function () { 61383 function DateProfileGenerator(_view) { 61384 this._view = _view; 61385 } 61386 DateProfileGenerator.prototype.opt = function (name) { 61387 return this._view.opt(name); 61388 }; 61389 DateProfileGenerator.prototype.trimHiddenDays = function (unzonedRange) { 61390 return this._view.trimHiddenDays(unzonedRange); 61391 }; 61392 DateProfileGenerator.prototype.msToUtcMoment = function (ms, forceAllDay) { 61393 return this._view.calendar.msToUtcMoment(ms, forceAllDay); 61394 }; 61395 /* Date Range Computation 61396 ------------------------------------------------------------------------------------------------------------------*/ 61397 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 61398 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile) { 61399 var prevDate = currentDateProfile.date.clone() 61400 .startOf(currentDateProfile.currentRangeUnit) 61401 .subtract(currentDateProfile.dateIncrement); 61402 return this.build(prevDate, -1); 61403 }; 61404 // Builds a structure with info about what the dates/ranges will be for the "next" view. 61405 DateProfileGenerator.prototype.buildNext = function (currentDateProfile) { 61406 var nextDate = currentDateProfile.date.clone() 61407 .startOf(currentDateProfile.currentRangeUnit) 61408 .add(currentDateProfile.dateIncrement); 61409 return this.build(nextDate, 1); 61410 }; 61411 // Builds a structure holding dates/ranges for rendering around the given date. 61412 // Optional direction param indicates whether the date is being incremented/decremented 61413 // from its previous value. decremented = -1, incremented = 1 (default). 61414 DateProfileGenerator.prototype.build = function (date, direction, forceToValid) { 61415 if (forceToValid === void 0) { forceToValid = false; } 61416 var isDateAllDay = !date.hasTime(); 61417 var validUnzonedRange; 61418 var minTime = null; 61419 var maxTime = null; 61420 var currentInfo; 61421 var isRangeAllDay; 61422 var renderUnzonedRange; 61423 var activeUnzonedRange; 61424 var isValid; 61425 validUnzonedRange = this.buildValidRange(); 61426 validUnzonedRange = this.trimHiddenDays(validUnzonedRange); 61427 if (forceToValid) { 61428 date = this.msToUtcMoment(validUnzonedRange.constrainDate(date), // returns MS 61429 isDateAllDay); 61430 } 61431 currentInfo = this.buildCurrentRangeInfo(date, direction); 61432 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 61433 renderUnzonedRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.unzonedRange), currentInfo.unit, isRangeAllDay); 61434 renderUnzonedRange = this.trimHiddenDays(renderUnzonedRange); 61435 activeUnzonedRange = renderUnzonedRange.clone(); 61436 if (!this.opt('showNonCurrentDates')) { 61437 activeUnzonedRange = activeUnzonedRange.intersect(currentInfo.unzonedRange); 61438 } 61439 minTime = moment.duration(this.opt('minTime')); 61440 maxTime = moment.duration(this.opt('maxTime')); 61441 activeUnzonedRange = this.adjustActiveRange(activeUnzonedRange, minTime, maxTime); 61442 activeUnzonedRange = activeUnzonedRange.intersect(validUnzonedRange); // might return null 61443 if (activeUnzonedRange) { 61444 date = this.msToUtcMoment(activeUnzonedRange.constrainDate(date), // returns MS 61445 isDateAllDay); 61446 } 61447 // it's invalid if the originally requested date is not contained, 61448 // or if the range is completely outside of the valid range. 61449 isValid = currentInfo.unzonedRange.intersectsWith(validUnzonedRange); 61450 return { 61451 // constraint for where prev/next operations can go and where events can be dragged/resized to. 61452 // an object with optional start and end properties. 61453 validUnzonedRange: validUnzonedRange, 61454 // range the view is formally responsible for. 61455 // for example, a month view might have 1st-31st, excluding padded dates 61456 currentUnzonedRange: currentInfo.unzonedRange, 61457 // name of largest unit being displayed, like "month" or "week" 61458 currentRangeUnit: currentInfo.unit, 61459 isRangeAllDay: isRangeAllDay, 61460 // dates that display events and accept drag-n-drop 61461 // will be `null` if no dates accept events 61462 activeUnzonedRange: activeUnzonedRange, 61463 // date range with a rendered skeleton 61464 // includes not-active days that need some sort of DOM 61465 renderUnzonedRange: renderUnzonedRange, 61466 // Duration object that denotes the first visible time of any given day 61467 minTime: minTime, 61468 // Duration object that denotes the exclusive visible end time of any given day 61469 maxTime: maxTime, 61470 isValid: isValid, 61471 date: date, 61472 // how far the current date will move for a prev/next operation 61473 dateIncrement: this.buildDateIncrement(currentInfo.duration) 61474 // pass a fallback (might be null) ^ 61475 }; 61476 }; 61477 // Builds an object with optional start/end properties. 61478 // Indicates the minimum/maximum dates to display. 61479 // not responsible for trimming hidden days. 61480 DateProfileGenerator.prototype.buildValidRange = function () { 61481 return this._view.getUnzonedRangeOption('validRange', this._view.calendar.getNow()) || 61482 new UnzonedRange_1.default(); // completely open-ended 61483 }; 61484 // Builds a structure with info about the "current" range, the range that is 61485 // highlighted as being the current month for example. 61486 // See build() for a description of `direction`. 61487 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 61488 // TODO: accept a MS-time instead of a moment `date`? 61489 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) { 61490 var viewSpec = this._view.viewSpec; 61491 var duration = null; 61492 var unit = null; 61493 var unzonedRange = null; 61494 var dayCount; 61495 if (viewSpec.duration) { 61496 duration = viewSpec.duration; 61497 unit = viewSpec.durationUnit; 61498 unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit); 61499 } 61500 else if ((dayCount = this.opt('dayCount'))) { 61501 unit = 'day'; 61502 unzonedRange = this.buildRangeFromDayCount(date, direction, dayCount); 61503 } 61504 else if ((unzonedRange = this.buildCustomVisibleRange(date))) { 61505 unit = util_1.computeGreatestUnit(unzonedRange.getStart(), unzonedRange.getEnd()); 61506 } 61507 else { 61508 duration = this.getFallbackDuration(); 61509 unit = util_1.computeGreatestUnit(duration); 61510 unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit); 61511 } 61512 return { duration: duration, unit: unit, unzonedRange: unzonedRange }; 61513 }; 61514 DateProfileGenerator.prototype.getFallbackDuration = function () { 61515 return moment.duration({ days: 1 }); 61516 }; 61517 // Returns a new activeUnzonedRange to have time values (un-ambiguate) 61518 // minTime or maxTime causes the range to expand. 61519 DateProfileGenerator.prototype.adjustActiveRange = function (unzonedRange, minTime, maxTime) { 61520 var start = unzonedRange.getStart(); 61521 var end = unzonedRange.getEnd(); 61522 if (this._view.usesMinMaxTime) { 61523 if (minTime < 0) {
61524 start.time(0).add(minTime); 61525 } 61526 if (maxTime > 24 * 60 * 60 * 1000) { 61527 end.time(maxTime - (24 * 60 * 60 * 1000)); 61528 } 61529 } 61530 return new UnzonedRange_1.default(start, end); 61531 }; 61532 // Builds the "current" range when it is specified as an explicit duration. 61533 // `unit` is the already-computed computeGreatestUnit value of duration. 61534 // TODO: accept a MS-time instead of a moment `date`? 61535 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) { 61536 var alignment = this.opt('dateAlignment'); 61537 var dateIncrementInput; 61538 var dateIncrementDuration; 61539 var start; 61540 var end; 61541 var res; 61542 // compute what the alignment should be 61543 if (!alignment) { 61544 dateIncrementInput = this.opt('dateIncrement'); 61545 if (dateIncrementInput) { 61546 dateIncrementDuration = moment.duration(dateIncrementInput); 61547 // use the smaller of the two units 61548 if (dateIncrementDuration < duration) { 61549 alignment = util_1.computeDurationGreatestUnit(dateIncrementDuration, dateIncrementInput); 61550 } 61551 else { 61552 alignment = unit; 61553 } 61554 } 61555 else { 61556 alignment = unit; 61557 } 61558 } 61559 // if the view displays a single day or smaller 61560 if (duration.as('days') <= 1) { 61561 if (this._view.isHiddenDay(start)) { 61562 start = this._view.skipHiddenDays(start, direction); 61563 start.startOf('day'); 61564 } 61565 } 61566 function computeRes() { 61567 start = date.clone().startOf(alignment); 61568 end = start.clone().add(duration); 61569 res = new UnzonedRange_1.default(start, end); 61570 } 61571 computeRes(); 61572 // if range is completely enveloped by hidden days, go past the hidden days 61573 if (!this.trimHiddenDays(res)) { 61574 date = this._view.skipHiddenDays(date, direction); 61575 computeRes(); 61576 } 61577 return res; 61578 }; 61579 // Builds the "current" range when a dayCount is specified. 61580 // TODO: accept a MS-time instead of a moment `date`? 61581 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) { 61582 var customAlignment = this.opt('dateAlignment'); 61583 var runningCount = 0; 61584 var start = date.clone(); 61585 var end; 61586 if (customAlignment) { 61587 start.startOf(customAlignment); 61588 } 61589 start.startOf('day'); 61590 start = this._view.skipHiddenDays(start, direction); 61591 end = start.clone(); 61592 do { 61593 end.add(1, 'day'); 61594 if (!this._view.isHiddenDay(end)) { 61595 runningCount++; 61596 } 61597 } while (runningCount < dayCount); 61598 return new UnzonedRange_1.default(start, end); 61599 }; 61600 // Builds a normalized range object for the "visible" range, 61601 // which is a way to define the currentUnzonedRange and activeUnzonedRange at the same time. 61602 // TODO: accept a MS-time instead of a moment `date`? 61603 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { 61604 var visibleUnzonedRange = this._view.getUnzonedRangeOption('visibleRange', this._view.calendar.applyTimezone(date) // correct zone. also generates new obj that avoids mutations 61605 ); 61606 if (visibleUnzonedRange && (visibleUnzonedRange.startMs == null || visibleUnzonedRange.endMs == null)) { 61607 return null; 61608 } 61609 return visibleUnzonedRange; 61610 }; 61611 // Computes the range that will represent the element/cells for *rendering*, 61612 // but which may have voided days/times. 61613 // not responsible for trimming hidden days. 61614 DateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { 61615 return currentUnzonedRange.clone(); 61616 }; 61617 // Compute the duration value that should be added/substracted to the current date 61618 // when a prev/next operation happens. 61619 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { 61620 var dateIncrementInput = this.opt('dateIncrement'); 61621 var customAlignment; 61622 if (dateIncrementInput) { 61623 return moment.duration(dateIncrementInput); 61624 } 61625 else if ((customAlignment = this.opt('dateAlignment'))) { 61626 return moment.duration(1, customAlignment); 61627 } 61628 else if (fallback) { 61629 return fallback; 61630 } 61631 else { 61632 return moment.duration({ days: 1 }); 61633 } 61634 }; 61635 return DateProfileGenerator; 61636}()); 61637exports.default = DateProfileGenerator; 61638 61639 61640/***/ }), 61641/* 222 */ 61642/***/ (function(module, exports, __webpack_require__) { 61643 61644Object.defineProperty(exports, "__esModule", { value: true });
61645var tslib_1 = __webpack_require__(2); 61646var $ = __webpack_require__(3); 61647var moment = __webpack_require__(0); 61648var exportHooks = __webpack_require__(16); 61649var util_1 = __webpack_require__(4); 61650var moment_ext_1 = __webpack_require__(10); 61651var ListenerMixin_1 = __webpack_require__(7); 61652var HitDragListener_1 = __webpack_require__(23); 61653var SingleEventDef_1 = __webpack_require__(13); 61654var EventInstanceGroup_1 = __webpack_require__(18); 61655var EventSource_1 = __webpack_require__(6); 61656var Interaction_1 = __webpack_require__(15); 61657var ExternalDropping = /** @class */ (function (_super) { 61658 tslib_1.__extends(ExternalDropping, _super); 61659 function ExternalDropping() { 61660 var _this = _super !== null && _super.apply(this, arguments) || this; 61661 _this.isDragging = false; // jqui-dragging an external element? boolean 61662 return _this; 61663 } 61664 /* 61665 component impements: 61666 - eventRangesToEventFootprints 61667 - isEventInstanceGroupAllowed 61668 - isExternalInstanceGroupAllowed 61669 - renderDrag 61670 - unrenderDrag 61671 */ 61672 ExternalDropping.prototype.end = function () { 61673 if (this.dragListener) { 61674 this.dragListener.endInteraction(); 61675 } 61676 }; 61677 ExternalDropping.prototype.bindToDocument = function () { 61678 this.listenTo($(document), { 61679 dragstart: this.handleDragStart, 61680 sortstart: this.handleDragStart // jqui 61681 }); 61682 }; 61683 ExternalDropping.prototype.unbindFromDocument = function () { 61684 this.stopListeningTo($(document)); 61685 }; 61686 // Called when a jQuery UI drag is initiated anywhere in the DOM 61687 ExternalDropping.prototype.handleDragStart = function (ev, ui) { 61688 var el; 61689 var accept; 61690 if (this.opt('droppable')) { 61691 el = $((ui ? ui.item : null) || ev.target); 61692 // Test that the dragged element passes the dropAccept selector or filter function. 61693 // FYI, the default is "*" (matches all) 61694 accept = this.opt('dropAccept'); 61695 if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) { 61696 if (!this.isDragging) { 61697 this.listenToExternalDrag(el, ev, ui); 61698 } 61699 } 61700 } 61701 }; 61702 // Called when a jQuery UI drag starts and it needs to be monitored for dropping 61703 ExternalDropping.prototype.listenToExternalDrag = function (el, ev, ui) { 61704 var _this = this; 61705 var component = this.component; 61706 var view = this.view; 61707 var meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create 61708 var singleEventDef; // a null value signals an unsuccessful drag 61709 // listener that tracks mouse movement over date-associated pixel regions 61710 var dragListener = this.dragListener = new HitDragListener_1.default(component, { 61711 interactionStart: function () { 61712 _this.isDragging = true; 61713 }, 61714 hitOver: function (hit) { 61715 var isAllowed = true; 61716 var hitFootprint = hit.component.getSafeHitFootprint(hit); // hit might not belong to this grid 61717 var mutatedEventInstanceGroup; 61718 if (hitFootprint) { 61719 singleEventDef = _this.computeExternalDrop(hitFootprint, meta); 61720 if (singleEventDef) { 61721 mutatedEventInstanceGroup = new EventInstanceGroup_1.default(singleEventDef.buildInstances()); 61722 isAllowed = meta.eventProps ? // isEvent? 61723 component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup) : 61724 component.isExternalInstanceGroupAllowed(mutatedEventInstanceGroup); 61725 } 61726 else { 61727 isAllowed = false; 61728 } 61729 } 61730 else { 61731 isAllowed = false; 61732 } 61733 if (!isAllowed) { 61734 singleEventDef = null;
61735 util_1.disableCursor(); 61736 } 61737 if (singleEventDef) { 61738 component.renderDrag(// called without a seg parameter 61739 component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, view.calendar))); 61740 } 61741 }, 61742 hitOut: function () { 61743 singleEventDef = null; // signal unsuccessful 61744 }, 61745 hitDone: function () { 61746 util_1.enableCursor(); 61747 component.unrenderDrag(); 61748 }, 61749 interactionEnd: function (ev) { 61750 if (singleEventDef) { 61751 view.reportExternalDrop(singleEventDef, Boolean(meta.eventProps), // isEvent 61752 Boolean(meta.stick), // isSticky 61753 el, ev, ui); 61754 } 61755 _this.isDragging = false; 61756 _this.dragListener = null; 61757 } 61758 }); 61759 dragListener.startDrag(ev); // start listening immediately 61760 }; 61761 // Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object), 61762 // returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null. 61763 // Returning a null value signals an invalid drop hit. 61764 // DOES NOT consider overlap/constraint. 61765 // Assumes both footprints are non-open-ended. 61766 ExternalDropping.prototype.computeExternalDrop = function (componentFootprint, meta) { 61767 var calendar = this.view.calendar; 61768 var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs).stripZone(); 61769 var end; 61770 var eventDef; 61771 if (componentFootprint.isAllDay) { 61772 // if dropped on an all-day span, and element's metadata specified a time, set it 61773 if (meta.startTime) { 61774 start.time(meta.startTime); 61775 } 61776 else { 61777 start.stripTime(); 61778 } 61779 } 61780 if (meta.duration) { 61781 end = start.clone().add(meta.duration); 61782 } 61783 start = calendar.applyTimezone(start); 61784 if (end) { 61785 end = calendar.applyTimezone(end); 61786 } 61787 eventDef = SingleEventDef_1.default.parse($.extend({}, meta.eventProps, { 61788 start: start, 61789 end: end 61790 }), new EventSource_1.default(calendar)); 61791 return eventDef; 61792 }; 61793 return ExternalDropping; 61794}(Interaction_1.default)); 61795exports.default = ExternalDropping; 61796ListenerMixin_1.default.mixInto(ExternalDropping); 61797/* External-Dragging-Element Data 61798----------------------------------------------------------------------------------------------------------------------*/ 61799// Require all HTML5 data-* attributes used by FullCalendar to have this prefix. 61800// A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event. 61801exportHooks.dataAttrPrefix = ''; 61802// Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure 61803// to be used for Event Object creation. 61804// A defined `.eventProps`, even when empty, indicates that an event should be created. 61805function getDraggedElMeta(el) { 61806 var prefix = exportHooks.dataAttrPrefix; 61807 var eventProps; // properties for creating the event, not related to date/time 61808 var startTime; // a Duration 61809 var duration; 61810 var stick; 61811 if (prefix) { 61812 prefix += '-'; 61813 } 61814 eventProps = el.data(prefix + 'event') || null; 61815 if (eventProps) { 61816 if (typeof eventProps === 'object') { 61817 eventProps = $.extend({}, eventProps); // make a copy 61818 } 61819 else { 61820 eventProps = {}; 61821 } 61822 // pluck special-cased date/time properties 61823 startTime = eventProps.start; 61824 if (startTime == null) { 61825 startTime = eventProps.time; 61826 } // accept 'time' as well 61827 duration = eventProps.duration; 61828 stick = eventProps.stick; 61829 delete eventProps.start; 61830 delete eventProps.time; 61831 delete eventProps.duration; 61832 delete eventProps.stick; 61833 } 61834 // fallback to standalone attribute values for each of the date/time properties 61835 if (startTime == null) { 61836 startTime = el.data(prefix + 'start'); 61837 } 61838 if (startTime == null) { 61839 startTime = el.data(prefix + 'time'); 61840 } // accept 'time' as well 61841 if (duration == null) { 61842 duration = el.data(prefix + 'duration'); 61843 } 61844 if (stick == null) { 61845 stick = el.data(prefix + 'stick'); 61846 } 61847 // massage into correct data types 61848 startTime = startTime != null ? moment.duration(startTime) : null; 61849 duration = duration != null ? moment.duration(duration) : null; 61850 stick = Boolean(stick); 61851 return { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick }; 61852} 61853 61854 61855/***/ }), 61856/* 223 */ 61857/***/ (function(module, exports, __webpack_require__) { 61858 61859Object.defineProperty(exports, "__esModule", { value: true });
61860var tslib_1 = __webpack_require__(2); 61861var $ = __webpack_require__(3); 61862var util_1 = __webpack_require__(4); 61863var EventDefMutation_1 = __webpack_require__(37); 61864var EventDefDateMutation_1 = __webpack_require__(50); 61865var HitDragListener_1 = __webpack_require__(23); 61866var Interaction_1 = __webpack_require__(15); 61867var EventResizing = /** @class */ (function (_super) { 61868 tslib_1.__extends(EventResizing, _super); 61869 /* 61870 component impements: 61871 - bindSegHandlerToEl 61872 - publiclyTrigger 61873 - diffDates 61874 - eventRangesToEventFootprints 61875 - isEventInstanceGroupAllowed 61876 - getSafeHitFootprint 61877 */ 61878 function EventResizing(component, eventPointing) { 61879 var _this = _super.call(this, component) || this; 61880 _this.isResizing = false; 61881 _this.eventPointing = eventPointing; 61882 return _this; 61883 } 61884 EventResizing.prototype.end = function () { 61885 if (this.dragListener) { 61886 this.dragListener.endInteraction(); 61887 } 61888 }; 61889 EventResizing.prototype.bindToEl = function (el) { 61890 var component = this.component; 61891 component.bindSegHandlerToEl(el, 'mousedown', this.handleMouseDown.bind(this)); 61892 component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this)); 61893 }; 61894 EventResizing.prototype.handleMouseDown = function (seg, ev) { 61895 if (this.component.canStartResize(seg, ev)) { 61896 this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer')) 61897 .startInteraction(ev, { distance: 5 }); 61898 } 61899 }; 61900 EventResizing.prototype.handleTouchStart = function (seg, ev) { 61901 if (this.component.canStartResize(seg, ev)) { 61902 this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer')) 61903 .startInteraction(ev); 61904 } 61905 }; 61906 // Creates a listener that tracks the user as they resize an event segment. 61907 // Generic enough to work with any type of Grid. 61908 EventResizing.prototype.buildDragListener = function (seg, isStart) { 61909 var _this = this; 61910 var component = this.component; 61911 var view = this.view; 61912 var calendar = view.calendar; 61913 var eventManager = calendar.eventManager; 61914 var el = seg.el; 61915 var eventDef = seg.footprint.eventDef; 61916 var eventInstance = seg.footprint.eventInstance; 61917 var isDragging; 61918 var resizeMutation; // zoned event date properties. falsy if invalid resize 61919 // Tracks mouse movement over the *grid's* coordinate map 61920 var dragListener = this.dragListener = new HitDragListener_1.default(component, { 61921 scroll: this.opt('dragScroll'), 61922 subjectEl: el, 61923 interactionStart: function () { 61924 isDragging = false; 61925 }, 61926 dragStart: function (ev) { 61927 isDragging = true; 61928 // ensure a mouseout on the manipulated event has been reported 61929 _this.eventPointing.handleMouseout(seg, ev); 61930 _this.segResizeStart(seg, ev); 61931 }, 61932 hitOver: function (hit, isOrig, origHit) { 61933 var isAllowed = true; 61934 var origHitFootprint = component.getSafeHitFootprint(origHit); 61935 var hitFootprint = component.getSafeHitFootprint(hit); 61936 var mutatedEventInstanceGroup; 61937 if (origHitFootprint && hitFootprint) { 61938 resizeMutation = isStart ? 61939 _this.computeEventStartResizeMutation(origHitFootprint, hitFootprint, seg.footprint) : 61940 _this.computeEventEndResizeMutation(origHitFootprint, hitFootprint, seg.footprint); 61941 if (resizeMutation) { 61942 mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, resizeMutation); 61943 isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup); 61944 } 61945 else { 61946 isAllowed = false; 61947 } 61948 } 61949 else { 61950 isAllowed = false; 61951 } 61952 if (!isAllowed) { 61953 resizeMutation = null;
61954 util_1.disableCursor(); 61955 } 61956 else if (resizeMutation.isEmpty()) { 61957 // no change. (FYI, event dates might have zones) 61958 resizeMutation = null; 61959 } 61960 if (resizeMutation) { 61961 view.hideEventsWithId(seg.footprint.eventDef.id); 61962 view.renderEventResize(component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg); 61963 } 61964 }, 61965 hitOut: function () { 61966 resizeMutation = null; 61967 }, 61968 hitDone: function () { 61969 view.unrenderEventResize(seg); 61970 view.showEventsWithId(seg.footprint.eventDef.id); 61971 util_1.enableCursor(); 61972 }, 61973 interactionEnd: function (ev) { 61974 if (isDragging) { 61975 _this.segResizeStop(seg, ev); 61976 } 61977 if (resizeMutation) { 61978 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait 61979 view.reportEventResize(eventInstance, resizeMutation, el, ev); 61980 } 61981 _this.dragListener = null; 61982 } 61983 }); 61984 return dragListener; 61985 }; 61986 // Called before event segment resizing starts 61987 EventResizing.prototype.segResizeStart = function (seg, ev) { 61988 this.isResizing = true; 61989 this.component.publiclyTrigger('eventResizeStart', { 61990 context: seg.el[0], 61991 args: [ 61992 seg.footprint.getEventLegacy(), 61993 ev, 61994 {}, 61995 this.view 61996 ] 61997 }); 61998 }; 61999 // Called after event segment resizing stops 62000 EventResizing.prototype.segResizeStop = function (seg, ev) { 62001 this.isResizing = false; 62002 this.component.publiclyTrigger('eventResizeStop', { 62003 context: seg.el[0], 62004 args: [ 62005 seg.footprint.getEventLegacy(), 62006 ev, 62007 {}, 62008 this.view 62009 ] 62010 }); 62011 }; 62012 // Returns new date-information for an event segment being resized from its start 62013 EventResizing.prototype.computeEventStartResizeMutation = function (startFootprint, endFootprint, origEventFootprint) { 62014 var origRange = origEventFootprint.componentFootprint.unzonedRange; 62015 var startDelta = this.component.diffDates(endFootprint.unzonedRange.getStart(), startFootprint.unzonedRange.getStart()); 62016 var dateMutation; 62017 var eventDefMutation; 62018 if (origRange.getStart().add(startDelta) < origRange.getEnd()) { 62019 dateMutation = new EventDefDateMutation_1.default(); 62020 dateMutation.setStartDelta(startDelta); 62021 eventDefMutation = new EventDefMutation_1.default(); 62022 eventDefMutation.setDateMutation(dateMutation); 62023 return eventDefMutation; 62024 } 62025 return false; 62026 }; 62027 // Returns new date-information for an event segment being resized from its end 62028 EventResizing.prototype.computeEventEndResizeMutation = function (startFootprint, endFootprint, origEventFootprint) { 62029 var origRange = origEventFootprint.componentFootprint.unzonedRange; 62030 var endDelta = this.component.diffDates(endFootprint.unzonedRange.getEnd(), startFootprint.unzonedRange.getEnd()); 62031 var dateMutation; 62032 var eventDefMutation; 62033 if (origRange.getEnd().add(endDelta) > origRange.getStart()) { 62034 dateMutation = new EventDefDateMutation_1.default(); 62035 dateMutation.setEndDelta(endDelta); 62036 eventDefMutation = new EventDefMutation_1.default(); 62037 eventDefMutation.setDateMutation(dateMutation); 62038 return eventDefMutation; 62039 } 62040 return false; 62041 }; 62042 return EventResizing; 62043}(Interaction_1.default)); 62044exports.default = EventResizing; 62045 62046 62047/***/ }), 62048/* 224 */ 62049/***/ (function(module, exports, __webpack_require__) { 62050 62051Object.defineProperty(exports, "__esModule", { value: true });
62052var tslib_1 = __webpack_require__(2); 62053var util_1 = __webpack_require__(4); 62054var EventDefMutation_1 = __webpack_require__(37); 62055var EventDefDateMutation_1 = __webpack_require__(50); 62056var DragListener_1 = __webpack_require__(54); 62057var HitDragListener_1 = __webpack_require__(23); 62058var MouseFollower_1 = __webpack_require__(244); 62059var Interaction_1 = __webpack_require__(15); 62060var EventDragging = /** @class */ (function (_super) { 62061 tslib_1.__extends(EventDragging, _super); 62062 /* 62063 component implements: 62064 - bindSegHandlerToEl 62065 - publiclyTrigger 62066 - diffDates 62067 - eventRangesToEventFootprints 62068 - isEventInstanceGroupAllowed 62069 */ 62070 function EventDragging(component, eventPointing) { 62071 var _this = _super.call(this, component) || this; 62072 _this.isDragging = false; 62073 _this.eventPointing = eventPointing; 62074 return _this; 62075 } 62076 EventDragging.prototype.end = function () { 62077 if (this.dragListener) { 62078 this.dragListener.endInteraction(); 62079 } 62080 }; 62081 EventDragging.prototype.getSelectionDelay = function () { 62082 var delay = this.opt('eventLongPressDelay'); 62083 if (delay == null) { 62084 delay = this.opt('longPressDelay'); // fallback 62085 } 62086 return delay; 62087 }; 62088 EventDragging.prototype.bindToEl = function (el) { 62089 var component = this.component; 62090 component.bindSegHandlerToEl(el, 'mousedown', this.handleMousedown.bind(this)); 62091 component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this)); 62092 }; 62093 EventDragging.prototype.handleMousedown = function (seg, ev) { 62094 if (!this.component.shouldIgnoreMouse() && 62095 this.component.canStartDrag(seg, ev)) { 62096 this.buildDragListener(seg).startInteraction(ev, { distance: 5 }); 62097 } 62098 }; 62099 EventDragging.prototype.handleTouchStart = function (seg, ev) { 62100 var component = this.component; 62101 var settings = { 62102 delay: this.view.isEventDefSelected(seg.footprint.eventDef) ? // already selected? 62103 0 : this.getSelectionDelay() 62104 }; 62105 if (component.canStartDrag(seg, ev)) { 62106 this.buildDragListener(seg).startInteraction(ev, settings); 62107 } 62108 else if (component.canStartSelection(seg, ev)) { 62109 this.buildSelectListener(seg).startInteraction(ev, settings); 62110 } 62111 }; 62112 // seg isn't draggable, but let's use a generic DragListener 62113 // simply for the delay, so it can be selected. 62114 // Has side effect of setting/unsetting `dragListener` 62115 EventDragging.prototype.buildSelectListener = function (seg) { 62116 var _this = this; 62117 var view = this.view; 62118 var eventDef = seg.footprint.eventDef; 62119 var eventInstance = seg.footprint.eventInstance; // null for inverse-background events 62120 if (this.dragListener) { 62121 return this.dragListener; 62122 } 62123 var dragListener = this.dragListener = new DragListener_1.default({ 62124 dragStart: function (ev) { 62125 if (dragListener.isTouch && 62126 !view.isEventDefSelected(eventDef) && 62127 eventInstance) { 62128 // if not previously selected, will fire after a delay. then, select the event 62129 view.selectEventInstance(eventInstance); 62130 } 62131 }, 62132 interactionEnd: function (ev) { 62133 _this.dragListener = null; 62134 } 62135 }); 62136 return dragListener; 62137 }; 62138 // Builds a listener that will track user-dragging on an event segment. 62139 // Generic enough to work with any type of Grid. 62140 // Has side effect of setting/unsetting `dragListener` 62141 EventDragging.prototype.buildDragListener = function (seg) { 62142 var _this = this; 62143 var component = this.component; 62144 var view = this.view; 62145 var calendar = view.calendar; 62146 var eventManager = calendar.eventManager; 62147 var el = seg.el; 62148 var eventDef = seg.footprint.eventDef; 62149 var eventInstance = seg.footprint.eventInstance; // null for inverse-background events 62150 var isDragging; 62151 var mouseFollower; // A clone of the original element that will move with the mouse 62152 var eventDefMutation; 62153 if (this.dragListener) { 62154 return this.dragListener; 62155 } 62156 // Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents 62157 // of the view. 62158 var dragListener = this.dragListener = new HitDragListener_1.default(view, { 62159 scroll: this.opt('dragScroll'), 62160 subjectEl: el, 62161 subjectCenter: true, 62162 interactionStart: function (ev) { 62163 seg.component = component; // for renderDrag 62164 isDragging = false; 62165 mouseFollower = new MouseFollower_1.default(seg.el, { 62166 additionalClass: 'fc-dragging', 62167 parentEl: view.el, 62168 opacity: dragListener.isTouch ? null : _this.opt('dragOpacity'), 62169 revertDuration: _this.opt('dragRevertDuration'), 62170 zIndex: 2 // one above the .fc-view 62171 }); 62172 mouseFollower.hide(); // don't show until we know this is a real drag 62173 mouseFollower.start(ev); 62174 }, 62175 dragStart: function (ev) { 62176 if (dragListener.isTouch && 62177 !view.isEventDefSelected(eventDef) && 62178 eventInstance) { 62179 // if not previously selected, will fire after a delay. then, select the event 62180 view.selectEventInstance(eventInstance); 62181 } 62182 isDragging = true; 62183 // ensure a mouseout on the manipulated event has been reported 62184 _this.eventPointing.handleMouseout(seg, ev); 62185 _this.segDragStart(seg, ev); 62186 view.hideEventsWithId(seg.footprint.eventDef.id); 62187 }, 62188 hitOver: function (hit, isOrig, origHit) { 62189 var isAllowed = true; 62190 var origFootprint; 62191 var footprint; 62192 var mutatedEventInstanceGroup; 62193 // starting hit could be forced (DayGrid.limit) 62194 if (seg.hit) { 62195 origHit = seg.hit; 62196 } 62197 // hit might not belong to this grid, so query origin grid 62198 origFootprint = origHit.component.getSafeHitFootprint(
62198origHit); 62199 footprint = hit.component.getSafeHitFootprint(hit); 62200 if (origFootprint && footprint) { 62201 eventDefMutation = _this.computeEventDropMutation(origFootprint, footprint, eventDef); 62202 if (eventDefMutation) { 62203 mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, eventDefMutation); 62204 isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup); 62205 } 62206 else { 62207 isAllowed = false; 62208 } 62209 } 62210 else { 62211 isAllowed = false; 62212 } 62213 if (!isAllowed) { 62214 eventDefMutation = null; 62215 util_1.disableCursor(); 62216 } 62217 // if a valid drop location, have the subclass render a visual indication 62218 if (eventDefMutation && 62219 view.renderDrag(// truthy if rendered something 62220 component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg, dragListener.isTouch)) { 62221 mouseFollower.hide(); // if the subclass is already using a mock event "helper", hide our own 62222 } 62223 else { 62224 mouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping) 62225 } 62226 if (isOrig) { 62227 // needs to have moved hits to be a valid drop 62228 eventDefMutation = null; 62229 } 62230 }, 62231 hitOut: function () { 62232 view.unrenderDrag(seg); // unrender whatever was done in renderDrag 62233 mouseFollower.show(); // show in case we are moving out of all hits 62234 eventDefMutation = null; 62235 }, 62236 hitDone: function () { 62237 util_1.enableCursor(); 62238 }, 62239 interactionEnd: function (ev) { 62240 delete seg.component; // prevent side effects 62241 // do revert animation if hasn't changed. calls a callback when finished (whether animation or not) 62242 mouseFollower.stop(!eventDefMutation, function () { 62243 if (isDragging) { 62244 view.unrenderDrag(seg); 62245 _this.segDragStop(seg, ev); 62246 } 62247 view.showEventsWithId(seg.footprint.eventDef.id); 62248 if (eventDefMutation) { 62249 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait 62250 view.reportEventDrop(eventInstance, eventDefMutation, el, ev); 62251 } 62252 }); 62253 _this.dragListener = null; 62254 } 62255 }); 62256 return dragListener; 62257 }; 62258 // Called before event segment dragging starts 62259 EventDragging.prototype.segDragStart = function (seg, ev) { 62260 this.isDragging = true; 62261 this.component.publiclyTrigger('eventDragStart', { 62262 context: seg.el[0], 62263 args: [ 62264 seg.footprint.getEventLegacy(), 62265 ev, 62266 {}, 62267 this.view 62268 ] 62269 }); 62270 }; 62271 // Called after event segment dragging stops 62272 EventDragging.prototype.segDragStop = function (seg, ev) { 62273 this.isDragging = false; 62274 this.component.publiclyTrigger('eventDragStop', { 62275 context: seg.el[0], 62276 args: [ 62277 seg.footprint.getEventLegacy(), 62278 ev, 62279 {}, 62280 this.view 62281 ] 62282 }); 62283 }; 62284 // DOES NOT consider overlap/constraint 62285 EventDragging.prototype.computeEventDropMutation = function (startFootprint, endFootprint, eventDef) { 62286 var eventDefMutation = new EventDefMutation_1.default(); 62287 eventDefMutation.setDateMutation(this.computeEventDateMutation(startFootprint, endFootprint)); 62288 return eventDefMutation; 62289 }; 62290 EventDragging.prototype.computeEventDateMutation = function (startFootprint, endFootprint) { 62291 var date0 = startFootprint.unzonedRange.getStart(); 62292 var date1 = endFootprint.unzonedRange.getStart(); 62293 var clearEnd = false; 62294 var forceTimed = false; 62295 var forceAllDay = false; 62296 var dateDelta; 62297 var dateMutation; 62298 if (startFootprint.isAllDay !== endFootprint.isAllDay) { 62299 clearEnd = true; 62300 if (endFootprint.isAllDay) { 62301 forceAllDay = true; 62302 date0.stripTime(); 62303 } 62304 else { 62305 forceTimed = true; 62306 } 62307 } 62308 dateDelta = this.component.diffDates(date1, date0); 62309 dateMutation = new EventDefDateMutation_1.default(); 62310 dateMutation.clearEnd = clearEnd; 62311 dateMutation.forceTimed = forceTimed; 62312 dateMutation.forceAllDay = forceAllDay; 62313 dateMutation.setDateDelta(dateDelta); 62314 return dateMutation; 62315 }; 62316 return EventDragging; 62317}(Interaction_1.default)); 62318exports.default = EventDragging; 62319 62320 62321/***/ }), 62322/* 225 */ 62323/***/ (function(module, exports, __webpack_require__) { 62324 62325Object.defineProperty(exports, "__esModule", { value: true });
62326var tslib_1 = __webpack_require__(2); 62327var util_1 = __webpack_require__(4); 62328var HitDragListener_1 = __webpack_require__(23); 62329var ComponentFootprint_1 = __webpack_require__(12); 62330var UnzonedRange_1 = __webpack_require__(5); 62331var Interaction_1 = __webpack_require__(15); 62332var DateSelecting = /** @class */ (function (_super) { 62333 tslib_1.__extends(DateSelecting, _super); 62334 /* 62335 component must implement: 62336 - bindDateHandlerToEl 62337 - getSafeHitFootprint 62338 - renderHighlight 62339 - unrenderHighlight 62340 */ 62341 function DateSelecting(component) { 62342 var _this = _super.call(this, component) || this; 62343 _this.dragListener = _this.buildDragListener(); 62344 return _this; 62345 } 62346 DateSelecting.prototype.end = function () { 62347 this.dragListener.endInteraction(); 62348 }; 62349 DateSelecting.prototype.getDelay = function () { 62350 var delay = this.opt('selectLongPressDelay'); 62351 if (delay == null) { 62352 delay = this.opt('longPressDelay'); // fallback 62353 } 62354 return delay; 62355 }; 62356 DateSelecting.prototype.bindToEl = function (el) { 62357 var _this = this; 62358 var component = this.component; 62359 var dragListener = this.dragListener; 62360 component.bindDateHandlerToEl(el, 'mousedown', function (ev) { 62361 if (_this.opt('selectable') && !component.shouldIgnoreMouse()) { 62362 dragListener.startInteraction(ev, { 62363 distance: _this.opt('selectMinDistance') 62364 }); 62365 } 62366 }); 62367 component.bindDateHandlerToEl(el, 'touchstart', function (ev) { 62368 if (_this.opt('selectable') && !component.shouldIgnoreTouch()) { 62369 dragListener.startInteraction(ev, { 62370 delay: _this.getDelay() 62371 }); 62372 } 62373 }); 62374 util_1.preventSelection(el); 62375 }; 62376 // Creates a listener that tracks the user's drag across day elements, for day selecting. 62377 DateSelecting.prototype.buildDragListener = function () { 62378 var _this = this; 62379 var component = this.component; 62380 var selectionFootprint; // null if invalid selection 62381 var dragListener = new HitDragListener_1.default(component, { 62382 scroll: this.opt('dragScroll'), 62383 interactionStart: function () { 62384 selectionFootprint = null; 62385 }, 62386 dragStart: function (ev) { 62387 _this.view.unselect(ev); // since we could be rendering a new selection, we want to clear any old one 62388 }, 62389 hitOver: function (hit, isOrig, origHit) { 62390 var origHitFootprint; 62391 var hitFootprint; 62392 if (origHit) { 62393 origHitFootprint = component.getSafeHitFootprint(origHit); 62394 hitFootprint = component.getSafeHitFootprint(hit); 62395 if (origHitFootprint && hitFootprint) { 62396 selectionFootprint = _this.computeSelection(origHitFootprint, hitFootprint); 62397 } 62398 else { 62399 selectionFootprint = null; 62400 } 62401 if (selectionFootprint) { 62402 component.renderSelectionFootprint(selectionFootprint); 62403 } 62404 else if (selectionFootprint === false) { 62405 util_1.disableCursor(); 62406 } 62407 } 62408 }, 62409 hitOut: function () { 62410 selectionFootprint = null; 62411 component.unrenderSelection(); 62412 }, 62413 hitDone: function () { 62414 util_1.enableCursor(); 62415 }, 62416 interactionEnd: function (ev, isCancelled) { 62417 if (!isCancelled && selectionFootprint) { 62418 // the selection will already have been rendered. just report it 62419 _this.view.reportSelection(selectionFootprint, ev); 62420 } 62421 } 62422 }); 62423 return dragListener; 62424 }; 62425 // Given the first and last date-spans of a selection, returns another date-span object. 62426 // Subclasses can override and provide additional data in the span object. Will be passed to render
62426SelectionFootprint(). 62427 // Will return false if the selection is invalid and this should be indicated to the user. 62428 // Will return null/undefined if a selection invalid but no error should be reported. 62429 DateSelecting.prototype.computeSelection = function (footprint0, footprint1) { 62430 var wholeFootprint = this.computeSelectionFootprint(footprint0, footprint1); 62431 if (wholeFootprint && !this.isSelectionFootprintAllowed(wholeFootprint)) { 62432 return false; 62433 } 62434 return wholeFootprint; 62435 }; 62436 // Given two spans, must return the combination of the two. 62437 // TODO: do this separation of concerns (combining VS validation) for event dnd/resize too. 62438 // Assumes both footprints are non-open-ended. 62439 DateSelecting.prototype.computeSelectionFootprint = function (footprint0, footprint1) { 62440 var ms = [ 62441 footprint0.unzonedRange.startMs, 62442 footprint0.unzonedRange.endMs, 62443 footprint1.unzonedRange.startMs, 62444 footprint1.unzonedRange.endMs 62445 ]; 62446 ms.sort(util_1.compareNumbers); 62447 return new ComponentFootprint_1.default(new UnzonedRange_1.default(ms[0], ms[3]), footprint0.isAllDay); 62448 }; 62449 DateSelecting.prototype.isSelectionFootprintAllowed = function (componentFootprint) { 62450 return this.component.dateProfile.validUnzonedRange.containsRange(componentFootprint.unzonedRange) && 62451 this.view.calendar.constraints.isSelectionFootprintAllowed(componentFootprint); 62452 }; 62453 return DateSelecting; 62454}(Interaction_1.default)); 62455exports.default = DateSelecting; 62456 62457 62458/***/ }), 62459/* 226 */ 62460/***/ (function(module, exports, __webpack_require__) { 62461 62462Object.defineProperty(exports, "__esModule", { value: true }); 62463var tslib_1 = __webpack_require__(2); 62464var moment = __webpack_require__(0); 62465var $ = __webpack_require__(3); 62466var util_1 = __webpack_require__(4); 62467var Scroller_1 = __webpack_require__(39); 62468var View_1 = __webpack_require__(41); 62469var TimeGrid_1 = __webpack_require__(227); 62470var DayGrid_1 = __webpack_require__(61); 62471var AGENDA_ALL_DAY_EVENT_LIMIT = 5; 62472var agendaTimeGridMethods; 62473var agendaDayGridMethods; 62474/* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically. 62475----------------------------------------------------------------------------------------------------------------------*/ 62476// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on). 62477// Responsible for managing width/height. 62478var AgendaView = /** @class */ (function (_super) { 62479 tslib_1.__extends(AgendaView, _super); 62480 function AgendaView(calendar, viewSpec) { 62481 var _this = _super.call(this, calendar, viewSpec) || this; 62482 _this.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering 62483 _this.timeGrid = _this.instantiateTimeGrid(); 62484 _this.addChild(_this.timeGrid); 62485 if (_this.opt('allDaySlot')) { 62486 _this.dayGrid = _this.instantiateDayGrid(); // the all-day subcomponent of this view 62487 _this.addChild(_this.dayGrid); 62488 } 62489 _this.scroller = new Scroller_1.default({ 62490 overflowX: 'hidden', 62491 overflowY: 'auto' 62492 }); 62493 return _this; 62494 } 62495 // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass 62496 AgendaView.prototype.instantiateTimeGrid = function () { 62497 var timeGrid = new this.timeGridClass(this); 62498 util_1.copyOwnProps(agendaTimeGridMethods, timeGrid); 62499 return timeGrid; 62500 }; 62501 // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass 62502 AgendaView.prototype.instantiateDayGrid = function () { 62503 var dayGrid = new this.dayGridClass(this); 62504 util_1.copyOwnProps(agendaDayGridMethods, dayGrid); 62505 return dayGrid; 62506 }; 62507 /* Rendering 62508 ------------------------------------------------------------------------------------------------------------------*/ 62509 AgendaView.prototype.renderSkeleton = function () { 62510 var timeGridWrapEl; 62511 var timeGridEl; 62512 this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml()); 62513 this.scroller.render(); 62514 timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container');
62515 timeGridEl = $('<div class="fc-time-grid" />').appendTo(timeGridWrapEl); 62516 this.el.find('.fc-body > tr > td').append(timeGridWrapEl); 62517 this.timeGrid.headContainerEl = this.el.find('.fc-head-container'); 62518 this.timeGrid.setElement(timeGridEl); 62519 if (this.dayGrid) { 62520 this.dayGrid.setElement(this.el.find('.fc-day-grid')); 62521 // have the day-grid extend it's coordinate area over the <hr> dividing the two grids 62522 this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight(); 62523 } 62524 }; 62525 AgendaView.prototype.unrenderSkeleton = function () { 62526 this.timeGrid.removeElement(); 62527 if (this.dayGrid) { 62528 this.dayGrid.removeElement(); 62529 } 62530 this.scroller.destroy(); 62531 }; 62532 // Builds the HTML skeleton for the view. 62533 // The day-grid and time-grid components will render inside containers defined by this HTML. 62534 AgendaView.prototype.renderSkeletonHtml = function () { 62535 var theme = this.calendar.theme; 62536 return '' + 62537 '<table class="' + theme.getClass('tableGrid') + '">' + 62538 (this.opt('columnHeader') ? 62539 '<thead class="fc-head">' + 62540 '<tr>' + 62541 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + 62542 '</tr>' + 62543 '</thead>' : 62544 '') + 62545 '<tbody class="fc-body">' + 62546 '<tr>' + 62547 '<td class="' + theme.getClass('widgetContent') + '">' + 62548 (this.dayGrid ? 62549 '<div class="fc-day-grid"/>' + 62550 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '"/>' : 62551 '') + 62552 '</td>' + 62553 '</tr>' + 62554 '</tbody>' + 62555 '</table>'; 62556 }; 62557 // Generates an HTML attribute string for setting the width of the axis, if it is known 62558 AgendaView.prototype.axisStyleAttr = function () { 62559 if (this.axisWidth != null) { 62560 return 'style="width:' + this.axisWidth + 'px"'; 62561 } 62562 return ''; 62563 }; 62564 /* Now Indicator 62565 ------------------------------------------------------------------------------------------------------------------*/ 62566 AgendaView.prototype.getNowIndicatorUnit = function () { 62567 return this.timeGrid.getNowIndicatorUnit(); 62568 }; 62569 /* Dimensions 62570 ------------------------------------------------------------------------------------------------------------------*/ 62571 // Adjusts the vertical dimensions of the view to the specified values 62572 AgendaView.prototype.updateSize = function (totalHeight, isAuto, isResize) { 62573 var eventLimit; 62574 var scrollerHeight; 62575 var scrollbarWidths; 62576 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 62577 // make all axis cells line up, and record the width so newly created axis cells will have it 62578 this.axisWidth = util_1.matchCellWidths(this.el.find('.fc-axis')); 62579 // hack to give the view some height prior to timeGrid's columns being rendered 62580 // TODO: separate setting height from scroller VS timeGrid. 62581 if (!this.timeGrid.colEls) { 62582 if (!isAuto) { 62583 scrollerHeight = this.computeScrollerHeight(totalHeight); 62584 this.scroller.setHeight(scrollerHeight); 62585 } 62586 return; 62587 } 62588 // set of fake row elements that must compensate when scroller has scrollbars 62589 var noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)'); 62590 // reset all dimensions back to the original state 62591 this.timeGrid.bottomRuleEl.hide(); // .show() will be called later if this <hr> is necessary 62592 this.scroller.clear(); // sets height to 'auto' and clears overflow 62593 util_1.uncompensateScroll(noScrollRowEls); 62594 // limit number of events in the all-day area 62595 if (this.dayGrid) { 62596 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed 62597 eventLimit = this.opt('eventLimit'); 62598 if (eventLimit && typeof eventLimit !== 'number') { 62599 eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number 62600 } 62601 if (eventLimit) { 62602 this.dayGrid.limitRows(eventLimit); 62603 } 62604 } 62605 if (!isAuto) { 62606 scrollerHeight = this.computeScrollerHeight(totalHeight); 62607 this.scroller.setHeight(scrollerHeight);
62608 scrollbarWidths = this.scroller.getScrollbarWidths(); 62609 if (scrollbarWidths.left || scrollbarWidths.right) { 62610 // make the all-day and header rows lines up 62611 util_1.compensateScroll(noScrollRowEls, scrollbarWidths); 62612 // the scrollbar compensation might have changed text flow, which might affect height, so recalculate 62613 // and reapply the desired height to the scroller. 62614 scrollerHeight = this.computeScrollerHeight(totalHeight); 62615 this.scroller.setHeight(scrollerHeight); 62616 } 62617 // guarantees the same scrollbar widths 62618 this.scroller.lockOverflow(scrollbarWidths); 62619 // if there's any space below the slats, show the horizontal rule. 62620 // this won't cause any new overflow, because lockOverflow already called. 62621 if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) { 62622 this.timeGrid.bottomRuleEl.show(); 62623 } 62624 } 62625 }; 62626 // given a desired total height of the view, returns what the height of the scroller should be 62627 AgendaView.prototype.computeScrollerHeight = function (totalHeight) { 62628 return totalHeight - 62629 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 62630 }; 62631 /* Scroll 62632 ------------------------------------------------------------------------------------------------------------------*/ 62633 // Computes the initial pre-configured scroll state prior to allowing the user to change it 62634 AgendaView.prototype.computeInitialDateScroll = function () { 62635 var scrollTime = moment.duration(this.opt('scrollTime')); 62636 var top = this.timeGrid.computeTimeTop(scrollTime); 62637 // zoom can give weird floating-point values. rather scroll a little bit further 62638 top = Math.ceil(top); 62639 if (top) { 62640 top++; // to overcome top border that slots beyond the first have. looks better 62641 } 62642 return { top: top }; 62643 }; 62644 AgendaView.prototype.queryDateScroll = function () { 62645 return { top: this.scroller.getScrollTop() }; 62646 }; 62647 AgendaView.prototype.applyDateScroll = function (scroll) { 62648 if (scroll.top !== undefined) { 62649 this.scroller.setScrollTop(scroll.top); 62650 } 62651 }; 62652 /* Hit Areas 62653 ------------------------------------------------------------------------------------------------------------------*/ 62654 // forward all hit-related method calls to the grids (dayGrid might not be defined) 62655 AgendaView.prototype.getHitFootprint = function (hit) { 62656 // TODO: hit.component is set as a hack to identify where the hit came from 62657 return hit.component.getHitFootprint(hit); 62658 }; 62659 AgendaView.prototype.getHitEl = function (hit) { 62660 // TODO: hit.component is set as a hack to identify where the hit came from 62661 return hit.component.getHitEl(hit); 62662 }; 62663 /* Event Rendering 62664 ------------------------------------------------------------------------------------------------------------------*/ 62665 AgendaView.prototype.executeEventRender = function (eventsPayload) { 62666 var dayEventsPayload = {}; 62667 var timedEventsPayload = {}; 62668 var id; 62669 var eventInstanceGroup; 62670 // separate the events into all-day and timed 62671 for (id in eventsPayload) { 62672 eventInstanceGroup = eventsPayload[id]; 62673 if (eventInstanceGroup.getEventDef().isAllDay()) { 62674 dayEventsPayload[id] = eventInstanceGroup; 62675 } 62676 else { 62677 timedEventsPayload[id] = eventInstanceGroup; 62678 } 62679 } 62680 this.timeGrid.executeEventRender(timedEventsPayload); 62681 if (this.dayGrid) { 62682 this.dayGrid.executeEventRender(dayEventsPayload); 62683 } 62684 }; 62685 /* Dragging/Resizing Routing 62686 ------------------------------------------------------------------------------------------------------------------*/ 62687 // A returned value of `true` signals that a mock "helper" event has been rendered. 62688 AgendaView.prototype.renderDrag = function (eventFootprints, seg, isTouch) { 62689 var groups = groupEventFootprintsByAllDay(eventFootprints); 62690 var renderedHelper = false; 62691 renderedHelper = this.timeGrid.renderDrag(groups.timed, seg, isTouch); 62692 if (this.dayGrid) { 62693 renderedHelper = this.dayGrid.renderDrag(groups.allDay, seg, isTouch) || renderedHelper; 62694 } 62695 return renderedHelper; 62696 }; 62697 AgendaView.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { 62698 var groups = groupEventFootprintsByAllDay(eventFootprints); 62699 this.timeGrid.renderEventResize(groups.timed, seg, isTouch); 62700 if (this.dayGrid) { 62701 this.dayGrid.renderEventResize(groups.allDay, seg, isTouch); 62702 } 62703 }; 62704 /* Selection 62705 ------------------------------------------------------------------------------------------------------------------*/ 62706 // Renders a visual indication of a selection 62707 AgendaView.prototype.renderSelectionFootprint = function (componentFootprint) { 62708 if (!componentFootprint.isAllDay) { 62709 this.timeGrid.renderSelectionFootprint(componentFootprint); 62710 } 62711 else if (this.dayGrid) { 62712 this.dayGrid.renderSelectionFootprint(componentFootprint); 62713 } 62714 }; 62715 return AgendaView; 62716}(View_1.default)); 62717exports.default = AgendaView; 62718AgendaView.prototype.timeGridClass = TimeGrid_1.default; 62719AgendaView.prototype.dayGridClass = DayGrid_1.default; 62720// Will customize the rendering behavior of the AgendaView's timeGrid 62721agendaTimeGridMethods = { 62722 // Generates the HTML that will go before the day-of week header cells 62723 renderHeadIntroHtml: function () { 62724 var view = this.view; 62725 var calendar = view.calendar; 62726 var weekStart = calendar.msToUtcMoment(this.dateProfile.renderUnzonedRange.startMs, true); 62727 var weekText; 62728 if (this.opt('weekNumbers')) { 62729 weekText = weekStart.format(this.opt('smallWeekFormat'));
62730 return '' + 62731 '<th class="fc-axis fc-week-number ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '>' + 62732 view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths 62733 { date: weekStart, type: 'week', forceOff: this.colCnt > 1 }, util_1.htmlEscape(weekText) // inner HTML 62734 ) + 62735 '</th>'; 62736 } 62737 else { 62738 return '<th class="fc-axis ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '></th>'; 62739 } 62740 }, 62741 // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column. 62742 renderBgIntroHtml: function () { 62743 var view = this.view; 62744 return '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '></td>'; 62745 }, 62746 // Generates the HTML that goes before all other types of cells. 62747 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid. 62748 renderIntroHtml: function () { 62749 var view = this.view; 62750 return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>'; 62751 } 62752}; 62753// Will customize the rendering behavior of the AgendaView's dayGrid 62754agendaDayGridMethods = { 62755 // Generates the HTML that goes before the all-day cells 62756 renderBgIntroHtml: function () { 62757 var view = this.view; 62758 return '' + 62759 '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' + 62760 '<span>' + // needed for matchCellWidths 62761 view.getAllDayHtml() + 62762 '</span>' + 62763 '</td>'; 62764 }, 62765 // Generates the HTML that goes before all other types of cells. 62766 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid. 62767 renderIntroHtml: function () { 62768 var view = this.view; 62769 return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>'; 62770 } 62771}; 62772function groupEventFootprintsByAllDay(eventFootprints) { 62773 var allDay = []; 62774 var timed = []; 62775 var i; 62776 for (i = 0; i < eventFootprints.length; i++) { 62777 if (eventFootprints[i].componentFootprint.isAllDay) { 62778 allDay.push(eventFootprints[i]); 62779 } 62780 else { 62781 timed.push(eventFootprints[i]); 62782 } 62783 } 62784 return { allDay: allDay, timed: timed }; 62785} 62786 62787 62788/***/ }), 62789/* 227 */ 62790/***/ (function(module, exports, __webpack_require__) { 62791 62792Object.defineProperty(exports, "__esModule", { value: true }); 62793var tslib_1 = __webpack_require__(2); 62794var $ = __webpack_require__(3); 62795var moment = __webpack_require__(0); 62796var util_1 = __webpack_require__(4); 62797var InteractiveDateComponent_1 = __webpack_require__(40); 62798var BusinessHourRenderer_1 = __webpack_require__(56); 62799var StandardInteractionsMixin_1 = __webpack_require__(60); 62800var DayTableMixin_1 = __webpack_require__(55); 62801var CoordCache_1 = __webpack_require__(53); 62802var UnzonedRange_1 = __webpack_require__(5); 62803var ComponentFootprint_1 = __webpack_require__(12); 62804var TimeGridEventRenderer_1 = __webpack_require__(246); 62805var TimeGridHelperRenderer_1 = __webpack_require__(247); 62806var TimeGridFillRenderer_1 = __webpack_require__(248);
62807/* A component that renders one or more columns of vertical time slots 62808----------------------------------------------------------------------------------------------------------------------*/ 62809// We mixin DayTable, even though there is only a single row of days 62810// potential nice values for the slot-duration and interval-duration 62811// from largest to smallest 62812var AGENDA_STOCK_SUB_DURATIONS = [ 62813 { hours: 1 }, 62814 { minutes: 30 }, 62815 { minutes: 15 }, 62816 { seconds: 30 }, 62817 { seconds: 15 } 62818]; 62819var TimeGrid = /** @class */ (function (_super) { 62820 tslib_1.__extends(TimeGrid, _super); 62821 function TimeGrid(view) { 62822 var _this = _super.call(this, view) || this; 62823 _this.processOptions(); 62824 return _this; 62825 } 62826 // Slices up the given span (unzoned start/end with other misc data) into an array of segments 62827 TimeGrid.prototype.componentFootprintToSegs = function (componentFootprint) { 62828 var segs = this.sliceRangeByTimes(componentFootprint.unzonedRange); 62829 var i; 62830 for (i = 0; i < segs.length; i++) { 62831 if (this.isRTL) { 62832 segs[i].col = this.daysPerRow - 1 - segs[i].dayIndex; 62833 } 62834 else { 62835 segs[i].col = segs[i].dayIndex; 62836 } 62837 } 62838 return segs; 62839 }; 62840 /* Date Handling 62841 ------------------------------------------------------------------------------------------------------------------*/ 62842 TimeGrid.prototype.sliceRangeByTimes = function (unzonedRange) { 62843 var segs = []; 62844 var segRange; 62845 var dayIndex; 62846 for (dayIndex = 0; dayIndex < this.daysPerRow; dayIndex++) { 62847 segRange = unzonedRange.intersect(this.dayRanges[dayIndex]); 62848 if (segRange) { 62849 segs.push({ 62850 startMs: segRange.startMs, 62851 endMs: segRange.endMs, 62852 isStart: segRange.isStart, 62853 isEnd: segRange.isEnd, 62854 dayIndex: dayIndex 62855 }); 62856 } 62857 } 62858 return segs; 62859 }; 62860 /* Options 62861 ------------------------------------------------------------------------------------------------------------------*/ 62862 // Parses various options into properties of this object 62863 TimeGrid.prototype.processOptions = function () { 62864 var slotDuration = this.opt('slotDuration'); 62865 var snapDuration = this.opt('snapDuration'); 62866 var input; 62867 slotDuration = moment.duration(slotDuration); 62868 snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration; 62869 this.slotDuration = slotDuration; 62870 this.snapDuration = snapDuration; 62871 this.snapsPerSlot = slotDuration / snapDuration; // TODO: ensure an integer multiple? 62872 // might be an array value (for TimelineView). 62873 // if so, getting the most granular entry (the last one probably). 62874 input = this.opt('slotLabelFormat'); 62875 if ($.isArray(input)) { 62876 input = input[input.length - 1]; 62877 } 62878 this.labelFormat = input || 62879 this.opt('smallTimeFormat'); // the computed default 62880 input = this.opt('slotLabelInterval'); 62881 this.labelInterval = input ? 62882 moment.duration(input) : 62883 this.computeLabelInterval(slotDuration); 62884 }; 62885 // Computes an automatic value for slotLabelInterval 62886 TimeGrid.prototype.computeLabelInterval = function (slotDuration) { 62887 var i; 62888 var labelInterval; 62889 var slotsPerLabel; 62890 // find the smallest stock label interval that results in more than one slots-per-label 62891 for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) { 62892 labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]); 62893 slotsPerLabel = util_1.divideDurationByDuration(labelInterval, slotDuration); 62894 if (util_1.isInt(slotsPerLabel) && slotsPerLabel > 1) { 62895 return labelInterval; 62896 } 62897 } 62898 return moment.duration(slotDuration); // fall back. clone 62899 }; 62900 /* Date Rendering 62901 ------------------------------------------------------------------------------------------------------------------*/ 62902 TimeGrid.prototype.renderDates = function (dateProfile) { 62903 this.dateProfile = dateProfile; 62904 this.updateDayTable(); 62905 this.renderSlats();
62906 this.renderColumns(); 62907 }; 62908 TimeGrid.prototype.unrenderDates = function () { 62909 // this.unrenderSlats(); // don't need this because repeated .html() calls clear 62910 this.unrenderColumns(); 62911 }; 62912 TimeGrid.prototype.renderSkeleton = function () { 62913 var theme = this.view.calendar.theme; 62914 this.el.html('<div class="fc-bg"></div>' + 62915 '<div class="fc-slats"></div>' + 62916 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" style="display:none" />'); 62917 this.bottomRuleEl = this.el.find('hr'); 62918 }; 62919 TimeGrid.prototype.renderSlats = function () { 62920 var theme = this.view.calendar.theme; 62921 this.slatContainerEl = this.el.find('> .fc-slats') 62922 .html(// avoids needing ::unrenderSlats() 62923 '<table class="' + theme.getClass('tableGrid') + '">' + 62924 this.renderSlatRowHtml() + 62925 '</table>'); 62926 this.slatEls = this.slatContainerEl.find('tr'); 62927 this.slatCoordCache = new CoordCache_1.default({ 62928 els: this.slatEls, 62929 isVertical: true 62930 }); 62931 }; 62932 // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. 62933 TimeGrid.prototype.renderSlatRowHtml = function () { 62934 var view = this.view; 62935 var calendar = view.calendar; 62936 var theme = calendar.theme; 62937 var isRTL = this.isRTL; 62938 var dateProfile = this.dateProfile; 62939 var html = ''; 62940 var slotTime = moment.duration(+dateProfile.minTime); // wish there was .clone() for durations 62941 var slotIterator = moment.duration(0); 62942 var slotDate; // will be on the view's first day, but we only care about its time 62943 var isLabeled; 62944 var axisHtml; 62945 // Calculate the time for each slot 62946 while (slotTime < dateProfile.maxTime) { 62947 slotDate = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs).time(slotTime); 62948 isLabeled = util_1.isInt(util_1.divideDurationByDuration(slotIterator, this.labelInterval)); 62949 axisHtml = 62950 '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' + 62951 (isLabeled ? 62952 '<span>' + // for matchCellWidths 62953 util_1.htmlEscape(slotDate.format(this.labelFormat)) + 62954 '</span>' : 62955 '') + 62956 '</td>'; 62957 html += 62958 '<tr data-time="' + slotDate.format('HH:mm:ss') + '"' + 62959 (isLabeled ? '' : ' class="fc-minor"') + 62960 '>' + 62961 (!isRTL ? axisHtml : '') + 62962 '<td class="' + theme.getClass('widgetContent') + '"/>' + 62963 (isRTL ? axisHtml : '') + 62964 '</tr>'; 62965 slotTime.add(this.slotDuration); 62966 slotIterator.add(this.slotDuration); 62967 } 62968 return html; 62969 }; 62970 TimeGrid.prototype.renderColumns = function () { 62971 var dateProfile = this.dateProfile; 62972 var theme = this.view.calendar.theme; 62973 this.dayRanges = this.dayDates.map(function (dayDate) { 62974 return new UnzonedRange_1.default(dayDate.clone().add(dateProfile.minTime), dayDate.clone().add(dateProfile.maxTime)); 62975 }); 62976 if (this.headContainerEl) { 62977 this.headContainerEl.html(this.renderHeadHtml()); 62978 } 62979 this.el.find('> .fc-bg').html('<table class="' + theme.getClass('tableGrid') + '">' + 62980 this.renderBgTrHtml(0) + // row=0 62981 '</table>'); 62982 this.colEls = this.el.find('.fc-day, .fc-disabled-day'); 62983 this.colCoordCache = new CoordCache_1.default({ 62984 els: this.colEls, 62985 isHorizontal: true 62986 }); 62987 this.renderContentSkeleton(); 62988 }; 62989 TimeGrid.prototype.unrenderColumns = function () { 62990 this.unrenderContentSkeleton(); 62991 }; 62992 /* Content Skeleton 62993 ------------------------------------------------------------------------------------------------------------------*/ 62994 // Renders the DOM that the view's content will live in 62995 TimeGrid.prototype.renderContentSkeleton = function () { 62996 var cellHtml = ''; 62997 var i; 62998 var skeletonEl; 62999 for (i = 0; i < this.colCnt; i++) { 63000 cellHtml += 63001 '<td>' + 63002 '<div class="fc-content-col">' + 63003 '<div class="fc-event-container fc-helper-container"></div>' + 63004 '<div class="fc-event-container"></div>' + 63005 '<div class="fc-highlight-container"></div>' + 63006 '<div class="fc-bgevent-container"></div>' + 63007 '<div class="fc-business-container"></div>' + 63008 '</div>' + 63009 '</td>'; 63010 }
63011 skeletonEl = this.contentSkeletonEl = $('<div class="fc-content-skeleton">' + 63012 '<table>' + 63013 '<tr>' + cellHtml + '</tr>' + 63014 '</table>' + 63015 '</div>'); 63016 this.colContainerEls = skeletonEl.find('.fc-content-col'); 63017 this.helperContainerEls = skeletonEl.find('.fc-helper-container'); 63018 this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)'); 63019 this.bgContainerEls = skeletonEl.find('.fc-bgevent-container'); 63020 this.highlightContainerEls = skeletonEl.find('.fc-highlight-container'); 63021 this.businessContainerEls = skeletonEl.find('.fc-business-container'); 63022 this.bookendCells(skeletonEl.find('tr')); // TODO: do this on string level 63023 this.el.append(skeletonEl); 63024 }; 63025 TimeGrid.prototype.unrenderContentSkeleton = function () { 63026 if (this.contentSkeletonEl) { 63027 this.contentSkeletonEl.remove(); 63028 this.contentSkeletonEl = null; 63029 this.colContainerEls = null; 63030 this.helperContainerEls = null; 63031 this.fgContainerEls = null; 63032 this.bgContainerEls = null; 63033 this.highlightContainerEls = null; 63034 this.businessContainerEls = null; 63035 } 63036 }; 63037 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col 63038 TimeGrid.prototype.groupSegsByCol = function (segs) { 63039 var segsByCol = []; 63040 var i; 63041 for (i = 0; i < this.colCnt; i++) { 63042 segsByCol.push([]); 63043 } 63044 for (i = 0; i < segs.length; i++) { 63045 segsByCol[segs[i].col].push(segs[i]); 63046 } 63047 return segsByCol; 63048 }; 63049 // Given segments grouped by column, insert the segments' elements into a parallel array of container 63050 // elements, each living within a column. 63051 TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) { 63052 var col; 63053 var segs; 63054 var i; 63055 for (col = 0; col < this.colCnt; col++) { 63056 segs = segsByCol[col]; 63057 for (i = 0; i < segs.length; i++) { 63058 containerEls.eq(col).append(segs[i].el); 63059 } 63060 } 63061 }; 63062 /* Now Indicator 63063 ------------------------------------------------------------------------------------------------------------------*/ 63064 TimeGrid.prototype.getNowIndicatorUnit = function () { 63065 return 'minute'; // will refresh on the minute 63066 }; 63067 TimeGrid.prototype.renderNowIndicator = function (date) { 63068 // HACK: if date columns not ready for some reason (scheduler) 63069 if (!this.colContainerEls) { 63070 return; 63071 } 63072 // seg system might be overkill, but it handles scenario where line needs to be rendered 63073 // more than once because of columns with the same date (resources columns for example) 63074 var segs = this.componentFootprintToSegs(new ComponentFootprint_1.default(new UnzonedRange_1.default(date, date.valueOf() + 1), // protect against null range 63075 false // all-day 63076 )); 63077 var top = this.computeDateTop(date, date); 63078 var nodes = []; 63079 var i; 63080 // render lines within the columns 63081 for (i = 0; i < segs.length; i++) { 63082 nodes.push($('<div class="fc-now-indicator fc-now-indicator-line"></div>') 63083 .css('top', top) 63084 .appendTo(this.colContainerEls.eq(segs[i].col))[0]); 63085 } 63086 // render an arrow over the axis 63087 if (segs.length > 0) { 63088 nodes.push($('<div class="fc-now-indicator fc-now-indicator-arrow"></div>') 63089 .css('top', top) 63090 .appendTo(this.el.find('.fc-content-skeleton'))[0]); 63091 } 63092 this.nowIndicatorEls = $(nodes); 63093 }; 63094 TimeGrid.prototype.unrenderNowIndicator = function () { 63095 if (this.nowIndicatorEls) { 63096 this.nowIndicatorEls.remove(); 63097 this.nowIndicatorEls = null; 63098 } 63099 }; 63100 /* Coordinates 63101 ------------------------------------------------------------------------------------------------------------------*/ 63102 TimeGrid.prototype.updateSize = function (totalHeight, isAuto, isResize) { 63103 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
63104 this.slatCoordCache.build(); 63105 if (isResize) { 63106 this.updateSegVerticals([].concat(this.eventRenderer.getSegs(), this.businessSegs || [])); 63107 } 63108 }; 63109 TimeGrid.prototype.getTotalSlatHeight = function () { 63110 return this.slatContainerEl.outerHeight(); 63111 }; 63112 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 63113 // `ms` can be a millisecond UTC time OR a UTC moment. 63114 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 63115 TimeGrid.prototype.computeDateTop = function (ms, startOfDayDate) { 63116 return this.computeTimeTop(moment.duration(ms - startOfDayDate.clone().stripTime())); 63117 }; 63118 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 63119 TimeGrid.prototype.computeTimeTop = function (time) { 63120 var len = this.slatEls.length; 63121 var dateProfile = this.dateProfile; 63122 var slatCoverage = (time - dateProfile.minTime) / this.slotDuration; // floating-point value of # of slots covered 63123 var slatIndex; 63124 var slatRemainder; 63125 // compute a floating-point number for how many slats should be progressed through. 63126 // from 0 to number of slats (inclusive) 63127 // constrained because minTime/maxTime might be customized. 63128 slatCoverage = Math.max(0, slatCoverage); 63129 slatCoverage = Math.min(len, slatCoverage); 63130 // an integer index of the furthest whole slat 63131 // from 0 to number slats (*exclusive*, so len-1) 63132 slatIndex = Math.floor(slatCoverage); 63133 slatIndex = Math.min(slatIndex, len - 1); 63134 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. 63135 // could be 1.0 if slatCoverage is covering *all* the slots 63136 slatRemainder = slatCoverage - slatIndex;
63137 return this.slatCoordCache.getTopPosition(slatIndex) + 63138 this.slatCoordCache.getHeight(slatIndex) * slatRemainder; 63139 }; 63140 // Refreshes the CSS top/bottom coordinates for each segment element. 63141 // Works when called after initial render, after a window resize/zoom for example. 63142 TimeGrid.prototype.updateSegVerticals = function (segs) { 63143 this.computeSegVerticals(segs); 63144 this.assignSegVerticals(segs); 63145 }; 63146 // For each segment in an array, computes and assigns its top and bottom properties 63147 TimeGrid.prototype.computeSegVerticals = function (segs) { 63148 var eventMinHeight = this.opt('agendaEventMinHeight'); 63149 var i; 63150 var seg; 63151 var dayDate; 63152 for (i = 0; i < segs.length; i++) { 63153 seg = segs[i]; 63154 dayDate = this.dayDates[seg.dayIndex]; 63155 seg.top = this.computeDateTop(seg.startMs, dayDate); 63156 seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.endMs, dayDate)); 63157 } 63158 }; 63159 // Given segments that already have their top/bottom properties computed, applies those values to 63160 // the segments' elements. 63161 TimeGrid.prototype.assignSegVerticals = function (segs) { 63162 var i; 63163 var seg; 63164 for (i = 0; i < segs.length; i++) { 63165 seg = segs[i]; 63166 seg.el.css(this.generateSegVerticalCss(seg)); 63167 } 63168 }; 63169 // Generates an object with CSS properties for the top/bottom coordinates of a segment element 63170 TimeGrid.prototype.generateSegVerticalCss = function (seg) { 63171 return { 63172 top: seg.top, 63173 bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container 63174 }; 63175 }; 63176 /* Hit System 63177 ------------------------------------------------------------------------------------------------------------------*/ 63178 TimeGrid.prototype.prepareHits = function () { 63179 this.colCoordCache.build(); 63180 this.slatCoordCache.build(); 63181 }; 63182 TimeGrid.prototype.releaseHits = function () { 63183 this.colCoordCache.clear(); 63184 // NOTE: don't clear slatCoordCache because we rely on it for computeTimeTop 63185 }; 63186 TimeGrid.prototype.queryHit = function (leftOffset, topOffset) { 63187 var snapsPerSlot = this.snapsPerSlot; 63188 var colCoordCache = this.colCoordCache; 63189 var slatCoordCache = this.slatCoordCache; 63190 if (colCoordCache.isLeftInBounds(leftOffset) && slatCoordCache.isTopInBounds(topOffset)) { 63191 var colIndex = colCoordCache.getHorizontalIndex(leftOffset); 63192 var slatIndex = slatCoordCache.getVerticalIndex(topOffset); 63193 if (colIndex != null && slatIndex != null) { 63194 var slatTop = slatCoordCache.getTopOffset(slatIndex); 63195 var slatHeight = slatCoordCache.getHeight(slatIndex); 63196 var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1 63197 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat 63198 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 63199 var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight; 63200 var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight; 63201 return { 63202 col: colIndex, 63203 snap: snapIndex, 63204 component: this, 63205 left: colCoordCache.getLeftOffset(colIndex), 63206 right: colCoordCache.getRightOffset(colIndex), 63207 top: snapTop, 63208 bottom: snapBottom 63209 }; 63210 } 63211 } 63212 }; 63213 TimeGrid.prototype.getHitFootprint = function (hit) { 63214 var start = this.getCellDate(0, hit.col); // row=0 63215 var time = this.computeSnapTime(hit.snap); // pass in the snap-index 63216 var end; 63217 start.time(time); 63218 end = start.clone().add(this.snapDuration); 63219 return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), false // all-day? 63220 ); 63221 }; 63222 // Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day 63223 TimeGrid.prototype.computeSnapTime = function (snapIndex) { 63224 return moment.duration(this.dateProfile.minTime + this.snapDuration * snapIndex); 63225 }; 63226 TimeGrid.prototype.getHitEl = function (hit) { 63227 return this.colEls.eq(hit.col); 63228 }; 63229 /* Event Drag Visualization 63230 ------------------------------------------------------------------------------------------------------------------*/ 63231 // Renders a visual indication of an event being dragged over the specified date(s). 63232 // A returned value of `true` signals that a mock "helper" event has been rendered. 63233 TimeGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) { 63234 var i; 63235 if (seg) { 63236 if (eventFootprints.length) { 63237 this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch); 63238 // signal that a helper has been rendered 63239 return true; 63240 } 63241 } 63242 else { 63243 for (i = 0; i < eventFootprints.length; i++) { 63244 this.renderHighlight(eventFootprints[i].componentFootprint); 63245 } 63246 } 63247 }; 63248 // Unrenders any visual indication of an event being dragged 63249 TimeGrid.prototype.unrenderDrag = function () { 63250 this.unrenderHighlight(); 63251 this.helperRenderer.unrender(); 63252 }; 63253 /* Event Resize Visualization 63254 ------------------------------------------------------------------------------------------------------------------*/ 63255 // Renders a visual indication of an event being resized 63256 TimeGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { 63257 this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch); 63258 }; 63259 // Unrenders any visual indication of an event being resized 63260 TimeGrid.prototype.unrenderEventResize = function () { 63261 this.helperRenderer.unrender(); 63262 }; 63263 /* Selection 63264 ------------------------------------------------------------------------------------------------------------------*/ 63265 // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight. 63266 TimeGrid.prototype.renderSelectionFootprint = function (componentFootprint) { 63267 if (this.opt('selectHelper')) { 63268 this.helperRenderer.renderComponentFootprint(componentFootprint); 63269 } 63270 else { 63271 this.renderHighlight(componentFootprint); 63272 } 63273 }; 63274 // Unrenders any visual indication of a selection 63275 TimeGrid.prototype.unrenderSelection = function () { 63276 this.helperRenderer.unrender(); 63277 this.unrenderHighlight(); 63278 }; 63279 return TimeGrid; 63280}(InteractiveDateComponent_1.default)); 63281exports.default = TimeGrid; 63282TimeGrid.prototype.eventRendererClass = TimeGridEventRenderer_1.default; 63283TimeGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default; 63284TimeGrid.prototype.helperRendererClass = TimeGridHelperRenderer_1.default; 63285TimeGrid.prototype.fillRendererClass = TimeGridFillRenderer_1.default; 63286StandardInteractionsMixin_1.default.mixInto(TimeGrid); 63287DayTableMixin_1.default.mixInto(TimeGrid); 63288 63289 63290/***/ }), 63291/* 228 */ 63292/***/ (function(module, exports, __webpack_require__) { 63293 63294Object.defineProperty(exports, "__esModule", { value: true });
63295var tslib_1 = __webpack_require__(2); 63296var UnzonedRange_1 = __webpack_require__(5); 63297var DateProfileGenerator_1 = __webpack_require__(221); 63298var BasicViewDateProfileGenerator = /** @class */ (function (_super) { 63299 tslib_1.__extends(BasicViewDateProfileGenerator, _super); 63300 function BasicViewDateProfileGenerator() { 63301 return _super !== null && _super.apply(this, arguments) || this; 63302 } 63303 // Computes the date range that will be rendered. 63304 BasicViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { 63305 var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); // an UnzonedRange 63306 var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay); 63307 var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay); 63308 // year and month views should be aligned with weeks. this is already done for week 63309 if (/^(year|month)$/.test(currentRangeUnit)) { 63310 start.startOf('week'); 63311 // make end-of-week if not already 63312 if (end.weekday()) { 63313 end.add(1, 'week').startOf('week'); // exclusively move backwards 63314 } 63315 } 63316 return new UnzonedRange_1.default(start, end); 63317 }; 63318 return BasicViewDateProfileGenerator; 63319}(DateProfileGenerator_1.default)); 63320exports.default = BasicViewDateProfileGenerator; 63321 63322 63323/***/ }), 63324/* 229 */ 63325/***/ (function(module, exports, __webpack_require__) { 63326 63327Object.defineProperty(exports, "__esModule", { value: true }); 63328var tslib_1 = __webpack_require__(2); 63329var moment = __webpack_require__(0); 63330var util_1 = __webpack_require__(4); 63331var BasicView_1 = __webpack_require__(62); 63332var MonthViewDateProfileGenerator_1 = __webpack_require__(253); 63333/* A month view with day cells running in rows (one-per-week) and columns 63334----------------------------------------------------------------------------------------------------------------------*/ 63335var MonthView = /** @class */ (function (_super) { 63336 tslib_1.__extends(MonthView, _super); 63337 function MonthView() { 63338 return _super !== null && _super.apply(this, arguments) || this; 63339 } 63340 // Overrides the default BasicView behavior to have special multi-week auto-height logic 63341 MonthView.prototype.setGridHeight = function (height, isAuto) { 63342 // if auto, make the height of each row the height that it would be if there were 6 weeks 63343 if (isAuto) { 63344 height *= this.dayGrid.rowCnt / 6; 63345 } 63346 util_1.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows 63347 }; 63348 MonthView.prototype.isDateInOtherMonth = function (date, dateProfile) { 63349 return date.month() !== moment.utc(dateProfile.currentUnzonedRange.startMs).month(); // TODO: optimize 63350 }; 63351 return MonthView; 63352}(BasicView_1.default)); 63353exports.default = MonthView; 63354MonthView.prototype.dateProfileGeneratorClass = MonthViewDateProfileGenerator_1.default; 63355 63356 63357/***/ }), 63358/* 230 */ 63359/***/ (function(module, exports, __webpack_require__) { 63360 63361Object.defineProperty(exports, "__esModule", { value: true }); 63362var tslib_1 = __webpack_require__(2); 63363var $ = __webpack_require__(3); 63364var util_1 = __webpack_require__(4); 63365var UnzonedRange_1 = __webpack_require__(5); 63366var View_1 = __webpack_require__(41); 63367var Scroller_1 = __webpack_require__(39); 63368var ListEventRenderer_1 = __webpack_require__(254); 63369var ListEventPointing_1 = __webpack_require__(255); 63370/* 63371Responsible for the scroller, and forwarding event-related actions into the "grid". 63372*/ 63373var ListView = /** @class */ (function (_super) { 63374 tslib_1.__extends(ListView, _super); 63375 function ListView(calendar, viewSpec) { 63376 var _this = _super.call(this, calendar, viewSpec) || this; 63377 _this.segSelector = '.fc-list-item'; // which elements accept event actions 63378 _this.scroller = new Scroller_1.default({ 63379 overflowX: 'hidden', 63380 overflowY: 'auto' 63381 }); 63382 return _this; 63383 } 63384 ListView.prototype.renderSkeleton = function () { 63385 this.el.addClass('fc-list-view ' + 63386 this.calendar.theme.getClass('listView')); 63387 this.scroller.render(); 63388 this.scroller.el.appendTo(this.el); 63389 this.contentEl = this.scroller.scrollEl; // shortcut 63390 }; 63391 ListView.prototype.unrenderSkeleton = function () { 63392 this.scroller.destroy(); // will remove the Grid too 63393 }; 63394 ListView.prototype.updateSize = function (totalHeight, isAuto, isResize) { 63395 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 63396 this.scroller.clear(); // sets height to 'auto' and clears overflow 63397 if (!isAuto) { 63398 this.scroller.setHeight(this.computeScrollerHeight(totalHeight)); 63399 } 63400 }; 63401 ListView.prototype.computeScrollerHeight = function (totalHeight) { 63402 return totalHeight -
63403 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 63404 }; 63405 ListView.prototype.renderDates = function (dateProfile) { 63406 var calendar = this.calendar; 63407 var dayStart = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs, true); 63408 var viewEnd = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.endMs, true); 63409 var dayDates = []; 63410 var dayRanges = []; 63411 while (dayStart < viewEnd) { 63412 dayDates.push(dayStart.clone()); 63413 dayRanges.push(new UnzonedRange_1.default(dayStart, dayStart.clone().add(1, 'day'))); 63414 dayStart.add(1, 'day'); 63415 } 63416 this.dayDates = dayDates; 63417 this.dayRanges = dayRanges; 63418 // all real rendering happens in EventRenderer 63419 }; 63420 // slices by day 63421 ListView.prototype.componentFootprintToSegs = function (footprint) { 63422 var dayRanges = this.dayRanges; 63423 var dayIndex; 63424 var segRange; 63425 var seg; 63426 var segs = []; 63427 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) { 63428 segRange = footprint.unzonedRange.intersect(dayRanges[dayIndex]); 63429 if (segRange) { 63430 seg = { 63431 startMs: segRange.startMs, 63432 endMs: segRange.endMs, 63433 isStart: segRange.isStart, 63434 isEnd: segRange.isEnd, 63435 dayIndex: dayIndex 63436 }; 63437 segs.push(seg); 63438 // detect when footprint won't go fully into the next day, 63439 // and mutate the latest seg to the be the end. 63440 if (!seg.isEnd && !footprint.isAllDay && 63441 dayIndex + 1 < dayRanges.length && 63442 footprint.unzonedRange.endMs < dayRanges[dayIndex + 1].startMs + this.nextDayThreshold) { 63443 seg.endMs = footprint.unzonedRange.endMs; 63444 seg.isEnd = true; 63445 break; 63446 } 63447 } 63448 } 63449 return segs; 63450 }; 63451 ListView.prototype.renderEmptyMessage = function () { 63452 this.contentEl.html('<div class="fc-list-empty-wrap2">' + // TODO: try less wraps 63453 '<div class="fc-list-empty-wrap1">' + 63454 '<div class="fc-list-empty">' + 63455 util_1.htmlEscape(this.opt('noEventsMessage')) + 63456 '</div>' + 63457 '</div>' + 63458 '</div>'); 63459 }; 63460 // render the event segments in the view 63461 ListView.prototype.renderSegList = function (allSegs) { 63462 var segsByDay = this.groupSegsByDay(allSegs); // sparse array 63463 var dayIndex; 63464 var daySegs; 63465 var i; 63466 var tableEl = $('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody/></table>'); 63467 var tbodyEl = tableEl.find('tbody'); 63468 for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) { 63469 daySegs = segsByDay[dayIndex]; 63470 if (daySegs) { 63471 // append a day header 63472 tbodyEl.append(this.dayHeaderHtml(this.dayDates[dayIndex])); 63473 this.eventRenderer.sortEventSegs(daySegs); 63474 for (i = 0; i < daySegs.length; i++) { 63475 tbodyEl.append(daySegs[i].el); // append event row 63476 } 63477 } 63478 } 63479 this.contentEl.empty().append(tableEl); 63480 }; 63481 // Returns a sparse array of arrays, segs grouped by their dayIndex 63482 ListView.prototype.groupSegsByDay = function (segs) { 63483 var segsByDay = []; // sparse array 63484 var i; 63485 var seg; 63486 for (i = 0; i < segs.length; i++) { 63487 seg = segs[i]; 63488 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) 63489 .push(seg); 63490 } 63491 return segsByDay; 63492 }; 63493 // generates the HTML for the day headers that live amongst the event rows 63494 ListView.prototype.dayHeaderHtml = function (dayDate) { 63495 var mainFormat = this.opt('listDayFormat'); 63496 var altFormat = this.opt('listDayAltFormat'); 63497 return '<tr class="fc-list-heading" data-date="' + dayDate.format('YYYY-MM-DD') + '">' + 63498 '<td class="' + (this.calendar.theme.getClass('tableListHeading') || 63499 this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' + 63500 (mainFormat ? 63501 this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-main' }, util_1.htmlEscape(dayDate.format(mainFormat)) // inner HTML 63502 ) : 63503 '') + 63504 (altFormat ? 63505 this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-alt' }, util_1.htmlEscape(dayDate.format(altFormat)) // inner HTML 63506 ) : 63507 '') + 63508 '</td>' + 63509 '</tr>'; 63510 }; 63511 return ListView; 63512}(View_1.default)); 63513exports.default = ListView; 63514ListView.prototype.eventRendererClass = ListEventRenderer_1.default; 63515ListView.prototype.eventPointingClass = ListEventPointing_1.default; 63516 63517 63518/***/ }), 63519/* 231 */, 63520/* 232 */, 63521/* 233 */, 63522/* 234 */, 63523/* 235 */, 63524/* 236 */ 63525/***/ (function(module, exports, __webpack_require__) { 63526 63527var $ = __webpack_require__(3);
63528var exportHooks = __webpack_require__(16); 63529var util_1 = __webpack_require__(4); 63530var Calendar_1 = __webpack_require__(220); 63531// for intentional side-effects 63532__webpack_require__(10); 63533__webpack_require__(47); 63534__webpack_require__(256); 63535__webpack_require__(257); 63536__webpack_require__(260); 63537__webpack_require__(261); 63538__webpack_require__(262); 63539__webpack_require__(263); 63540$.fullCalendar = exportHooks; 63541$.fn.fullCalendar = function (options) { 63542 var args = Array.prototype.slice.call(arguments, 1); // for a possible method call 63543 var res = this; // what this function will return (this jQuery object by default) 63544 this.each(function (i, _element) { 63545 var element = $(_element); 63546 var calendar = element.data('fullCalendar'); // get the existing calendar object (if any) 63547 var singleRes; // the returned value of this single method call 63548 // a method call 63549 if (typeof options === 'string') { 63550 if (options === 'getCalendar') { 63551 if (!i) { 63552 res = calendar; 63553 } 63554 } 63555 else if (options === 'destroy') { 63556 if (calendar) { 63557 calendar.destroy(); 63558 element.removeData('fullCalendar'); 63559 } 63560 } 63561 else if (!calendar) { 63562 util_1.warn('Attempting to call a FullCalendar method on an element with no calendar.'); 63563 } 63564 else if ($.isFunction(calendar[options])) { 63565 singleRes = calendar[options].apply(calendar, args); 63566 if (!i) { 63567 res = singleRes; // record the first method call result 63568 } 63569 if (options === 'destroy') { 63570 element.removeData('fullCalendar'); 63571 } 63572 } 63573 else { 63574 util_1.warn("'" + options + "' is an unknown FullCalendar method."); 63575 } 63576 } 63577 else if (!calendar) { 63578 calendar = new Calendar_1.default(element, options); 63579 element.data('fullCalendar', calendar); 63580 calendar.render(); 63581 } 63582 }); 63583 return res; 63584}; 63585module.exports = exportHooks; 63586 63587 63588/***/ }), 63589/* 237 */ 63590/***/ (function(module, exports, __webpack_require__) { 63591 63592Object.defineProperty(exports, "__esModule", { value: true }); 63593var tslib_1 = __webpack_require__(2); 63594var Model_1 = __webpack_require__(48); 63595var Component = /** @class */ (function (_super) { 63596 tslib_1.__extends(Component, _super); 63597 function Component() { 63598 return _super !== null && _super.apply(this, arguments) || this; 63599 } 63600 Component.prototype.setElement = function (el) { 63601 this.el = el; 63602 this.bindGlobalHandlers(); 63603 this.renderSkeleton(); 63604 this.set('isInDom', true); 63605 }; 63606 Component.prototype.removeElement = function () { 63607 this.unset('isInDom'); 63608 this.unrenderSkeleton(); 63609 this.unbindGlobalHandlers(); 63610 this.el.remove(); 63611 // NOTE: don't null-out this.el in case the View was destroyed within an API callback. 63612 // We don't null-out the View's other jQuery element references upon destroy, 63613 // so we shouldn't kill this.el either. 63614 }; 63615 Component.prototype.bindGlobalHandlers = function () { 63616 // subclasses can override 63617 }; 63618 Component.prototype.unbindGlobalHandlers = function () { 63619 // subclasses can override 63620 }; 63621 /* 63622 NOTE: Can't have a `render` method. Read the deprecation notice in View::executeDateRender 63623 */ 63624 // Renders the basic structure of the view before any content is rendered 63625 Component.prototype.renderSkeleton = function () { 63626 // subclasses should implement 63627 }; 63628 // Unrenders the basic structure of the view 63629 Component.prototype.unrenderSkeleton = function () { 63630 // subclasses should implement 63631 }; 63632 return Component; 63633}(Model_1.default)); 63634exports.default = Component; 63635 63636 63637/***/ }), 63638/* 238 */ 63639/***/ (function(module, exports) { 63640 63641Object.defineProperty(exports, "__esModule", { value: true });
63642var Iterator = /** @class */ (function () { 63643 function Iterator(items) { 63644 this.items = items || []; 63645 } 63646 /* Calls a method on every item passing the arguments through */ 63647 Iterator.prototype.proxyCall = function (methodName) { 63648 var args = []; 63649 for (var _i = 1; _i < arguments.length; _i++) { 63650 args[_i - 1] = arguments[_i]; 63651 } 63652 var results = []; 63653 this.items.forEach(function (item) { 63654 results.push(item[methodName].apply(item, args)); 63655 }); 63656 return results; 63657 }; 63658 return Iterator; 63659}()); 63660exports.default = Iterator; 63661 63662 63663/***/ }), 63664/* 239 */ 63665/***/ (function(module, exports, __webpack_require__) { 63666 63667Object.defineProperty(exports, "__esModule", { value: true }); 63668var $ = __webpack_require__(3); 63669var util_1 = __webpack_require__(4); 63670/* Toolbar with buttons and title 63671----------------------------------------------------------------------------------------------------------------------*/ 63672var Toolbar = /** @class */ (function () { 63673 function Toolbar(calendar, toolbarOptions) { 63674 this.el = null; // mirrors local `el` 63675 this.viewsWithButtons = []; 63676 this.calendar = calendar; 63677 this.toolbarOptions = toolbarOptions; 63678 } 63679 // method to update toolbar-specific options, not calendar-wide options 63680 Toolbar.prototype.setToolbarOptions = function (newToolbarOptions) { 63681 this.toolbarOptions = newToolbarOptions; 63682 }; 63683 // can be called repeatedly and will rerender 63684 Toolbar.prototype.render = function () { 63685 var sections = this.toolbarOptions.layout; 63686 var el = this.el; 63687 if (sections) { 63688 if (!el) { 63689 el = this.el = $("<div class='fc-toolbar " + this.toolbarOptions.extraClasses + "'/>"); 63690 } 63691 else { 63692 el.empty(); 63693 } 63694 el.append(this.renderSection('left')) 63695 .append(this.renderSection('right')) 63696 .append(this.renderSection('center')) 63697 .append('<div class="fc-clear"/>'); 63698 } 63699 else { 63700 this.removeElement(); 63701 } 63702 }; 63703 Toolbar.prototype.removeElement = function () { 63704 if (this.el) { 63705 this.el.remove(); 63706 this.el = null; 63707 } 63708 }; 63709 Toolbar.prototype.renderSection = function (position) { 63710 var _this = this; 63711 var calendar = this.calendar; 63712 var theme = calendar.theme; 63713 var optionsManager = calendar.optionsManager; 63714 var viewSpecManager = calendar.viewSpecManager; 63715 var sectionEl = $('<div class="fc-' + position + '"/>'); 63716 var buttonStr = this.toolbarOptions.layout[position]; 63717 var calendarCustomButtons = optionsManager.get('customButtons') || {}; 63718 var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {}; 63719 var calendarButtonText = optionsManager.get('buttonText') || {}; 63720 if (buttonStr) { 63721 $.each(buttonStr.split(' '), function (i, buttonGroupStr) { 63722 var groupChildren = $(); 63723 var isOnlyButtons = true; 63724 var groupEl; 63725 $.each(buttonGroupStr.split(','), function (j, buttonName) { 63726 var customButtonProps; 63727 var viewSpec; 63728 var buttonClick; 63729 var buttonIcon; // only one of these will be set 63730 var buttonText; // " 63731 var buttonInnerHtml; 63732 var buttonClasses; 63733 var buttonEl; 63734 var buttonAriaAttr; 63735 if (buttonName === 'title') { 63736 groupChildren = groupChildren.add($('<h2> </h2>')); // we always want it to take up height 63737 isOnlyButtons = false; 63738 } 63739 else { 63740 if ((customButtonProps = calendarCustomButtons[buttonName])) { 63741 buttonClick = function (ev) { 63742 if (customButtonProps.click) { 63743 customButtonProps.click.call(buttonEl[0], ev); 63744 } 63745 }; 63746 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || 63747 (buttonIcon = theme.getIconClass(buttonName)) || 63748 (buttonText = customButtonProps.text); 63749 } 63750 else if ((viewSpec = viewSpecManager.getViewSpec(buttonName))) { 63751 _this.viewsWithButtons.push(buttonName); 63752 buttonClick = function () { 63753 calendar.changeView(buttonName); 63754 }; 63755 (buttonText = viewSpec.buttonTextOverride) || 63756 (buttonIcon = theme.getIconClass(buttonName)) || 63757 (buttonText = viewSpec.buttonTextDefault); 63758 } 63759 else if (calendar[buttonName]) { 63760 buttonClick = function () { 63761 calendar[buttonName](); 63762 }; 63763 (buttonText = calendarButtonTextOverrides[buttonName]) || 63764 (buttonIcon = theme.getIconClass(buttonName)) || 63765 (buttonText = calendarButtonText[buttonName]); 63766 // ^ everything else is considered default 63767 } 63768 if (buttonClick) {
63769 buttonClasses = [ 63770 'fc-' + buttonName + '-button', 63771 theme.getClass('button'), 63772 theme.getClass('stateDefault') 63773 ]; 63774 if (buttonText) { 63775 buttonInnerHtml = util_1.htmlEscape(buttonText); 63776 buttonAriaAttr = ''; 63777 } 63778 else if (buttonIcon) { 63779 buttonInnerHtml = "<span class='" + buttonIcon + "'></span>"; 63780 buttonAriaAttr = ' aria-label="' + buttonName + '"'; 63781 } 63782 buttonEl = $(// type="button" so that it doesn't submit a form 63783 '<button type="button" class="' + buttonClasses.join(' ') + '"' + 63784 buttonAriaAttr + 63785 '>' + buttonInnerHtml + '</button>') 63786 .click(function (ev) { 63787 // don't process clicks for disabled buttons 63788 if (!buttonEl.hasClass(theme.getClass('stateDisabled'))) { 63789 buttonClick(ev); 63790 // after the click action, if the button becomes the "active" tab, or disabled, 63791 // it should never have a hover class, so remove it now. 63792 if (buttonEl.hasClass(theme.getClass('stateActive')) || 63793 buttonEl.hasClass(theme.getClass('stateDisabled'))) { 63794 buttonEl.removeClass(theme.getClass('stateHover')); 63795 } 63796 } 63797 }) 63798 .mousedown(function () { 63799 // the *down* effect (mouse pressed in). 63800 // only on buttons that are not the "active" tab, or disabled 63801 buttonEl 63802 .not('.' + theme.getClass('stateActive')) 63803 .not('.' + theme.getClass('stateDisabled')) 63804 .addClass(theme.getClass('stateDown')); 63805 }) 63806 .mouseup(function () { 63807 // undo the *down* effect 63808 buttonEl.removeClass(theme.getClass('stateDown')); 63809 }) 63810 .hover(function () { 63811 // the *hover* effect. 63812 // only on buttons that are not the "active" tab, or disabled 63813 buttonEl 63814 .not('.' + theme.getClass('stateActive')) 63815 .not('.' + theme.getClass('stateDisabled')) 63816 .addClass(theme.getClass('stateHover')); 63817 }, function () { 63818 // undo the *hover* effect 63819 buttonEl 63820 .removeClass(theme.getClass('stateHover')) 63821 .removeClass(theme.getClass('stateDown')); // if mouseleave happens before mouseup 63822 }); 63823 groupChildren = groupChildren.add(buttonEl); 63824 } 63825 } 63826 }); 63827 if (isOnlyButtons) { 63828 groupChildren 63829 .first().addClass(theme.getClass('cornerLeft')).end() 63830 .last().addClass(theme.getClass('cornerRight')).end(); 63831 } 63832 if (groupChildren.length > 1) { 63833 groupEl = $('<div/>'); 63834 if (isOnlyButtons) { 63835 groupEl.addClass(theme.getClass('buttonGroup')); 63836 } 63837 groupEl.append(groupChildren); 63838 sectionEl.append(groupEl); 63839 } 63840 else { 63841 sectionEl.append(groupChildren); // 1 or 0 children 63842 } 63843 }); 63844 } 63845 return sectionEl; 63846 }; 63847 Toolbar.prototype.updateTitle = function (text) { 63848 if (this.el) { 63849 this.el.find('h2').text(text); 63850 } 63851 }; 63852 Toolbar.prototype.activateButton = function (buttonName) { 63853 if (this.el) { 63854 this.el.find('.fc-' + buttonName + '-button') 63855 .addClass(this.calendar.theme.getClass('stateActive')); 63856 } 63857 }; 63858 Toolbar.prototype.deactivateButton = function (buttonName) { 63859 if (this.el) { 63860 this.el.find('.fc-' + buttonName + '-button') 63861 .removeClass(this.calendar.theme.getClass('stateActive')); 63862 } 63863 }; 63864 Toolbar.prototype.disableButton = function (buttonName) { 63865 if (this.el) { 63866 this.el.find('.fc-' + buttonName + '-button') 63867 .prop('disabled', true) 63868 .addClass(this.calendar.theme.getClass('stateDisabled')); 63869 } 63870 }; 63871 Toolbar.prototype.enableButton = function (buttonName) { 63872 if (this.el) { 63873 this.el.find('.fc-' + buttonName + '-button') 63874 .prop('disabled', false) 63875 .removeClass(this.calendar.theme.getClass('stateDisabled')); 63876 } 63877 }; 63878 Toolbar.prototype.getViewsWithButtons = function () { 63879 return this.viewsWithButtons; 63880 }; 63881 return Toolbar; 63882}()); 63883exports.default = Toolbar; 63884 63885 63886/***/ }), 63887/* 240 */ 63888/***/ (function(module, exports, __webpack_require__) { 63889 63890Object.defineProperty(exports, "__esModule", { value: true });
63891var tslib_1 = __webpack_require__(2); 63892var $ = __webpack_require__(3); 63893var util_1 = __webpack_require__(4); 63894var options_1 = __webpack_require__(32); 63895var locale_1 = __webpack_require__(31); 63896var Model_1 = __webpack_require__(48); 63897var OptionsManager = /** @class */ (function (_super) { 63898 tslib_1.__extends(OptionsManager, _super); 63899 function OptionsManager(_calendar, overrides) { 63900 var _this = _super.call(this) || this; 63901 _this._calendar = _calendar; 63902 _this.overrides = $.extend({}, overrides); // make a copy 63903 _this.dynamicOverrides = {}; 63904 _this.compute(); 63905 return _this; 63906 } 63907 OptionsManager.prototype.add = function (newOptionHash) { 63908 var optionCnt = 0; 63909 var optionName; 63910 this.recordOverrides(newOptionHash); // will trigger this model's watchers 63911 for (optionName in newOptionHash) { 63912 optionCnt++; 63913 } 63914 // special-case handling of single option change. 63915 // if only one option change, `optionName` will be its name. 63916 if (optionCnt === 1) { 63917 if (optionName === 'height' || optionName === 'contentHeight' || optionName === 'aspectRatio') { 63918 this._calendar.updateViewSize(true); // isResize=true 63919 return; 63920 } 63921 else if (optionName === 'defaultDate') { 63922 return; // can't change date this way. use gotoDate instead 63923 } 63924 else if (optionName === 'businessHours') { 63925 return; // this model already reacts to this 63926 } 63927 else if (/^(event|select)(Overlap|Constraint|Allow)$/.test(optionName)) { 63928 return; // doesn't affect rendering. only interactions. 63929 } 63930 else if (optionName === 'timezone') { 63931 this._calendar.view.flash('initialEvents'); 63932 return; 63933 } 63934 } 63935 // catch-all. rerender the header and footer and rebuild/rerender the current view 63936 this._calendar.renderHeader(); 63937 this._calendar.renderFooter(); 63938 // even non-current views will be affected by this option change. do before rerender 63939 // TODO: detangle 63940 this._calendar.viewsByType = {}; 63941 this._calendar.reinitView(); 63942 }; 63943 // Computes the flattened options hash for the calendar and assigns to `this.options`. 63944 // Assumes this.overrides and this.dynamicOverrides have already been initialized. 63945 OptionsManager.prototype.compute = function () { 63946 var locale; 63947 var localeDefaults; 63948 var isRTL; 63949 var dirDefaults; 63950 var rawOptions; 63951 locale = util_1.firstDefined(// explicit locale option given? 63952 this.dynamicOverrides.locale, this.overrides.locale); 63953 localeDefaults = locale_1.localeOptionHash[locale]; 63954 if (!localeDefaults) { 63955 locale = options_1.globalDefaults.locale; 63956 localeDefaults = locale_1.localeOptionHash[locale] || {}; 63957 } 63958 isRTL = util_1.firstDefined(// based on options computed so far, is direction RTL? 63959 this.dynamicOverrides.isRTL, this.overrides.isRTL, localeDefaults.isRTL, options_1.globalDefaults.isRTL); 63960 dirDefaults = isRTL ? options_1.rtlDefaults : {}; 63961 this.dirDefaults = dirDefaults; 63962 this.localeDefaults = localeDefaults; 63963 rawOptions = options_1.mergeOptions([ 63964 options_1.globalDefaults, 63965 dirDefaults, 63966 localeDefaults, 63967 this.overrides, 63968 this.dynamicOverrides 63969 ]); 63970 locale_1.populateInstanceComputableOptions(rawOptions); // fill in gaps with computed options 63971 this.reset(rawOptions); 63972 }; 63973 // stores the new options internally, but does not rerender anything. 63974 OptionsManager.prototype.recordOverrides = function (newOptionHash) { 63975 var optionName; 63976 for (optionName in newOptionHash) { 63977 this.dynamicOverrides[optionName] = newOptionHash[optionName]; 63978 } 63979 this._calendar.viewSpecManager.clearCache(); // the dynamic override invalidates the options in this cache, so just clear it 63980 this.compute(); // this.options needs to be recomputed after the dynamic override 63981 }; 63982 return OptionsManager; 63983}(Model_1.default)); 63984exports.default = OptionsManager; 63985 63986 63987/***/ }), 63988/* 241 */ 63989/***/ (function(module, exports, __webpack_require__) { 63990 63991Object.defineProperty(exports, "__esModule", { value: true });
63992var moment = __webpack_require__(0); 63993var $ = __webpack_require__(3); 63994var ViewRegistry_1 = __webpack_require__(22); 63995var util_1 = __webpack_require__(4); 63996var options_1 = __webpack_require__(32); 63997var locale_1 = __webpack_require__(31); 63998var ViewSpecManager = /** @class */ (function () { 63999 function ViewSpecManager(optionsManager, _calendar) { 64000 this.optionsManager = optionsManager; 64001 this._calendar = _calendar; 64002 this.clearCache(); 64003 } 64004 ViewSpecManager.prototype.clearCache = function () { 64005 this.viewSpecCache = {}; 64006 }; 64007 // Gets information about how to create a view. Will use a cache. 64008 ViewSpecManager.prototype.getViewSpec = function (viewType) { 64009 var cache = this.viewSpecCache; 64010 return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType)); 64011 }; 64012 // Given a duration singular unit, like "week" or "day", finds a matching view spec. 64013 // Preference is given to views that have corresponding buttons. 64014 ViewSpecManager.prototype.getUnitViewSpec = function (unit) { 64015 var viewTypes; 64016 var i; 64017 var spec; 64018 if ($.inArray(unit, util_1.unitsDesc) !== -1) { 64019 // put views that have buttons first. there will be duplicates, but oh well 64020 viewTypes = this._calendar.header.getViewsWithButtons(); // TODO: include footer as well? 64021 $.each(ViewRegistry_1.viewHash, function (viewType) { 64022 viewTypes.push(viewType); 64023 }); 64024 for (i = 0; i < viewTypes.length; i++) { 64025 spec = this.getViewSpec(viewTypes[i]); 64026 if (spec) { 64027 if (spec.singleUnit === unit) { 64028 return spec; 64029 } 64030 } 64031 } 64032 } 64033 }; 64034 // Builds an object with information on how to create a given view 64035 ViewSpecManager.prototype.buildViewSpec = function (requestedViewType) { 64036 var viewOverrides = this.optionsManager.overrides.views || {}; 64037 var specChain = []; // for the view. lowest to highest priority 64038 var defaultsChain = []; // for the view. lowest to highest priority 64039 var overridesChain = []; // for the view. lowest to highest priority 64040 var viewType = requestedViewType; 64041 var spec; // for the view 64042 var overrides; // for the view 64043 var durationInput; 64044 var duration; 64045 var unit; 64046 // iterate from the specific view definition to a more general one until we hit an actual View class 64047 while (viewType) { 64048 spec = ViewRegistry_1.viewHash[viewType]; 64049 overrides = viewOverrides[viewType]; 64050 viewType = null; // clear. might repopulate for another iteration 64051 if (typeof spec === 'function') { 64052 spec = { 'class': spec }; 64053 } 64054 if (spec) { 64055 specChain.unshift(spec); 64056 defaultsChain.unshift(spec.defaults || {}); 64057 durationInput = durationInput || spec.duration; 64058 viewType = viewType || spec.type; 64059 } 64060 if (overrides) { 64061 overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level 64062 durationInput = durationInput || overrides.duration; 64063 viewType = viewType || overrides.type; 64064 } 64065 } 64066 spec = util_1.mergeProps(specChain); 64067 spec.type = requestedViewType; 64068 if (!spec['class']) { 64069 return false; 64070 } 64071 // fall back to top-level `duration` option 64072 durationInput = durationInput || 64073 this.optionsManager.dynamicOverrides.duration || 64074 this.optionsManager.overrides.duration; 64075 if (durationInput) { 64076 duration = moment.duration(durationInput); 64077 if (duration.valueOf()) { 64078 unit = util_1.computeDurationGreatestUnit(duration, durationInput); 64079 spec.duration = duration; 64080 spec.durationUnit = unit; 64081 // view is a single-unit duration, like "week" or "day" 64082 // incorporate options for this. lowest priority 64083 if (duration.as(unit) === 1) { 64084 spec.singleUnit = unit; 64085 overridesChain.unshift(viewOverrides[unit] || {}); 64086 } 64087 } 64088 } 64089 spec.defaults = options_1.mergeOptions(defaultsChain); 64090 spec.overrides = options_1.mergeOptions(overridesChain); 64091 this.buildViewSpecOptions(spec); 64092 this.buildViewSpecButtonText(spec, requestedViewType); 64093 return spec; 64094 }; 64095 // Builds and assigns a view spec's options object from its already-assigned defaults and overrides 64096 ViewSpecManager.prototype.buildViewSpecOptions = function (spec) { 64097 var optionsManager = this.optionsManager; 64098 spec.options = options_1.mergeOptions([ 64099 options_1.globalDefaults, 64100 spec.defaults, 64101 optionsManager.dirDefaults, 64102 optionsManager.localeDefaults, 64103 optionsManager.overrides, 64104 spec.overrides, 64105 optionsManager.dynamicOverrides // dynamically set via setter. highest precedence 64106 ]); 64107 locale_1.populateInstanceComputableOptions(spec.options); 64108 }; 64109 // Computes and assigns a view spec's buttonText-related options 64110 ViewSpecManager.prototype.buildViewSpecButtonText = function (spec, requestedViewType) { 64111 var optionsManager = this.optionsManager; 64112 // given an options object with a possible `buttonText` hash, lookup the buttonText for the 64113 // requested view, falling back to a generic unit entry like "week" or "day" 64114 function queryButtonText(options) { 64115 var buttonText = options.buttonText || {}; 64116 return buttonText[requestedViewType] || 64117 // view can decide to look up a certain key 64118 (spec.buttonTextKey ? buttonText[spec.buttonTextKey] : null) || 64119 // a key like "month" 64120 (spec.singleUnit ? buttonText[spec.singleUnit] : null); 64121 } 64122 // highest to lowest priority 64123 spec.buttonTextOverride = 64124 queryButtonText(optionsManager.dynamicOverrides) || 64125 queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence 64126 spec.overrides.buttonText; // `buttonText` for view-specific options is a string 64127 // highest to lowest priority. mirrors buildViewSpecOptions 64128 spec.buttonTextDefault = 64129 queryButtonText(optionsManager.localeDefaults) || 64130 queryButtonText(optionsManager.dirDefaults) ||
64131 spec.defaults.buttonText || // a single string. from ViewSubclass.defaults 64132 queryButtonText(options_1.globalDefaults) || 64133 (spec.duration ? this._calendar.humanizeDuration(spec.duration) : null) || // like "3 days" 64134 requestedViewType; // fall back to given view name 64135 }; 64136 return ViewSpecManager; 64137}()); 64138exports.default = ViewSpecManager; 64139 64140 64141/***/ }), 64142/* 242 */ 64143/***/ (function(module, exports, __webpack_require__) { 64144 64145Object.defineProperty(exports, "__esModule", { value: true }); 64146var $ = __webpack_require__(3); 64147var util_1 = __webpack_require__(4); 64148var EventPeriod_1 = __webpack_require__(243); 64149var ArrayEventSource_1 = __webpack_require__(52); 64150var EventSource_1 = __webpack_require__(6); 64151var EventSourceParser_1 = __webpack_require__(38); 64152var SingleEventDef_1 = __webpack_require__(13); 64153var EventInstanceGroup_1 = __webpack_require__(18); 64154var EmitterMixin_1 = __webpack_require__(11); 64155var ListenerMixin_1 = __webpack_require__(7); 64156var EventManager = /** @class */ (function () { 64157 function EventManager(calendar) { 64158 this.calendar = calendar; 64159 this.stickySource = new ArrayEventSource_1.default(calendar); 64160 this.otherSources = []; 64161 } 64162 EventManager.prototype.requestEvents = function (start, end, timezone, force) { 64163 if (force || 64164 !this.currentPeriod || 64165 !this.currentPeriod.isWithinRange(start, end) || 64166 timezone !== this.currentPeriod.timezone) { 64167 this.setPeriod(// will change this.currentPeriod 64168 new EventPeriod_1.default(start, end, timezone)); 64169 } 64170 return this.currentPeriod.whenReleased(); 64171 }; 64172 // Source Adding/Removing 64173 // ----------------------------------------------------------------------------------------------------------------- 64174 EventManager.prototype.addSource = function (eventSource) { 64175 this.otherSources.push(eventSource); 64176 if (this.currentPeriod) { 64177 this.currentPeriod.requestSource(eventSource); // might release 64178 } 64179 }; 64180 EventManager.prototype.removeSource = function (doomedSource) { 64181 util_1.removeExact(this.otherSources, doomedSource); 64182 if (this.currentPeriod) { 64183 this.currentPeriod.purgeSource(doomedSource); // might release 64184 } 64185 }; 64186 EventManager.prototype.removeAllSources = function () { 64187 this.otherSources = []; 64188 if (this.currentPeriod) { 64189 this.currentPeriod.purgeAllSources(); // might release 64190 } 64191 }; 64192 // Source Refetching 64193 // ----------------------------------------------------------------------------------------------------------------- 64194 EventManager.prototype.refetchSource = function (eventSource) { 64195 var currentPeriod = this.currentPeriod; 64196 if (currentPeriod) { 64197 currentPeriod.freeze(); 64198 currentPeriod.purgeSource(eventSource); 64199 currentPeriod.requestSource(eventSource); 64200 currentPeriod.thaw(); 64201 } 64202 }; 64203 EventManager.prototype.refetchAllSources = function () { 64204 var currentPeriod = this.currentPeriod; 64205 if (currentPeriod) { 64206 currentPeriod.freeze(); 64207 currentPeriod.purgeAllSources(); 64208 currentPeriod.requestSources(this.getSources()); 64209 currentPeriod.thaw(); 64210 } 64211 }; 64212 // Source Querying 64213 // ----------------------------------------------------------------------------------------------------------------- 64214 EventManager.prototype.getSources = function () { 64215 return [this.stickySource].concat(this.otherSources); 64216 }; 64217 // like querySources, but accepts multple match criteria (like multiple IDs) 64218 EventManager.prototype.multiQuerySources = function (matchInputs) { 64219 // coerce into an array 64220 if (!matchInputs) { 64221 matchInputs = []; 64222 } 64223 else if (!$.isArray(matchInputs)) { 64224 matchInputs = [matchInputs]; 64225 } 64226 var matchingSources = []; 64227 var i; 64228 // resolve raw inputs to real event source objects 64229 for (i = 0; i < matchInputs.length; i++) { 64230 matchingSources.push.apply(// append 64231 matchingSources, this.querySources(matchInputs[i])); 64232 } 64233 return matchingSources; 64234 }; 64235 // matchInput can either by a real event source object, an ID, or the function/URL for the source. 64236 // returns an array of matching source objects. 64237 EventManager.prototype.querySources = function (matchInput) { 64238 var sources = this.otherSources; 64239 var i; 64240 var source; 64241 // given a proper event source object 64242 for (i = 0; i < sources.length; i++) { 64243 source = sources[i];
64244 if (source === matchInput) { 64245 return [source]; 64246 } 64247 } 64248 // an ID match 64249 source = this.getSourceById(EventSource_1.default.normalizeId(matchInput)); 64250 if (source) { 64251 return [source]; 64252 } 64253 // parse as an event source 64254 matchInput = EventSourceParser_1.default.parse(matchInput, this.calendar); 64255 if (matchInput) { 64256 return $.grep(sources, function (source) { 64257 return isSourcesEquivalent(matchInput, source); 64258 }); 64259 } 64260 }; 64261 /* 64262 ID assumed to already be normalized 64263 */ 64264 EventManager.prototype.getSourceById = function (id) { 64265 return $.grep(this.otherSources, function (source) { 64266 return source.id && source.id === id; 64267 })[0]; 64268 }; 64269 // Event-Period 64270 // ----------------------------------------------------------------------------------------------------------------- 64271 EventManager.prototype.setPeriod = function (eventPeriod) { 64272 if (this.currentPeriod) { 64273 this.unbindPeriod(this.currentPeriod); 64274 this.currentPeriod = null; 64275 } 64276 this.currentPeriod = eventPeriod; 64277 this.bindPeriod(eventPeriod); 64278 eventPeriod.requestSources(this.getSources()); 64279 }; 64280 EventManager.prototype.bindPeriod = function (eventPeriod) { 64281 this.listenTo(eventPeriod, 'release', function (eventsPayload) { 64282 this.trigger('release', eventsPayload); 64283 }); 64284 }; 64285 EventManager.prototype.unbindPeriod = function (eventPeriod) { 64286 this.stopListeningTo(eventPeriod); 64287 }; 64288 // Event Getting/Adding/Removing 64289 // ----------------------------------------------------------------------------------------------------------------- 64290 EventManager.prototype.getEventDefByUid = function (uid) { 64291 if (this.currentPeriod) { 64292 return this.currentPeriod.getEventDefByUid(uid); 64293 } 64294 }; 64295 EventManager.prototype.addEventDef = function (eventDef, isSticky) { 64296 if (isSticky) { 64297 this.stickySource.addEventDef(eventDef); 64298 } 64299 if (this.currentPeriod) { 64300 this.currentPeriod.addEventDef(eventDef); // might release 64301 } 64302 }; 64303 EventManager.prototype.removeEventDefsById = function (eventId) {
64304 this.getSources().forEach(function (eventSource) { 64305 eventSource.removeEventDefsById(eventId); 64306 }); 64307 if (this.currentPeriod) { 64308 this.currentPeriod.removeEventDefsById(eventId); // might release 64309 } 64310 }; 64311 EventManager.prototype.removeAllEventDefs = function () { 64312 this.getSources().forEach(function (eventSource) { 64313 eventSource.removeAllEventDefs(); 64314 }); 64315 if (this.currentPeriod) { 64316 this.currentPeriod.removeAllEventDefs(); 64317 } 64318 }; 64319 // Event Mutating 64320 // ----------------------------------------------------------------------------------------------------------------- 64321 /* 64322 Returns an undo function. 64323 */ 64324 EventManager.prototype.mutateEventsWithId = function (eventDefId, eventDefMutation) { 64325 var currentPeriod = this.currentPeriod; 64326 var eventDefs; 64327 var undoFuncs = []; 64328 if (currentPeriod) { 64329 currentPeriod.freeze(); 64330 eventDefs = currentPeriod.getEventDefsById(eventDefId); 64331 eventDefs.forEach(function (eventDef) { 64332 // add/remove esp because id might change 64333 currentPeriod.removeEventDef(eventDef); 64334 undoFuncs.push(eventDefMutation.mutateSingle(eventDef)); 64335 currentPeriod.addEventDef(eventDef); 64336 }); 64337 currentPeriod.thaw(); 64338 return function () { 64339 currentPeriod.freeze(); 64340 for (var i = 0; i < eventDefs.length; i++) { 64341 currentPeriod.removeEventDef(eventDefs[i]); 64342 undoFuncs[i](); 64343 currentPeriod.addEventDef(eventDefs[i]); 64344 } 64345 currentPeriod.thaw(); 64346 }; 64347 } 64348 return function () { }; 64349 }; 64350 /* 64351 copies and then mutates 64352 */ 64353 EventManager.prototype.buildMutatedEventInstanceGroup = function (eventDefId, eventDefMutation) { 64354 var eventDefs = this.getEventDefsById(eventDefId); 64355 var i; 64356 var defCopy; 64357 var allInstances = []; 64358 for (i = 0; i < eventDefs.length; i++) { 64359 defCopy = eventDefs[i].clone(); 64360 if (defCopy instanceof SingleEventDef_1.default) { 64361 eventDefMutation.mutateSingle(defCopy); 64362 allInstances.push.apply(allInstances, // append 64363 defCopy.buildInstances()); 64364 } 64365 } 64366 return new EventInstanceGroup_1.default(allInstances); 64367 }; 64368 // Freezing 64369 // ----------------------------------------------------------------------------------------------------------------- 64370 EventManager.prototype.freeze = function () { 64371 if (this.currentPeriod) { 64372 this.currentPeriod.freeze(); 64373 } 64374 }; 64375 EventManager.prototype.thaw = function () { 64376 if (this.currentPeriod) { 64377 this.currentPeriod.thaw(); 64378 } 64379 }; 64380 // methods that simply forward to EventPeriod 64381 EventManager.prototype.getEventDefsById = function (eventDefId) { 64382 return this.currentPeriod.getEventDefsById(eventDefId); 64383 }; 64384 EventManager.prototype.getEventInstances = function () { 64385 return this.currentPeriod.getEventInstances(); 64386 }; 64387 EventManager.prototype.getEventInstancesWithId = function (eventDefId) { 64388 return this.currentPeriod.getEventInstancesWithId(eventDefId); 64389 }; 64390 EventManager.prototype.getEventInstancesWithoutId = function (eventDefId) { 64391 return this.currentPeriod.getEventInstancesWithoutId(eventDefId); 64392 }; 64393 return EventManager; 64394}()); 64395exports.default = EventManager; 64396EmitterMixin_1.default.mixInto(EventManager); 64397ListenerMixin_1.default.mixInto(EventManager); 64398function isSourcesEquivalent(source0, source1) { 64399 return source0.getPrimitive() === source1.getPrimitive(); 64400} 64401 64402 64403/***/ }), 64404/* 243 */ 64405/***/ (function(module, exports, __webpack_require__) { 64406 64407Object.defineProperty(exports, "__esModule", { value: true }); 64408var $ = __webpack_require__(3); 64409var util_1 = __webpack_require__(4); 64410var Promise_1 = __webpack_require__(20); 64411var EmitterMixin_1 = __webpack_require__(11); 64412var UnzonedRange_1 = __webpack_require__(5); 64413var EventInstanceGroup_1 = __webpack_require__(18); 64414var EventPeriod = /** @class */ (function () { 64415 function EventPeriod(start, end, timezone) { 64416 this.pendingCnt = 0; 64417 this.freezeDepth = 0; 64418 this.stuntedReleaseCnt = 0; 64419 this.releaseCnt = 0; 64420 this.start = start; 64421 this.end = end; 64422 this.timezone = timezone; 64423 this.unzonedRange = new UnzonedRange_1.default(start.clone().stripZone(), end.clone().stripZone()); 64424 this.requestsByUid = {}; 64425 this.eventDefsByUid = {}; 64426 this.eventDefsById = {}; 64427 this.eventInstanceGroupsById = {}; 64428 } 64429 EventPeriod.prototype.isWithinRange = function (start, end) { 64430 // TODO: use a range util function? 64431 return !start.isBefore(this.start) && !end.isAfter(this.end); 64432 }; 64433 // Requesting and Purging 64434 // ----------------------------------------------------------------------------------------------------------------- 64435 EventPeriod.prototype.requestSources = function (sources) { 64436 this.freeze(); 64437 for (var i = 0; i < sources.length; i++) { 64438 this.requestSource(sources[i]); 64439 } 64440 this.thaw(); 64441 }; 64442 EventPeriod.prototype.requestSource = function (source) { 64443 var _this = this; 64444 var request = { source: source, status: 'pending', eventDefs: null }; 64445 this.requestsByUid[source.uid] = request; 64446 this.pendingCnt += 1; 64447 source.fetch(this.start, this.end, this.timezone).then(function (eventDefs) { 64448 if (request.status !== 'cancelled') { 64449 request.status = 'completed'; 64450 request.eventDefs = eventDefs; 64451 _this.addEventDefs(eventDefs); 64452 _this.pendingCnt--; 64453 _this.tryRelease(); 64454 } 64455 }, function () { 64456 if (request.status !== 'cancelled') { 64457 request.status = 'failed'; 64458 _this.pendingCnt--; 64459 _this.tryRelease(); 64460 } 64461 }); 64462 }; 64463 EventPeriod.prototype.purgeSource = function (source) { 64464 var request = this.requestsByUid[source.uid]; 64465 if (request) { 64466 delete this.requestsByUid[source.uid]; 64467 if (request.status === 'pending') { 64468 request.status = 'cancelled'; 64469 this.pendingCnt--; 64470 this.tryRelease(); 64471 } 64472 else if (request.status === 'completed') {
64473 request.eventDefs.forEach(this.removeEventDef.bind(this)); 64474 } 64475 } 64476 }; 64477 EventPeriod.prototype.purgeAllSources = function () { 64478 var requestsByUid = this.requestsByUid; 64479 var uid; 64480 var request; 64481 var completedCnt = 0; 64482 for (uid in requestsByUid) { 64483 request = requestsByUid[uid]; 64484 if (request.status === 'pending') { 64485 request.status = 'cancelled'; 64486 } 64487 else if (request.status === 'completed') { 64488 completedCnt++; 64489 } 64490 } 64491 this.requestsByUid = {}; 64492 this.pendingCnt = 0; 64493 if (completedCnt) { 64494 this.removeAllEventDefs(); // might release 64495 } 64496 }; 64497 // Event Definitions 64498 // ----------------------------------------------------------------------------------------------------------------- 64499 EventPeriod.prototype.getEventDefByUid = function (eventDefUid) { 64500 return this.eventDefsByUid[eventDefUid]; 64501 }; 64502 EventPeriod.prototype.getEventDefsById = function (eventDefId) { 64503 var a = this.eventDefsById[eventDefId]; 64504 if (a) { 64505 return a.slice(); // clone 64506 } 64507 return []; 64508 }; 64509 EventPeriod.prototype.addEventDefs = function (eventDefs) { 64510 for (var i = 0; i < eventDefs.length; i++) { 64511 this.addEventDef(eventDefs[i]); 64512 } 64513 }; 64514 EventPeriod.prototype.addEventDef = function (eventDef) { 64515 var eventDefsById = this.eventDefsById; 64516 var eventDefId = eventDef.id; 64517 var eventDefs = eventDefsById[eventDefId] || (eventDefsById[eventDefId] = []); 64518 var eventInstances = eventDef.buildInstances(this.unzonedRange); 64519 var i; 64520 eventDefs.push(eventDef); 64521 this.eventDefsByUid[eventDef.uid] = eventDef; 64522 for (i = 0; i < eventInstances.length; i++) { 64523 this.addEventInstance(eventInstances[i], eventDefId); 64524 } 64525 }; 64526 EventPeriod.prototype.removeEventDefsById = function (eventDefId) { 64527 var _this = this; 64528 this.getEventDefsById(eventDefId).forEach(function (eventDef) { 64529 _this.removeEventDef(eventDef); 64530 }); 64531 }; 64532 EventPeriod.prototype.removeAllEventDefs = function () { 64533 var isEmpty = $.isEmptyObject(this.eventDefsByUid); 64534 this.eventDefsByUid = {}; 64535 this.eventDefsById = {}; 64536 this.eventInstanceGroupsById = {}; 64537 if (!isEmpty) { 64538 this.tryRelease(); 64539 } 64540 }; 64541 EventPeriod.prototype.removeEventDef = function (eventDef) { 64542 var eventDefsById = this.eventDefsById; 64543 var eventDefs = eventDefsById[eventDef.id]; 64544 delete this.eventDefsByUid[eventDef.uid]; 64545 if (eventDefs) { 64546 util_1.removeExact(eventDefs, eventDef); 64547 if (!eventDefs.length) { 64548 delete eventDefsById[eventDef.id]; 64549 } 64550 this.removeEventInstancesForDef(eventDef); 64551 } 64552 }; 64553 // Event Instances 64554 // ----------------------------------------------------------------------------------------------------------------- 64555 EventPeriod.prototype.getEventInstances = function () { 64556 var eventInstanceGroupsById = this.eventInstanceGroupsById; 64557 var eventInstances = []; 64558 var id; 64559 for (id in eventInstanceGroupsById) { 64560 eventInstances.push.apply(eventInstances, // append 64561 eventInstanceGroupsById[id].eventInstances); 64562 } 64563 return eventInstances; 64564 }; 64565 EventPeriod.prototype.getEventInstancesWithId = function (eventDefId) { 64566 var eventInstanceGroup = this.eventInstanceGroupsById[eventDefId]; 64567 if (eventInstanceGroup) { 64568 return eventInstanceGroup.eventInstances.slice(); // clone 64569 } 64570 return []; 64571 }; 64572 EventPeriod.prototype.getEventInstancesWithoutId = function (eventDefId) { 64573 var eventInstanceGroupsById = this.eventInstanceGroupsById; 64574 var matchingInstances = []; 64575 var id; 64576 for (id in eventInstanceGroupsById) { 64577 if (id !== eventDefId) { 64578 matchingInstances.push.apply(matchingInstances, // append 64579 eventInstanceGroupsById[id].eventInstances); 64580 } 64581 } 64582 return matchingInstances; 64583 }; 64584 EventPeriod.prototype.addEventInstance = function (eventInstance, eventDefId) { 64585 var eventInstanceGroupsById = this.eventInstanceGroupsById; 64586 var eventInstanceGroup = eventInstanceGroupsById[eventDefId] || 64587 (eventInstanceGroupsById[eventDefId] = new EventInstanceGroup_1.default()); 64588 eventInstanceGroup.eventInstances.push(eventInstance); 64589 this.tryRelease(); 64590 }; 64591 EventPeriod.prototype.removeEventInstancesForDef = function (eventDef) { 64592 var eventInstanceGroupsById = this.eventInstanceGroupsById; 64593 var eventInstanceGroup = eventInstanceGroupsById[eventDef.id]; 64594 var removeCnt; 64595 if (eventInstanceGroup) { 64596 removeCnt = util_1.removeMatching(eventInstanceGroup.eventInstances, function (currentEventInstance) { 64597 return currentEventInstance.def === eventDef; 64598 }); 64599 if (!eventInstanceGroup.eventInstances.length) { 64600 delete eventInstanceGroupsById[eventDef.id]; 64601 } 64602 if (removeCnt) { 64603 this.tryRelease(); 64604 } 64605 } 64606 }; 64607 // Releasing and Freezing 64608 // ----------------------------------------------------------------------------------------------------------------- 64609 EventPeriod.prototype.tryRelease = function () { 64610 if (!this.pendingCnt) { 64611 if (!this.freezeDepth) { 64612 this.release(); 64613 } 64614 else { 64615 this.stuntedReleaseCnt++; 64616 } 64617 } 64618 }; 64619 EventPeriod.prototype.release = function () { 64620 this.releaseCnt++; 64621 this.trigger('release', this.eventInstanceGroupsById); 64622 }; 64623 EventPeriod.prototype.whenReleased = function () { 64624 var _this = this; 64625 if (this.releaseCnt) { 64626 return Promise_1.default.resolve(this.eventInstanceGroupsById); 64627 } 64628 else { 64629 return Promise_1.default.construct(function (onResolve) { 64630 _this.one('release', onResolve); 64631 }); 64632 } 64633 }; 64634 EventPeriod.prototype.freeze = function () { 64635 if (!(this.freezeDepth++)) { 64636 this.stuntedReleaseCnt = 0; 64637 } 64638 }; 64639 EventPeriod.prototype.thaw = function () { 64640 if (!(--this.freezeDepth) && this.stuntedReleaseCnt && !this.pendingCnt) { 64641 this.release(); 64642 } 64643 }; 64644 return EventPeriod; 64645}()); 64646exports.default = EventPeriod; 64647EmitterMixin_1.default.mixInto(EventPeriod); 64648 64649 64650/***/ }), 64651/* 244 */ 64652/***/ (function(module, exports, __webpack_require__) { 64653 64654Object.defineProperty(exports, "__esModule", { value: true });
64655var $ = __webpack_require__(3); 64656var util_1 = __webpack_require__(4); 64657var ListenerMixin_1 = __webpack_require__(7); 64658/* Creates a clone of an element and lets it track the mouse as it moves 64659----------------------------------------------------------------------------------------------------------------------*/ 64660var MouseFollower = /** @class */ (function () { 64661 function MouseFollower(sourceEl, options) { 64662 this.isFollowing = false; 64663 this.isHidden = false; 64664 this.isAnimating = false; // doing the revert animation? 64665 this.options = options = options || {}; 64666 this.sourceEl = sourceEl; 64667 this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent 64668 } 64669 // Causes the element to start following the mouse 64670 MouseFollower.prototype.start = function (ev) { 64671 if (!this.isFollowing) { 64672 this.isFollowing = true; 64673 this.y0 = util_1.getEvY(ev); 64674 this.x0 = util_1.getEvX(ev); 64675 this.topDelta = 0; 64676 this.leftDelta = 0; 64677 if (!this.isHidden) { 64678 this.updatePosition(); 64679 } 64680 if (util_1.getEvIsTouch(ev)) { 64681 this.listenTo($(document), 'touchmove', this.handleMove); 64682 } 64683 else { 64684 this.listenTo($(document), 'mousemove', this.handleMove); 64685 } 64686 } 64687 }; 64688 // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position. 64689 // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately. 64690 MouseFollower.prototype.stop = function (shouldRevert, callback) { 64691 var _this = this; 64692 var revertDuration = this.options.revertDuration; 64693 var complete = function () { 64694 _this.isAnimating = false; 64695 _this.removeElement(); 64696 _this.top0 = _this.left0 = null; // reset state for future updatePosition calls 64697 if (callback) { 64698 callback(); 64699 } 64700 }; 64701 if (this.isFollowing && !this.isAnimating) { 64702 this.isFollowing = false; 64703 this.stopListeningTo($(document)); 64704 if (shouldRevert && revertDuration && !this.isHidden) { 64705 this.isAnimating = true; 64706 this.el.animate({ 64707 top: this.top0, 64708 left: this.left0 64709 }, { 64710 duration: revertDuration, 64711 complete: complete 64712 }); 64713 } 64714 else { 64715 complete(); 64716 } 64717 } 64718 }; 64719 // Gets the tracking element. Create it if necessary 64720 MouseFollower.prototype.getEl = function () { 64721 var el = this.el; 64722 if (!el) { 64723 el = this.el = this.sourceEl.clone() 64724 .addClass(this.options.additionalClass || '') 64725 .css({ 64726 position: 'absolute', 64727 visibility: '', 64728 display: this.isHidden ? 'none' : '', 64729 margin: 0, 64730 right: 'auto', 64731 bottom: 'auto', 64732 width: this.sourceEl.width(), 64733 height: this.sourceEl.height(), 64734 opacity: this.options.opacity || '', 64735 zIndex: this.options.zIndex 64736 }); 64737 // we don't want long taps or any mouse interaction causing selection/menus. 64738 // would use preventSelection(), but that prevents selectstart, causing problems. 64739 el.addClass('fc-unselectable'); 64740 el.appendTo(this.parentEl); 64741 } 64742 return el; 64743 }; 64744 // Removes the tracking element if it has already been created 64745 MouseFollower.prototype.removeElement = function () { 64746 if (this.el) { 64747 this.el.remove(); 64748 this.el = null; 64749 } 64750 }; 64751 // Update the CSS position of the tracking element 64752 MouseFollower.prototype.updatePosition = function () { 64753 var sourceOffset; 64754 var origin; 64755 this.getEl(); // ensure this.el
64756 // make sure origin info was computed 64757 if (this.top0 == null) { 64758 sourceOffset = this.sourceEl.offset(); 64759 origin = this.el.offsetParent().offset(); 64760 this.top0 = sourceOffset.top - origin.top; 64761 this.left0 = sourceOffset.left - origin.left; 64762 } 64763 this.el.css({ 64764 top: this.top0 + this.topDelta, 64765 left: this.left0 + this.leftDelta 64766 }); 64767 }; 64768 // Gets called when the user moves the mouse 64769 MouseFollower.prototype.handleMove = function (ev) { 64770 this.topDelta = util_1.getEvY(ev) - this.y0; 64771 this.leftDelta = util_1.getEvX(ev) - this.x0; 64772 if (!this.isHidden) { 64773 this.updatePosition(); 64774 } 64775 }; 64776 // Temporarily makes the tracking element invisible. Can be called before following starts 64777 MouseFollower.prototype.hide = function () { 64778 if (!this.isHidden) { 64779 this.isHidden = true; 64780 if (this.el) { 64781 this.el.hide(); 64782 } 64783 } 64784 }; 64785 // Show the tracking element after it has been temporarily hidden 64786 MouseFollower.prototype.show = function () { 64787 if (this.isHidden) { 64788 this.isHidden = false; 64789 this.updatePosition(); 64790 this.getEl().show(); 64791 } 64792 }; 64793 return MouseFollower; 64794}()); 64795exports.default = MouseFollower; 64796ListenerMixin_1.default.mixInto(MouseFollower); 64797 64798 64799/***/ }), 64800/* 245 */ 64801/***/ (function(module, exports, __webpack_require__) { 64802 64803Object.defineProperty(exports, "__esModule", { value: true }); 64804var tslib_1 = __webpack_require__(2); 64805var HitDragListener_1 = __webpack_require__(23); 64806var Interaction_1 = __webpack_require__(15); 64807var DateClicking = /** @class */ (function (_super) { 64808 tslib_1.__extends(DateClicking, _super); 64809 /* 64810 component must implement: 64811 - bindDateHandlerToEl 64812 - getSafeHitFootprint 64813 - getHitEl 64814 */ 64815 function DateClicking(component) { 64816 var _this = _super.call(this, component) || this; 64817 _this.dragListener = _this.buildDragListener(); 64818 return _this; 64819 } 64820 DateClicking.prototype.end = function () { 64821 this.dragListener.endInteraction(); 64822 }; 64823 DateClicking.prototype.bindToEl = function (el) { 64824 var component = this.component; 64825 var dragListener = this.dragListener; 64826 component.bindDateHandlerToEl(el, 'mousedown', function (ev) { 64827 if (!component.shouldIgnoreMouse()) { 64828 dragListener.startInteraction(ev); 64829 } 64830 }); 64831 component.bindDateHandlerToEl(el, 'touchstart', function (ev) { 64832 if (!component.shouldIgnoreTouch()) { 64833 dragListener.startInteraction(ev); 64834 } 64835 }); 64836 }; 64837 // Creates a listener that tracks the user's drag across day elements, for day clicking. 64838 DateClicking.prototype.buildDragListener = function () { 64839 var _this = this; 64840 var component = this.component; 64841 var dayClickHit; // null if invalid dayClick 64842 var dragListener = new HitDragListener_1.default(component, { 64843 scroll: this.opt('dragScroll'), 64844 interactionStart: function () { 64845 dayClickHit = dragListener.origHit; 64846 }, 64847 hitOver: function (hit, isOrig, origHit) { 64848 // if user dragged to another cell at any point, it can no longer be a dayClick 64849 if (!isOrig) { 64850 dayClickHit = null; 64851 } 64852 }, 64853 hitOut: function () { 64854 dayClickHit = null; 64855 }, 64856 interactionEnd: function (ev, isCancelled) { 64857 var componentFootprint; 64858 if (!isCancelled && dayClickHit) { 64859 componentFootprint = component.getSafeHitFootprint(dayClickHit); 64860 if (componentFootprint) { 64861 _this.view.triggerDayClick(componentFootprint, component.getHitEl(dayClickHit), ev); 64862 } 64863 } 64864 } 64865 }); 64866 // because dragListener won't be called with any time delay, "dragging" will begin immediately, 64867 // which will kill any touchmoving/scrolling. Prevent this. 64868 dragListener.shouldCancelTouchScroll = false; 64869 dragListener.scrollAlwaysKills = true; 64870 return dragListener; 64871 }; 64872 return DateClicking; 64873}(Interaction_1.default)); 64874exports.default = DateClicking; 64875 64876 64877/***/ }), 64878/* 246 */ 64879/***/ (function(module, exports, __webpack_require__) { 64880 64881Object.defineProperty(exports, "__esModule", { value: true });
64882var tslib_1 = __webpack_require__(2); 64883var util_1 = __webpack_require__(4); 64884var EventRenderer_1 = __webpack_require__(42); 64885/* 64886Only handles foreground segs. 64887Does not own rendering. Use for low-level util methods by TimeGrid. 64888*/ 64889var TimeGridEventRenderer = /** @class */ (function (_super) { 64890 tslib_1.__extends(TimeGridEventRenderer, _super); 64891 function TimeGridEventRenderer(timeGrid, fillRenderer) { 64892 var _this = _super.call(this, timeGrid, fillRenderer) || this; 64893 _this.timeGrid = timeGrid; 64894 return _this; 64895 } 64896 TimeGridEventRenderer.prototype.renderFgSegs = function (segs) { 64897 this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls); 64898 }; 64899 // Given an array of foreground segments, render a DOM element for each, computes position, 64900 // and attaches to the column inner-container elements. 64901 TimeGridEventRenderer.prototype.renderFgSegsIntoContainers = function (segs, containerEls) { 64902 var segsByCol; 64903 var col; 64904 segsByCol = this.timeGrid.groupSegsByCol(segs); 64905 for (col = 0; col < this.timeGrid.colCnt; col++) { 64906 this.updateFgSegCoords(segsByCol[col]); 64907 } 64908 this.timeGrid.attachSegsByCol(segsByCol, containerEls); 64909 }; 64910 TimeGridEventRenderer.prototype.unrenderFgSegs = function () { 64911 if (this.fgSegs) { 64912 this.fgSegs.forEach(function (seg) { 64913 seg.el.remove(); 64914 }); 64915 } 64916 }; 64917 // Computes a default event time formatting string if `timeFormat` is not explicitly defined 64918 TimeGridEventRenderer.prototype.computeEventTimeFormat = function () { 64919 return this.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM) 64920 }; 64921 // Computes a default `displayEventEnd` value if one is not expliclty defined 64922 TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () { 64923 return true; 64924 }; 64925 // Renders the HTML for a single event segment's default rendering 64926 TimeGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { 64927 var view = this.view; 64928 var calendar = view.calendar; 64929 var componentFootprint = seg.footprint.componentFootprint; 64930 var isAllDay = componentFootprint.isAllDay; 64931 var eventDef = seg.footprint.eventDef; 64932 var isDraggable = view.isEventDefDraggable(eventDef); 64933 var isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef); 64934 var isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef); 64935 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd); 64936 var skinCss = util_1.cssToStr(this.getSkinCss(eventDef)); 64937 var timeText; 64938 var fullTimeText; // more verbose time text. for the print stylesheet 64939 var startTimeText; // just the start time text 64940 classes.unshift('fc-time-grid-event', 'fc-v-event'); 64941 // if the event appears to span more than one day... 64942 if (view.isMultiDayRange(componentFootprint.unzonedRange)) { 64943 // Don't display time text on segments that run entirely through a day. 64944 // That would appear as midnight-midnight and would look dumb. 64945 // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am) 64946 if (seg.isStart || seg.isEnd) { 64947 var zonedStart = calendar.msToMoment(seg.startMs); 64948 var zonedEnd = calendar.msToMoment(seg.endMs); 64949 timeText = this._getTimeText(zonedStart, zonedEnd, isAllDay); 64950 fullTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, 'LT'); 64951 startTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, null, false); // displayEnd=false 64952 } 64953 } 64954 else { 64955 // Display the normal time text for the *event's* times 64956 timeText = this.getTimeText(seg.footprint); 64957 fullTimeText = this.getTimeText(seg.footprint, 'LT'); 64958 startTimeText = this.getTimeText(seg.footprint, null, false); // displayEnd=false 64959 } 64960 return '<a class="' + classes.join(' ') + '"' + 64961 (eventDef.url ? 64962 ' href="' + util_1.htmlEscape(eventDef.url) + '"' : 64963 '') + 64964 (skinCss ? 64965 ' style="' + skinCss + '"' : 64966 '') + 64967 '>' + 64968 '<div class="fc-content">' + 64969 (timeText ? 64970 '<div class="fc-time"' + 64971 ' data-start="' + util_1.htmlEscape(startTimeText) + '"' + 64972 ' data-full="' + util_1.htmlEscape(fullTimeText) + '"' + 64973 '>' + 64974 '<span>' + util_1.htmlEscape(timeText) + '</span>' + 64975 '</div>' : 64976 '') + 64977 (eventDef.title ? 64978 '<div class="fc-title">' + 64979 util_1.htmlEscape(eventDef.title) + 64980 '</div>' : 64981 '') + 64982 '</div>' + 64983 '<div class="fc-bg"/>' + 64984 /* TODO: write CSS for this 64985 (isResizableFromStart ? 64986 '<div class="fc-resizer fc-start-resizer" />' : 64987 '' 64988 ) + 64989 */ 64990 (isResizableFromEnd ? 64991 '<div class="fc-resizer fc-end-resizer" />' : 64992 '') + 64993 '</a>'; 64994 }; 64995 // Given segments that are assumed to all live in the *same column*, 64996 // compute their verical/horizontal coordinates and assign to their elements. 64997 TimeGridEventRenderer.prototype.updateFgSegCoords = function (segs) { 64998 this.timeGrid.computeSegVerticals(segs); // horizontals relies on this 64999 this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array 65000 this.timeGrid.assignSegVerticals(segs); 65001 this.assignFgSegHorizontals(segs); 65002 }; 65003 // Given an array of segments that are all in the same column, set
65003s the backwardCoord and forwardCoord on each. 65004 // NOTE: Also reorders the given array by date! 65005 TimeGridEventRenderer.prototype.computeFgSegHorizontals = function (segs) { 65006 var levels; 65007 var level0; 65008 var i; 65009 this.sortEventSegs(segs); // order by certain criteria 65010 levels = buildSlotSegLevels(segs); 65011 computeForwardSlotSegs(levels); 65012 if ((level0 = levels[0])) { 65013 for (i = 0; i < level0.length; i++) { 65014 computeSlotSegPressures(level0[i]); 65015 } 65016 for (i = 0; i < level0.length; i++) { 65017 this.computeFgSegForwardBack(level0[i], 0, 0); 65018 } 65019 } 65020 }; 65021 // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range 65022 // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and 65023 // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left. 65024 // 65025 // The segment might be part of a "series", which means consecutive segments with the same pressure 65026 // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of 65027 // segments behind this one in the current series, and `seriesBackwardCoord` is the starting 65028 // coordinate of the first segment in the series. 65029 TimeGridEventRenderer.prototype.computeFgSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) { 65030 var forwardSegs = seg.forwardSegs; 65031 var i; 65032 if (seg.forwardCoord === undefined) { 65033 if (!forwardSegs.length) { 65034 // if there are no forward segments, this segment should butt up against the edge 65035 seg.forwardCoord = 1; 65036 } 65037 else { 65038 // sort highest pressure first 65039 this.sortForwardSegs(forwardSegs); 65040 // this segment's forwardCoord will be calculated from the backwardCoord of the 65041 // highest-pressure forward segment. 65042 this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord); 65043 seg.forwardCoord = forwardSegs[0].backwardCoord; 65044 } 65045 // calculate the backwardCoord from the forwardCoord. consider the series 65046 seg.backwardCoord = seg.forwardCoord - 65047 (seg.forwardCoord - seriesBackwardCoord) / // available width for series 65048 (seriesBackwardPressure + 1); // # of segments in the series 65049 // use this segment's coordinates to computed the coordinates of the less-pressurized 65050 // forward segments 65051 for (i = 0; i < forwardSegs.length; i++) { 65052 this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord); 65053 } 65054 } 65055 }; 65056 TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) { 65057 forwardSegs.sort(util_1.proxy(this, 'compareForwardSegs')); 65058 }; 65059 // A cmp function for determining which forward segment to rely on more when computing coordinates. 65060 TimeGridEventRenderer.prototype.compareForwardSegs = function (seg1, seg2) { 65061 // put higher-pressure first 65062 return seg2.forwardPressure - seg1.forwardPressure || 65063 // put segments that are closer to initial edge first (and favor ones with no coords yet) 65064 (seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) || 65065 // do normal sorting... 65066 this.compareEventSegs(seg1, seg2); 65067 }; 65068 // Given foreground event segments that have already had their position coordinates computed, 65069 // assigns position-related CSS values to their elements. 65070 TimeGridEventRenderer.prototype.assignFgSegHorizontals = function (segs) { 65071 var i; 65072 var seg; 65073 for (i = 0; i < segs.length; i++) { 65074 seg = segs[i]; 65075 seg.el.css(this.generateFgSegHorizontalCss(seg)); 65076 // if the height is short, add a className for alternate styling 65077 if (seg.bottom - seg.top < 30) { 65078 seg.el.addClass('fc-short'); 65079 } 65080 } 65081 }; 65082 // Generates an object with CSS properties/values that should be applied to an event segment element. 65083 // Contains important positioning-related properties that should be applied to any event element, customized or not. 65084 TimeGridEventRenderer.prototype.generateFgSegHorizontalCss = function (seg) { 65085 var shouldOverlap = this.opt('slotEventOverlap'); 65086 var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point 65087 var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point 65088 var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first 65089 var isRTL = this.timeGrid.isRTL; 65090 var left; // amount of space from left edge, a fraction of the total width 65091 var right; // amount of space from right edge, a fraction of the total width 65092 if (shouldOverlap) { 65093 // double the width, but don't go beyond the maximum forward coordinate (1.0) 65094 forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2); 65095 } 65096 if (isRTL) { 65097 left = 1 - forwardCoord; 65098 right = backwardCoord; 65099 } 65100 else { 65101 left = backwardCoord; 65102 right = 1 - forwardCoord; 65103 } 65104 props.zIndex = seg.level + 1; // convert from 0-base to 1-based 65105 props.left = left * 100 + '%'; 65106 props.right = right * 100 + '%'; 65107 if (shouldOverlap && seg.forwardPressure) { 65108 // add padding to the edge so that forward stacked events don't cover the resizer's icon 65109 props[isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width 65110 } 65111 return props; 65112 }; 65113 return TimeGridEventRenderer; 65114}(EventRenderer_1.default)); 65115exports.default = TimeGridEventRenderer; 65116// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is 65117// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date. 65118function buildSlotSegLevels(segs) { 65119 var levels = []; 65120 var i; 65121 var seg; 65122 var j; 65123 for (i = 0; i < segs.length; i++) { 65124 seg = segs[i]; 65125 // go through all the levels and stop on the first level where there are no collisions 65126 for (j = 0; j < levels.length; j++) { 65127 if (!computeSlotSegCollisions(seg, levels[j]).length) { 65128 break; 65129 } 65130 } 65131 seg.level = j; 65132 (levels[j] || (levels[j] = [])).push(seg); 65133 } 65134 return levels; 65135} 65136// For every segment, figure out the other segments that are in subsequent 65137// levels that also occupy the same vertical space. Accumulate in seg.forwardSegs 65138function computeForwardSlotSegs(levels) { 65139 var i; 65140 var level; 65141 var j; 65142 var seg; 65143 var k; 65144 for (i = 0; i < levels.length; i++) { 65145 level = levels[i]; 65146 for (j = 0; j < level.length; j++) { 65147 seg = level[j]; 65148 seg.forwardSegs = []; 65149 for (k = i + 1; k < levels.length; k++) { 65150 computeSlotSegCollisions(seg, levels[k], seg.forwardSegs); 65151 } 65152 } 65153 } 65154} 65155// Figure out which path forward (via seg.forwardSegs) results in the longest path until
65156// the furthest edge is reached. The number of segments in this path will be seg.forwardPressure 65157function computeSlotSegPressures(seg) { 65158 var forwardSegs = seg.forwardSegs; 65159 var forwardPressure = 0; 65160 var i; 65161 var forwardSeg; 65162 if (seg.forwardPressure === undefined) { 65163 for (i = 0; i < forwardSegs.length; i++) { 65164 forwardSeg = forwardSegs[i]; 65165 // figure out the child's maximum forward path 65166 computeSlotSegPressures(forwardSeg); 65167 // either use the existing maximum, or use the child's forward pressure 65168 // plus one (for the forwardSeg itself) 65169 forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure); 65170 } 65171 seg.forwardPressure = forwardPressure; 65172 } 65173} 65174// Find all the segments in `otherSegs` that vertically collide with `seg`. 65175// Append into an optionally-supplied `results` array and return. 65176function computeSlotSegCollisions(seg, otherSegs, results) { 65177 if (results === void 0) { results = []; } 65178 for (var i = 0; i < otherSegs.length; i++) { 65179 if (isSlotSegCollision(seg, otherSegs[i])) { 65180 results.push(otherSegs[i]); 65181 } 65182 } 65183 return results; 65184} 65185// Do these segments occupy the same vertical space? 65186function isSlotSegCollision(seg1, seg2) { 65187 return seg1.bottom > seg2.top && seg1.top < seg2.bottom; 65188} 65189 65190 65191/***/ }), 65192/* 247 */ 65193/***/ (function(module, exports, __webpack_require__) { 65194 65195Object.defineProperty(exports, "__esModule", { value: true }); 65196var tslib_1 = __webpack_require__(2); 65197var $ = __webpack_require__(3); 65198var HelperRenderer_1 = __webpack_require__(58); 65199var TimeGridHelperRenderer = /** @class */ (function (_super) { 65200 tslib_1.__extends(TimeGridHelperRenderer, _super); 65201 function TimeGridHelperRenderer() { 65202 return _super !== null && _super.apply(this, arguments) || this; 65203 } 65204 TimeGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { 65205 var helperNodes = []; 65206 var i; 65207 var seg; 65208 var sourceEl; 65209 // TODO: not good to call eventRenderer this way 65210 this.eventRenderer.renderFgSegsIntoContainers(segs, this.component.helperContainerEls); 65211 // Try to make the segment that is in the same row as sourceSeg look the same 65212 for (i = 0; i < segs.length; i++) { 65213 seg = segs[i]; 65214 if (sourceSeg && sourceSeg.col === seg.col) { 65215 sourceEl = sourceSeg.el; 65216 seg.el.css({ 65217 left: sourceEl.css('left'), 65218 right: sourceEl.css('right'), 65219 'margin-left': sourceEl.css('margin-left'), 65220 'margin-right': sourceEl.css('margin-right') 65221 }); 65222 } 65223 helperNodes.push(seg.el[0]); 65224 } 65225 return $(helperNodes); // must return the elements rendered 65226 }; 65227 return TimeGridHelperRenderer; 65228}(HelperRenderer_1.default)); 65229exports.default = TimeGridHelperRenderer; 65230 65231 65232/***/ }), 65233/* 248 */ 65234/***/ (function(module, exports, __webpack_require__) { 65235 65236Object.defineProperty(exports, "__esModule", { value: true }); 65237var tslib_1 = __webpack_require__(2); 65238var FillRenderer_1 = __webpack_require__(57); 65239var TimeGridFillRenderer = /** @class */ (function (_super) { 65240 tslib_1.__extends(TimeGridFillRenderer, _super); 65241 function TimeGridFillRenderer() { 65242 return _super !== null && _super.apply(this, arguments) || this; 65243 } 65244 TimeGridFillRenderer.prototype.attachSegEls = function (type, segs) { 65245 var timeGrid = this.component; 65246 var containerEls; 65247 // TODO: more efficient lookup 65248 if (type === 'bgEvent') { 65249 containerEls = timeGrid.bgContainerEls; 65250 } 65251 else if (type === 'businessHours') { 65252 containerEls = timeGrid.businessContainerEls; 65253 } 65254 else if (type === 'highlight') { 65255 containerEls = timeGrid.highlightContainerEls; 65256 } 65257 timeGrid.updateSegVerticals(segs); 65258 timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls); 65259 return segs.map(function (seg) { 65260 return seg.el[0]; 65261 }); 65262 }; 65263 return TimeGridFillRenderer; 65264}(FillRenderer_1.default)); 65265exports.default = TimeGridFillRenderer; 65266 65267 65268/***/ }), 65269/* 249 */ 65270/***/ (function(module, exports, __webpack_require__) { 65271 65272/* A rectangular panel that is absolutely positioned over other content 65273------------------------------------------------------------------------------------------------------------------------ 65274Options: 65275 - className (string) 65276 - content (HTML string or jQuery element set) 65277 - parentEl 65278 - top 65279 - left 65280 - right (the x coord of where the right edge should be. not a "CSS" right) 65281 - autoHide (boolean) 65282 - show (callback) 65283 - hide (callback) 65284*/ 65285Object.defineProperty(exports, "__esModule", { value: true });
65286var $ = __webpack_require__(3); 65287var util_1 = __webpack_require__(4); 65288var ListenerMixin_1 = __webpack_require__(7); 65289var Popover = /** @class */ (function () { 65290 function Popover(options) { 65291 this.isHidden = true; 65292 this.margin = 10; // the space required between the popover and the edges of the scroll container 65293 this.options = options || {}; 65294 } 65295 // Shows the popover on the specified position. Renders it if not already 65296 Popover.prototype.show = function () { 65297 if (this.isHidden) { 65298 if (!this.el) { 65299 this.render(); 65300 } 65301 this.el.show(); 65302 this.position(); 65303 this.isHidden = false; 65304 this.trigger('show'); 65305 } 65306 }; 65307 // Hides the popover, through CSS, but does not remove it from the DOM 65308 Popover.prototype.hide = function () { 65309 if (!this.isHidden) { 65310 this.el.hide(); 65311 this.isHidden = true; 65312 this.trigger('hide'); 65313 } 65314 }; 65315 // Creates `this.el` and renders content inside of it 65316 Popover.prototype.render = function () { 65317 var _this = this; 65318 var options = this.options; 65319 this.el = $('<div class="fc-popover"/>') 65320 .addClass(options.className || '') 65321 .css({ 65322 // position initially to the top left to avoid creating scrollbars 65323 top: 0, 65324 left: 0 65325 }) 65326 .append(options.content) 65327 .appendTo(options.parentEl); 65328 // when a click happens on anything inside with a 'fc-close' className, hide the popover 65329 this.el.on('click', '.fc-close', function () { 65330 _this.hide(); 65331 }); 65332 if (options.autoHide) { 65333 this.listenTo($(document), 'mousedown', this.documentMousedown); 65334 } 65335 }; 65336 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature 65337 Popover.prototype.documentMousedown = function (ev) { 65338 // only hide the popover if the click happened outside the popover 65339 if (this.el && !$(ev.target).closest(this.el).length) { 65340 this.hide(); 65341 } 65342 }; 65343 // Hides and unregisters any handlers 65344 Popover.prototype.removeElement = function () { 65345 this.hide(); 65346 if (this.el) { 65347 this.el.remove(); 65348 this.el = null; 65349 } 65350 this.stopListeningTo($(document), 'mousedown'); 65351 }; 65352 // Positions the popover optimally, using the top/left/right options 65353 Popover.prototype.position = function () { 65354 var options = this.options; 65355 var origin = this.el.offsetParent().offset(); 65356 var width = this.el.outerWidth(); 65357 var height = this.el.outerHeight(); 65358 var windowEl = $(window); 65359 var viewportEl = util_1.getScrollParent(this.el); 65360 var viewportTop; 65361 var viewportLeft; 65362 var viewportOffset; 65363 var top; // the "position" (not "offset") values for the popover 65364 var left; // 65365 // compute top and left 65366 top = options.top || 0; 65367 if (options.left !== undefined) { 65368 left = options.left; 65369 } 65370 else if (options.right !== undefined) { 65371 left = options.right - width; // derive the left value from the right value 65372 } 65373 else { 65374 left = 0; 65375 } 65376 if (viewportEl.is(window) || viewportEl.is(document)) { 65377 viewportEl = windowEl; 65378 viewportTop = 0; // the window is always at the top left 65379 viewportLeft = 0; // (and .offset() won't work if called here) 65380 } 65381 else { 65382 viewportOffset = viewportEl.offset(); 65383 viewportTop = viewportOffset.top; 65384 viewportLeft = viewportOffset.left; 65385 } 65386 // if the window is scrolled, it causes the visible area to be further down 65387 viewportTop += windowEl.scrollTop(); 65388 viewportLeft += windowEl.scrollLeft(); 65389 // constrain to the view port. if constrained by two edges, give precedence to top/left 65390 if (options.viewportConstrain !== false) { 65391 top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin); 65392 top = Math.max(top, viewportTop + this.margin); 65393 left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin); 65394 left = Math.max(left, viewportLeft + this.margin); 65395 } 65396 this.el.css({ 65397 top: top - origin.top, 65398 left: left - origin.left 65399 }); 65400 }; 65401 // Triggers a callback. Calls a function in the option hash of the same name. 65402 // Arguments beyond the first `name` are forwarded on. 65403 // TODO: better code reuse for this. Repeat code 65404 Popover.prototype.trigger = function (name) { 65405 if (this.options[name]) { 65406 this.options[name].apply(this, Array.prototype.slice.call(arguments, 1)); 65407 } 65408 }; 65409 return Popover; 65410}()); 65411exports.default = Popover; 65412ListenerMixin_1.default.mixInto(Popover); 65413 65414 65415/***/ }), 65416/* 250 */ 65417/***/ (function(module, exports, __webpack_require__) { 65418 65419Object.defineProperty(exports, "__esModule", { value: true });
65420var tslib_1 = __webpack_require__(2); 65421var $ = __webpack_require__(3); 65422var util_1 = __webpack_require__(4); 65423var EventRenderer_1 = __webpack_require__(42); 65424/* Event-rendering methods for the DayGrid class 65425----------------------------------------------------------------------------------------------------------------------*/ 65426var DayGridEventRenderer = /** @class */ (function (_super) { 65427 tslib_1.__extends(DayGridEventRenderer, _super); 65428 function DayGridEventRenderer(dayGrid, fillRenderer) { 65429 var _this = _super.call(this, dayGrid, fillRenderer) || this; 65430 _this.dayGrid = dayGrid; 65431 return _this; 65432 } 65433 DayGridEventRenderer.prototype.renderBgRanges = function (eventRanges) { 65434 // don't render timed background events 65435 eventRanges = $.grep(eventRanges, function (eventRange) { 65436 return eventRange.eventDef.isAllDay(); 65437 }); 65438 _super.prototype.renderBgRanges.call(this, eventRanges); 65439 }; 65440 // Renders the given foreground event segments onto the grid 65441 DayGridEventRenderer.prototype.renderFgSegs = function (segs) { 65442 var rowStructs = this.rowStructs = this.renderSegRows(segs); 65443 // append to each row's content skeleton 65444 this.dayGrid.rowEls.each(function (i, rowNode) { 65445 $(rowNode).find('.fc-content-skeleton > table').append(rowStructs[i].tbodyEl); 65446 }); 65447 }; 65448 // Unrenders all currently rendered foreground event segments 65449 DayGridEventRenderer.prototype.unrenderFgSegs = function () { 65450 var rowStructs = this.rowStructs || []; 65451 var rowStruct; 65452 while ((rowStruct = rowStructs.pop())) { 65453 rowStruct.tbodyEl.remove(); 65454 } 65455 this.rowStructs = null; 65456 }; 65457 // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton. 65458 // Returns an array of rowStruct objects (see the bottom of `renderSegRow`). 65459 // PRECONDITION: each segment shoud already have a rendered and assigned `.el` 65460 DayGridEventRenderer.prototype.renderSegRows = function (segs) { 65461 var rowStructs = []; 65462 var segRows; 65463 var row; 65464 segRows = this.groupSegRows(segs); // group into nested arrays 65465 // iterate each row of segment groupings 65466 for (row = 0; row < segRows.length; row++) { 65467 rowStructs.push(this.renderSegRow(row, segRows[row])); 65468 } 65469 return rowStructs; 65470 }; 65471 // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains 65472 // the segments. Returns object with a bunch of internal data about how the render was calculated. 65473 // NOTE: modifies rowSegs 65474 DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) { 65475 var colCnt = this.dayGrid.colCnt; 65476 var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels 65477 var levelCnt = Math.max(1, segLevels.length); // ensure at least one level 65478 var tbody = $('<tbody/>'); 65479 var segMatrix = []; // lookup for which segments are rendered into which level+col cells 65480 var cellMatrix = []; // lookup for all <td> elements of the level+col matrix 65481 var loneCellMatrix = []; // lookup for <td> elements that only take up a single column 65482 var i; 65483 var levelSegs; 65484 var col; 65485 var tr; 65486 var j; 65487 var seg; 65488 var td; 65489 // populates empty cells from the current column (`col`) to `endCol` 65490 function emptyCellsUntil(endCol) { 65491 while (col < endCol) { 65492 // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell 65493 td = (loneCellMatrix[i - 1] || [])[col]; 65494 if (td) { 65495 td.attr('rowspan', parseInt(td.attr('rowspan') || 1, 10) + 1); 65496 } 65497 else { 65498 td = $('<td/>'); 65499 tr.append(td); 65500 } 65501 cellMatrix[i][col] = td; 65502 loneCellMatrix[i][col] = td; 65503 col++; 65504 } 65505 } 65506 for (i = 0; i < levelCnt; i++) { 65507 levelSegs = segLevels[i]; 65508 col = 0; 65509 tr = $('<tr/>'); 65510 segMatrix.push([]); 65511 cellMatrix.push([]); 65512 loneCellMatrix.push([]); 65513 // levelCnt might be 1 even though there are no actual levels. protect against this. 65514 // this single empty row is useful for styling. 65515 if (levelSegs) { 65516 for (j = 0; j < levelSegs.length; j++) { 65517 seg = levelSegs[j]; 65518 emptyCellsUntil(seg.leftCol); 65519 // create a container that occupies or more columns. append the event element. 65520 td = $('<td class="fc-event-container"/>').append(seg.el); 65521 if (seg.leftCol !== seg.rightCol) { 65522 td.attr('colspan', seg.rightCol - seg.leftCol + 1); 65523 } 65524 else { 65525 loneCellMatrix[i][col] = td; 65526 } 65527 while (col <= seg.rightCol) { 65528 cellMatrix[i][col] = td; 65529 segMatrix[i][col] = seg; 65530 col++; 65531 } 65532 tr.append(td); 65533 } 65534 } 65535 emptyCellsUntil(colCnt); // finish off the row 65536 this.dayGrid.bookendCells(tr); 65537 tbody.append(tr); 65538 } 65539 return { 65540 row: row, 65541 tbodyEl: tbody, 65542 cellMatrix: cellMatrix, 65543 segMatrix: segMatrix, 65544 segLevels: segLevels, 65545 segs: rowSegs 65546 }; 65547 }; 65548 // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels. 65549 // NOTE: modifies segs 65550 DayGridEventRenderer.prototype.buildSegLevels = function (segs) { 65551 var levels = []; 65552 var i; 65553 var seg; 65554 var j; 65555 // Give preference to elements with certain criteria, so they have 65556 // a chance to be closer to the top. 65557 this.sortEventSegs(segs); 65558 for (i = 0; i < segs.length; i++) { 65559 seg = segs[i]; 65560 // loop through levels, starting with the topmost, until the segment doesn't collide with other segments 65561 for (j = 0; j < levels.length; j++) {
65562 if (!isDaySegCollision(seg, levels[j])) { 65563 break; 65564 } 65565 } 65566 // `j` now holds the desired subrow index 65567 seg.level = j; 65568 // create new level array if needed and append segment 65569 (levels[j] || (levels[j] = [])).push(seg); 65570 } 65571 // order segments left-to-right. very important if calendar is RTL 65572 for (j = 0; j < levels.length; j++) { 65573 levels[j].sort(compareDaySegCols); 65574 } 65575 return levels; 65576 }; 65577 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row 65578 DayGridEventRenderer.prototype.groupSegRows = function (segs) { 65579 var segRows = []; 65580 var i; 65581 for (i = 0; i < this.dayGrid.rowCnt; i++) { 65582 segRows.push([]); 65583 } 65584 for (i = 0; i < segs.length; i++) { 65585 segRows[segs[i].row].push(segs[i]); 65586 } 65587 return segRows; 65588 }; 65589 // Computes a default event time formatting string if `timeFormat` is not explicitly defined 65590 DayGridEventRenderer.prototype.computeEventTimeFormat = function () { 65591 return this.opt('extraSmallTimeFormat'); // like "6p" or "6:30p" 65592 }; 65593 // Computes a default `displayEventEnd` value if one is not expliclty defined 65594 DayGridEventRenderer.prototype.computeDisplayEventEnd = function () { 65595 return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day 65596 }; 65597 // Builds the HTML to be used for the default element for an individual segment 65598 DayGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { 65599 var view = this.view; 65600 var eventDef = seg.footprint.eventDef; 65601 var isAllDay = seg.footprint.componentFootprint.isAllDay; 65602 var isDraggable = view.isEventDefDraggable(eventDef); 65603 var isResizableFromStart = !disableResizing && isAllDay && 65604 seg.isStart && view.isEventDefResizableFromStart(eventDef); 65605 var isResizableFromEnd = !disableResizing && isAllDay && 65606 seg.isEnd && view.isEventDefResizableFromEnd(eventDef); 65607 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd); 65608 var skinCss = util_1.cssToStr(this.getSkinCss(eventDef)); 65609 var timeHtml = ''; 65610 var timeText; 65611 var titleHtml; 65612 classes.unshift('fc-day-grid-event', 'fc-h-event');
65613 // Only display a timed events time if it is the starting segment 65614 if (seg.isStart) { 65615 timeText = this.getTimeText(seg.footprint); 65616 if (timeText) { 65617 timeHtml = '<span class="fc-time">' + util_1.htmlEscape(timeText) + '</span>'; 65618 } 65619 } 65620 titleHtml = 65621 '<span class="fc-title">' + 65622 (util_1.htmlEscape(eventDef.title || '') || ' ') + // we always want one line of height 65623 '</span>'; 65624 return '<a class="' + classes.join(' ') + '"' + 65625 (eventDef.url ? 65626 ' href="' + util_1.htmlEscape(eventDef.url) + '"' : 65627 '') + 65628 (skinCss ? 65629 ' style="' + skinCss + '"' : 65630 '') + 65631 '>' + 65632 '<div class="fc-content">' + 65633 (this.dayGrid.isRTL ? 65634 titleHtml + ' ' + timeHtml : // put a natural space in between 65635 timeHtml + ' ' + titleHtml // 65636 ) + 65637 '</div>' + 65638 (isResizableFromStart ? 65639 '<div class="fc-resizer fc-start-resizer" />' : 65640 '') + 65641 (isResizableFromEnd ? 65642 '<div class="fc-resizer fc-end-resizer" />' : 65643 '') + 65644 '</a>'; 65645 }; 65646 return DayGridEventRenderer; 65647}(EventRenderer_1.default)); 65648exports.default = DayGridEventRenderer; 65649// Computes whether two segments' columns collide. They are assumed to be in the same row. 65650function isDaySegCollision(seg, otherSegs) { 65651 var i; 65652 var otherSeg; 65653 for (i = 0; i < otherSegs.length; i++) { 65654 otherSeg = otherSegs[i]; 65655 if (otherSeg.leftCol <= seg.rightCol && 65656 otherSeg.rightCol >= seg.leftCol) { 65657 return true; 65658 } 65659 } 65660 return false; 65661} 65662// A cmp function for determining the leftmost event 65663function compareDaySegCols(a, b) { 65664 return a.leftCol - b.leftCol; 65665} 65666 65667 65668/***/ }), 65669/* 251 */ 65670/***/ (function(module, exports, __webpack_require__) { 65671 65672Object.defineProperty(exports, "__esModule", { value: true }); 65673var tslib_1 = __webpack_require__(2); 65674var $ = __webpack_require__(3); 65675var HelperRenderer_1 = __webpack_require__(58); 65676var DayGridHelperRenderer = /** @class */ (function (_super) { 65677 tslib_1.__extends(DayGridHelperRenderer, _super); 65678 function DayGridHelperRenderer() { 65679 return _super !== null && _super.apply(this, arguments) || this; 65680 } 65681 // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null. 65682 DayGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { 65683 var helperNodes = []; 65684 var rowStructs; 65685 // TODO: not good to call eventRenderer this way 65686 rowStructs = this.eventRenderer.renderSegRows(segs); 65687 // inject each new event skeleton into each associated row 65688 this.component.rowEls.each(function (row, rowNode) { 65689 var rowEl = $(rowNode); // the .fc-row 65690 var skeletonEl = $('<div class="fc-helper-skeleton"><table/></div>'); // will be absolutely positioned 65691 var skeletonTopEl; 65692 var skeletonTop; 65693 // If there is an original segment, match the top position. Otherwise, put it at the row's top level 65694 if (sourceSeg && sourceSeg.row === row) { 65695 skeletonTop = sourceSeg.el.position().top; 65696 } 65697 else { 65698 skeletonTopEl = rowEl.find('.fc-content-skeleton tbody'); 65699 if (!skeletonTopEl.length) { 65700 skeletonTopEl = rowEl.find('.fc-content-skeleton table'); 65701 } 65702 skeletonTop = skeletonTopEl.position().top; 65703 } 65704 skeletonEl.css('top', skeletonTop) 65705 .find('table') 65706 .append(rowStructs[row].tbodyEl); 65707 rowEl.append(skeletonEl); 65708 helperNodes.push(skeletonEl[0]); 65709 }); 65710 return $(helperNodes); // must return the elements rendered 65711 }; 65712 return DayGridHelperRenderer; 65713}(HelperRenderer_1.default)); 65714exports.default = DayGridHelperRenderer; 65715 65716 65717/***/ }), 65718/* 252 */ 65719/***/ (function(module, exports, __webpack_require__) { 65720 65721Object.defineProperty(exports, "__esModule", { value: true });
65722var tslib_1 = __webpack_require__(2); 65723var $ = __webpack_require__(3); 65724var FillRenderer_1 = __webpack_require__(57); 65725var DayGridFillRenderer = /** @class */ (function (_super) { 65726 tslib_1.__extends(DayGridFillRenderer, _super); 65727 function DayGridFillRenderer() { 65728 var _this = _super !== null && _super.apply(this, arguments) || this; 65729 _this.fillSegTag = 'td'; // override the default tag name 65730 return _this; 65731 } 65732 DayGridFillRenderer.prototype.attachSegEls = function (type, segs) { 65733 var nodes = []; 65734 var i; 65735 var seg; 65736 var skeletonEl; 65737 for (i = 0; i < segs.length; i++) { 65738 seg = segs[i]; 65739 skeletonEl = this.renderFillRow(type, seg); 65740 this.component.rowEls.eq(seg.row).append(skeletonEl); 65741 nodes.push(skeletonEl[0]); 65742 } 65743 return nodes; 65744 }; 65745 // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered. 65746 DayGridFillRenderer.prototype.renderFillRow = function (type, seg) { 65747 var colCnt = this.component.colCnt; 65748 var startCol = seg.leftCol; 65749 var endCol = seg.rightCol + 1; 65750 var className; 65751 var skeletonEl; 65752 var trEl; 65753 if (type === 'businessHours') { 65754 className = 'bgevent'; 65755 } 65756 else { 65757 className = type.toLowerCase(); 65758 } 65759 skeletonEl = $('<div class="fc-' + className + '-skeleton">' + 65760 '<table><tr/></table>' + 65761 '</div>'); 65762 trEl = skeletonEl.find('tr'); 65763 if (startCol > 0) { 65764 trEl.append('<td colspan="' + startCol + '"/>'); 65765 } 65766 trEl.append(seg.el.attr('colspan', endCol - startCol)); 65767 if (endCol < colCnt) { 65768 trEl.append('<td colspan="' + (colCnt - endCol) + '"/>'); 65769 } 65770 this.component.bookendCells(trEl); 65771 return skeletonEl; 65772 }; 65773 return DayGridFillRenderer; 65774}(FillRenderer_1.default)); 65775exports.default = DayGridFillRenderer; 65776 65777 65778/***/ }), 65779/* 253 */ 65780/***/ (function(module, exports, __webpack_require__) { 65781 65782Object.defineProperty(exports, "__esModule", { value: true }); 65783var tslib_1 = __webpack_require__(2); 65784var BasicViewDateProfileGenerator_1 = __webpack_require__(228); 65785var UnzonedRange_1 = __webpack_require__(5); 65786var MonthViewDateProfileGenerator = /** @class */ (function (_super) { 65787 tslib_1.__extends(MonthViewDateProfileGenerator, _super); 65788 function MonthViewDateProfileGenerator() { 65789 return _super !== null && _super.apply(this, arguments) || this; 65790 } 65791 // Computes the date range that will be rendered. 65792 MonthViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { 65793 var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); 65794 var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay); 65795 var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay); 65796 var rowCnt; 65797 // ensure 6 weeks 65798 if (this.opt('fixedWeekCount')) { 65799 rowCnt = Math.ceil(// could be partial weeks due to hiddenDays 65800 end.diff(start, 'weeks', true) // dontRound=true 65801 ); 65802 end.add(6 - rowCnt, 'weeks'); 65803 } 65804 return new UnzonedRange_1.default(start, end); 65805 }; 65806 return MonthViewDateProfileGenerator; 65807}(BasicViewDateProfileGenerator_1.default)); 65808exports.default = MonthViewDateProfileGenerator; 65809 65810 65811/***/ }), 65812/* 254 */ 65813/***/ (function(module, exports, __webpack_require__) { 65814 65815Object.defineProperty(exports, "__esModule", { value: true }); 65816var tslib_1 = __webpack_require__(2); 65817var util_1 = __webpack_require__(4); 65818var EventRenderer_1 = __webpack_require__(42); 65819var ListEventRenderer = /** @class */ (function (_super) { 65820 tslib_1.__extends(ListEventRenderer, _super); 65821 function ListEventRenderer() { 65822 return _super !== null && _super.apply(this, arguments) || this; 65823 } 65824 ListEventRenderer.prototype.renderFgSegs = function (segs) { 65825 if (!segs.length) { 65826 this.component.renderEmptyMessage(); 65827 } 65828 else {
65829 this.component.renderSegList(segs); 65830 } 65831 }; 65832 // generates the HTML for a single event row 65833 ListEventRenderer.prototype.fgSegHtml = function (seg) { 65834 var view = this.view; 65835 var calendar = view.calendar; 65836 var theme = calendar.theme; 65837 var eventFootprint = seg.footprint; 65838 var eventDef = eventFootprint.eventDef; 65839 var componentFootprint = eventFootprint.componentFootprint; 65840 var url = eventDef.url; 65841 var classes = ['fc-list-item'].concat(this.getClasses(eventDef)); 65842 var bgColor = this.getBgColor(eventDef); 65843 var timeHtml; 65844 if (componentFootprint.isAllDay) { 65845 timeHtml = view.getAllDayHtml(); 65846 } 65847 else if (view.isMultiDayRange(componentFootprint.unzonedRange)) { 65848 if (seg.isStart || seg.isEnd) { 65849 timeHtml = util_1.htmlEscape(this._getTimeText(calendar.msToMoment(seg.startMs), calendar.msToMoment(seg.endMs), componentFootprint.isAllDay)); 65850 } 65851 else { 65852 timeHtml = view.getAllDayHtml(); 65853 } 65854 } 65855 else { 65856 // Display the normal time text for the *event's* times 65857 timeHtml = util_1.htmlEscape(this.getTimeText(eventFootprint)); 65858 } 65859 if (url) { 65860 classes.push('fc-has-url'); 65861 } 65862 return '<tr class="' + classes.join(' ') + '">' + 65863 (this.displayEventTime ? 65864 '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' + 65865 (timeHtml || '') + 65866 '</td>' : 65867 '') + 65868 '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' + 65869 '<span class="fc-event-dot"' + 65870 (bgColor ? 65871 ' style="background-color:' + bgColor + '"' : 65872 '') + 65873 '></span>' + 65874 '</td>' + 65875 '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' + 65876 '<a' + (url ? ' href="' + util_1.htmlEscape(url) + '"' : '') + '>' + 65877 util_1.htmlEscape(eventDef.title || '') + 65878 '</a>' + 65879 '</td>' + 65880 '</tr>'; 65881 }; 65882 // like "4:00am" 65883 ListEventRenderer.prototype.computeEventTimeFormat = function () { 65884 return this.opt('mediumTimeFormat'); 65885 }; 65886 return ListEventRenderer; 65887}(EventRenderer_1.default)); 65888exports.default = ListEventRenderer; 65889 65890 65891/***/ }), 65892/* 255 */ 65893/***/ (function(module, exports, __webpack_require__) { 65894 65895Object.defineProperty(exports, "__esModule", { value: true }); 65896var tslib_1 = __webpack_require__(2); 65897var $ = __webpack_require__(3); 65898var EventPointing_1 = __webpack_require__(59); 65899var ListEventPointing = /** @class */ (function (_super) { 65900 tslib_1.__extends(ListEventPointing, _super); 65901 function ListEventPointing() { 65902 return _super !== null && _super.apply(this, arguments) || this; 65903 } 65904 // for events with a url, the whole <tr> should be clickable, 65905 // but it's impossible to wrap with an <a> tag. simulate this. 65906 ListEventPointing.prototype.handleClick = function (seg, ev) { 65907 var url; 65908 _super.prototype.handleClick.call(this, seg, ev); // might prevent the default action 65909 // not clicking on or within an <a> with an href 65910 if (!$(ev.target).closest('a[href]').length) { 65911 url = seg.footprint.eventDef.url; 65912 if (url && !ev.isDefaultPrevented()) { 65913 window.location.href = url; // simulate link click 65914 } 65915 } 65916 }; 65917 return ListEventPointing; 65918}(EventPointing_1.default)); 65919exports.default = ListEventPointing; 65920 65921 65922/***/ }), 65923/* 256 */ 65924/***/ (function(module, exports, __webpack_require__) { 65925 65926Object.defineProperty(exports, "__esModule", { value: true }); 65927var EventSourceParser_1 = __webpack_require__(38); 65928var ArrayEventSource_1 = __webpack_require__(52); 65929var FuncEventSource_1 = __webpack_require__(215); 65930var JsonFeedEventSource_1 = __webpack_require__(216); 65931EventSourceParser_1.default.registerClass(ArrayEventSource_1.default); 65932EventSourceParser_1.default.registerClass(FuncEventSource_1.default); 65933EventSourceParser_1.default.registerClass(JsonFeedEventSource_1.default); 65934 65935 65936/***/ }), 65937/* 257 */ 65938/***/ (function(module, exports, __webpack_require__) { 65939 65940Object.defineProperty(exports, "__esModule", { value: true });
65941var ThemeRegistry_1 = __webpack_require__(51); 65942var StandardTheme_1 = __webpack_require__(213); 65943var JqueryUiTheme_1 = __webpack_require__(214); 65944var Bootstrap3Theme_1 = __webpack_require__(258); 65945var Bootstrap4Theme_1 = __webpack_require__(259); 65946ThemeRegistry_1.defineThemeSystem('standard', StandardTheme_1.default); 65947ThemeRegistry_1.defineThemeSystem('jquery-ui', JqueryUiTheme_1.default); 65948ThemeRegistry_1.defineThemeSystem('bootstrap3', Bootstrap3Theme_1.default); 65949ThemeRegistry_1.defineThemeSystem('bootstrap4', Bootstrap4Theme_1.default); 65950 65951 65952/***/ }), 65953/* 258 */ 65954/***/ (function(module, exports, __webpack_require__) { 65955 65956Object.defineProperty(exports, "__esModule", { value: true }); 65957var tslib_1 = __webpack_require__(2); 65958var Theme_1 = __webpack_require__(19); 65959var Bootstrap3Theme = /** @class */ (function (_super) { 65960 tslib_1.__extends(Bootstrap3Theme, _super); 65961 function Bootstrap3Theme() { 65962 return _super !== null && _super.apply(this, arguments) || this; 65963 } 65964 return Bootstrap3Theme; 65965}(Theme_1.default)); 65966exports.default = Bootstrap3Theme; 65967Bootstrap3Theme.prototype.classes = { 65968 widget: 'fc-bootstrap3', 65969 tableGrid: 'table-bordered', 65970 tableList: 'table', 65971 tableListHeading: 'active', 65972 buttonGroup: 'btn-group', 65973 button: 'btn btn-default', 65974 stateActive: 'active', 65975 stateDisabled: 'disabled', 65976 today: 'alert alert-info', 65977 popover: 'panel panel-default', 65978 popoverHeader: 'panel-heading', 65979 popoverContent: 'panel-body', 65980 // day grid 65981 // for left/right border color when border is inset from edges (all-day in agenda view) 65982 // avoid `panel` class b/c don't want margins/radius. only border color. 65983 headerRow: 'panel-default', 65984 dayRow: 'panel-default', 65985 // list view 65986 listView: 'panel panel-default' 65987}; 65988Bootstrap3Theme.prototype.baseIconClass = 'glyphicon'; 65989Bootstrap3Theme.prototype.iconClasses = { 65990 close: 'glyphicon-remove', 65991 prev: 'glyphicon-chevron-left', 65992 next: 'glyphicon-chevron-right', 65993 prevYear: 'glyphicon-backward', 65994 nextYear: 'glyphicon-forward' 65995}; 65996Bootstrap3Theme.prototype.iconOverrideOption = 'bootstrapGlyphicons'; 65997Bootstrap3Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapGlyphicon'; 65998Bootstrap3Theme.prototype.iconOverridePrefix = 'glyphicon-'; 65999 66000 66001/***/ }), 66002/* 259 */ 66003/***/ (function(module, exports, __webpack_require__) { 66004 66005Object.defineProperty(exports, "__esModule", { value: true }); 66006var tslib_1 = __webpack_require__(2); 66007var Theme_1 = __webpack_require__(19); 66008var Bootstrap4Theme = /** @class */ (function (_super) { 66009 tslib_1.__extends(Bootstrap4Theme, _super); 66010 function Bootstrap4Theme() { 66011 return _super !== null && _super.apply(this, arguments) || this; 66012 } 66013 return Bootstrap4Theme; 66014}(Theme_1.default)); 66015exports.default = Bootstrap4Theme; 66016Bootstrap4Theme.prototype.classes = { 66017 widget: 'fc-bootstrap4',
66018 tableGrid: 'table-bordered', 66019 tableList: 'table', 66020 tableListHeading: 'table-active', 66021 buttonGroup: 'btn-group', 66022 button: 'btn btn-primary', 66023 stateActive: 'active', 66024 stateDisabled: 'disabled', 66025 today: 'alert alert-info', 66026 popover: 'card card-primary', 66027 popoverHeader: 'card-header', 66028 popoverContent: 'card-body', 66029 // day grid 66030 // for left/right border color when border is inset from edges (all-day in agenda view) 66031 // avoid `table` class b/c don't want margins/padding/structure. only border color. 66032 headerRow: 'table-bordered', 66033 dayRow: 'table-bordered', 66034 // list view 66035 listView: 'card card-primary' 66036}; 66037Bootstrap4Theme.prototype.baseIconClass = 'fa'; 66038Bootstrap4Theme.prototype.iconClasses = { 66039 close: 'fa-times', 66040 prev: 'fa-chevron-left', 66041 next: 'fa-chevron-right', 66042 prevYear: 'fa-angle-double-left', 66043 nextYear: 'fa-angle-double-right' 66044}; 66045Bootstrap4Theme.prototype.iconOverrideOption = 'bootstrapFontAwesome'; 66046Bootstrap4Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; 66047Bootstrap4Theme.prototype.iconOverridePrefix = 'fa-'; 66048 66049 66050/***/ }), 66051/* 260 */ 66052/***/ (function(module, exports, __webpack_require__) { 66053 66054Object.defineProperty(exports, "__esModule", { value: true }); 66055var ViewRegistry_1 = __webpack_require__(22); 66056var BasicView_1 = __webpack_require__(62); 66057var MonthView_1 = __webpack_require__(229); 66058ViewRegistry_1.defineView('basic', { 66059 'class': BasicView_1.default 66060}); 66061ViewRegistry_1.defineView('basicDay', { 66062 type: 'basic', 66063 duration: { days: 1 } 66064}); 66065ViewRegistry_1.defineView('basicWeek', { 66066 type: 'basic', 66067 duration: { weeks: 1 } 66068}); 66069ViewRegistry_1.defineView('month', { 66070 'class': MonthView_1.default, 66071 duration: { months: 1 }, 66072 defaults: { 66073 fixedWeekCount: true 66074 } 66075}); 66076 66077 66078/***/ }), 66079/* 261 */ 66080/***/ (function(module, exports, __webpack_require__) { 66081 66082Object.defineProperty(exports, "__esModule", { value: true }); 66083var ViewRegistry_1 = __webpack_require__(22); 66084var AgendaView_1 = __webpack_require__(226); 66085ViewRegistry_1.defineView('agenda', { 66086 'class': AgendaView_1.default, 66087 defaults: { 66088 allDaySlot: true, 66089 slotDuration: '00:30:00', 66090 slotEventOverlap: true // a bad name. confused with overlap/constraint system 66091 } 66092}); 66093ViewRegistry_1.defineView('agendaDay', { 66094 type: 'agenda', 66095 duration: { days: 1 } 66096}); 66097ViewRegistry_1.defineView('agendaWeek', { 66098 type: 'agenda', 66099 duration: { weeks: 1 } 66100}); 66101 66102 66103/***/ }), 66104/* 262 */ 66105/***/ (function(module, exports, __webpack_require__) { 66106 66107Object.defineProperty(exports, "__esModule", { value: true }); 66108var ViewRegistry_1 = __webpack_require__(22); 66109var ListView_1 = __webpack_require__(230); 66110ViewRegistry_1.defineView('list', { 66111 'class': ListView_1.default, 66112 buttonTextKey: 'list', 66113 defaults: { 66114 buttonText: 'list', 66115 listDayFormat: 'LL', 66116 noEventsMessage: 'No events to display' 66117 } 66118}); 66119ViewRegistry_1.defineView('listDay', { 66120 type: 'list', 66121 duration: { days: 1 }, 66122 defaults: { 66123 listDayFormat: 'dddd' // day-of-week is all we need. full date is probably in header 66124 } 66125}); 66126ViewRegistry_1.defineView('listWeek', { 66127 type: 'list', 66128 duration: { weeks: 1 }, 66129 defaults: { 66130 listDayFormat: 'dddd', 66131 listDayAltFormat: 'LL' 66132 } 66133}); 66134ViewRegistry_1.defineView('listMonth', { 66135 type: 'list', 66136 duration: { month: 1 }, 66137 defaults: { 66138 listDayAltFormat: 'dddd' // day-of-week is nice-to-have 66139 } 66140}); 66141ViewRegistry_1.defineView('listYear', { 66142 type: 'list', 66143 duration: { year: 1 }, 66144 defaults: { 66145 listDayAltFormat: 'dddd' // day-of-week is nice-to-have 66146 } 66147}); 66148 66149 66150/***/ }), 66151/* 263 */ 66152/***/ (function(module, exports) { 66153 66154Object.defineProperty(exports, "__esModule", { value: true }); 66155 66156 66157/***/ }) 66158/******/ ]); 66159}); 66160; 66161//# sourceMappingURL=scripts.js.map
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.