1// Polyfills 2( function () { 3 // CustomEvent for IE11 and Edge. 4 if ( typeof window.CustomEvent !== "function" ) { 5 function CustomEvent( event, params ) { 6 params = params || {}; 7 var evt = document.createEvent( 'CustomEvent' ); 8 evt.initCustomEvent( event, params.bubbles || false, params.cancelable || false, params.detail || undefined ); 9 return evt; 10 } 11 CustomEvent.prototype = window.Event.prototype; 12 window.CustomEvent = CustomEvent; 13 } 14 15 // Static object detection method, lifted from jQuery 16 if ( !Object.isPlainObject ) { 17 ( function () { 18 var getProto = Object.getPrototypeOf; 19 var class2type = {}; 20 var toString = class2type.toString; 21 var hasOwn = class2type.hasOwnProperty; 22 var fnToString = hasOwn.toString; 23 var ObjectFunctionString = fnToString.call( Object ); 24 25 Object.isPlainObject = function ( obj ) { 26 var proto, Ctor; 27 28 // Detect obvious negatives 29 // Use toString instead of jQuery.type to catch host objects 30 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 31 return false; 32 } 33 34 proto = getProto( obj ); 35 36 // Objects with no prototype (e.g., `Object.create( null )`) are plain 37 if ( !proto ) { 38 return true; 39 } 40 41 // Objects with prototype are plain iff they were constructed by a global Object function 42 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 43 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 44 }; 45 } )(); 46 } 47 // Static empty object detection method. 48 if ( !Object.isEmptyObject ) { 49 ( function () { 50 Object.isEmptyObject = function ( obj ) { 51 if ( !Object.isPlainObject( obj ) ) { 52 // Not a plain object, so it cannot be an empty one. 53 return false; 54 } 55 // Look for any properties belonging to the object. 56 for ( var p in obj ) { 57 if ( !obj.hasOwnProperty( p ) ) { 58 // Skip over inherited ones. 59 continue; 60 } else { 61 // Has a property, therefore it isn't empty. 62 return false; 63 } 64 } 65 // All good. 66 return true; 67 }; 68 } )(); 69 } 70 if ( !Object.extend ) { 71 ( function () { 72 function value( v ) { 73 var arr; 74 if ( v === undefined || v === null ) { 75 return v; 76 } 77 switch ( typeof v ) { 78 case 'boolean': 79 case 'number': 80 case 'string': 81 // By value. 82 return v; 83 } 84 if ( v.constructor === Date ) { 85 // Clone the date. 86 return new Date( v.getTime() ); 87 } else if ( Array.isArray( v ) ) { 88 // Clone the array. 89 arr = new Array( v.length ); 90 for ( var i = 0; i < v.length; i++ ) { 91 arr[i] = value( v[i], true ); 92 } 93 return arr; 94 } else if ( Object.isPlainObject( v ) ) { 95 // Clone the object and return it. 96 return Object.extend( {}, v ); 97 } else { 98 return undefined; 99 } 100 } 101 // Combined objects together. 102 // If the first object is null or undefined a new object will be initialized. 103 Object.extend = function () { 104 var start, next, v, 105 args = Array.from( arguments ); 106 start = args.shift() || {}; 107 while ( next = args.shift() ) { 108 if ( !Object.isPlainObject( next ) ) { 109 // Only extend plain objects. 110 continue; 111 } 112 for ( var p in next ) { 113 if ( !next.hasOwnProperty( p ) ) { 114 // Skip inherited properties. 115 continue; 116 } 117 v = value( next[p] ); 118 if ( v !== undefined ) { 119 // Assign any non-undefind values. 120 start[p] = v; 121 } 122 } 123 } 124 return start; 125 }; 126 // Create a clone of an object or array. 127 Object.clone = function ( o ) { 128 return value( o ); 129 }; 130 } )(); 131 } 132 if ( !Array.isArray ) { 133 Array.isArray = function ( arg ) { 134 return Object.prototype.toString.call( arg ) === '[object Array]'; 135 }; 136 } 137 // MDN polyfill 138 if ( !Array.from ) { 139 Array.from = ( function () { 140 var toStr = Object.prototype.toString; 141 var isCallable = function ( fn ) { 142 return typeof fn === 'function' || toStr.call( fn ) === '[object Function]'; 143 }; 144 var toInteger = function ( value ) { 145 var number = Number( value ); 146 if ( isNaN( number ) ) { return 0; } 147 if ( number === 0 || !isFinite( number ) ) { return number; } 148 return ( number > 0 ? 1 : -1 ) * Math.floor( Math.abs( number ) ); 149 }; 150 var maxSafeInteger = Math.pow( 2, 53 ) - 1; 151 var toLength = function ( value ) { 152 var len = toInteger( value ); 153 return Math.min( Math.max( len, 0 ), maxSafeInteger ); 154 }; 155 156 // The length property of the from method is 1. 157 return function from( arrayLike/*, mapFn, thisArg */ ) { 158 // 1. Let C be the this value. 159 var C = this; 160 161 // 2. Let items be ToObject(arrayLike). 162 var items = Object( arrayLike ); 163 164 // 3. ReturnIfAbrupt(items). 165 if ( arrayLike == null ) { 166 throw new TypeError( 'Array.from requires an array-like object - not null or undefined' ); 167 } 168 169 // 4. If mapfn is undefined, then let mapping be false. 170 var mapFn = arguments.length > 1 ? arguments[1] : void undefined; 171 var T; 172 if ( typeof mapFn !== 'undefined' ) { 173 // 5. else 174 // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. 175 if ( !isCallable( mapFn ) ) { 176 throw new TypeError( 'Array.from: when provided, the second argument must be a function' ); 177 } 178 179 // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. 180 if ( arguments.length > 2 ) { 181 T = arguments[2]; 182 } 183 } 184 185 // 10. Let lenValue be Get(items, "length"). 186 // 11. Let len be ToLength(lenValue). 187 var len = toLength( items.length ); 188 189 // 13. If IsConstructor(C) is true, then 190 // 13. a. Let A be the result of calling the [[Construct]] internal method 191 // of C with an argument list containing the single item len. 192 // 14. a. Else, Let A be ArrayCreate(len). 193 var A = isCallable( C ) ? Object( new C( len ) ) : new Array( len ); 194 195 // 16. Let k be 0. 196 var k = 0; 197 // 17. Repeat, while k < len⦠(also steps a - h) 198 var kValue; 199 while ( k < len ) { 200 kValue = items[k]; 201 if ( mapFn ) { 202 A[k] = typeof T === 'undefined' ? mapFn( kValue, k ) : mapFn.call( T, kValue, k ); 203 } else { 204 A[k] = kValue; 205 }
206 k += 1; 207 } 208 // 18. Let putStatus be Put(A, "length", len, true). 209 A.length = len; 210 // 20. Return A. 211 return A; 212 }; 213 }() ); 214 } 215 // Create an array quick sort function. 216 if ( !Array.quickSort ) { 217 ( function () { 218 var utils = { 219 // Swap two positions of an array. 220 swap: function ( array, a, b ) { 221 var tmp = array[a]; 222 array[a] = array[b]; 223 array[b] = tmp; 224 }, 225 // Separate part of an array into high/low. 226 partition: function ( array, begin, end, pivot, fn ) { 227 // Get the pivit point. 228 var piv = array[pivot]; 229 utils.swap( array, pivot, end - 1 ); 230 231 // Move all items in front of or after the pivot point. 232 var store = begin; 233 var ix; 234 for ( ix = begin; ix < end - 1; ++ix ) { 235 if ( fn ? fn( array[ix], piv ) <= 0 : array[ix] <= piv ) { 236 utils.swap( array, store, ix ); 237 ++store; 238 } 239 } 240 utils.swap( array, end - 1, store ); 241 242 return store; 243 }, 244 // Perform a quicksort on a part of an array. 245 quick: function ( array, begin, end, fn ) { 246 if ( end - 1 > begin ) { 247 // Get a pivot point. 248 var pivot = begin + Math.floor( Math.random() * ( end - begin ) ); 249 250 // Partition the array in to pre-sorted halves. 251 pivot = utils.partition( array, begin, end, pivot, fn ); 252 253 // Recursivly sort each half. 254 utils.quick( array, begin, pivot, fn ); 255 utils.quick( array, pivot + 1, end, fn ); 256 } 257 } 258 }; 259 // Run a partition-exchange sort. 260 Array.quickSort = function ( array, fn ) { 261 utils.quick( array, 0, array.length, fn ); 262 }; 263 } )(); 264 } 265 if ( !Array.bindex ) { 266 // Perform a b-tree search of an array for a value. 267 Array.bindex = function ( array, key, propName, last ) { 268 var min, max, found, mid, item, val; 269 270 if ( !array || !array.length ) { 271 return -1; 272 } 273 274 min = 0; 275 max = array.length - 1; 276 found = null; 277 278 if ( last === undefined && propName === true ) { 279 last = propName; 280 propName === undefined; 281 } 282 283 // Search until we've collapsed the dimensions. 284 while ( min < max ) { 285 // Get the middle, truncated downwards. 286 mid = ( min + max ) >> 1; 287 item = array[mid]; 288 289 // Get the value as a property, or the element itself. 290 if ( propName ) { 291 val = item[propName]; 292 } else { 293 val = item; 294 } 295 296 // Reduce the search. 297 if ( val < key ) { 298 min = mid + 1; 299 } else if ( val > key ) { 300 max = mid - 1; 301 } else { 302 // Found an exact match, keep going until we get the first (or last) match. 303 found = mid; 304 if ( last ) { 305 min = mid + 1; 306 } else { 307 max = mid - 1; 308 } 309 } 310 } 311 312 if ( found !== null ) { 313 // Found an exact match. 314 return found; 315 } else if ( min === 0 ) { 316 // First item on the list. 317 return min; 318 } else { 319 // If we don't have an exact match, we want the last value that is LESSER than the key. 320 321 // Get the item and value. 322 item = array[min]; 323 if ( propName ) { 324 val = item[propName]; 325 } else { 326 val = item; 327 } 328 329 // If the value is greater than the key, move back one. 330 if ( val > key ) { 331 min--; 332 } 333 334 return min; 335 } 336 }; 337 } 338 339 // MDN polyfill. 340 if ( window.NodeList && !NodeList.prototype.forEach ) { 341 NodeList.prototype.forEach = function ( callback, thisArg ) { 342 thisArg = thisArg || window; 343 for ( var i = 0; i < this.length; i++ ) { 344 callback.call( thisArg, this[i], i, this ); 345 } 346 }; 347 } 348 if ( window.HTMLCollection && !HTMLCollection.prototype.forEach ) { 349 HTMLCollection.prototype.forEach = function ( callback, thisArg ) { 350 thisArg = thisArg || window; 351 for ( var i = 0; i < this.length; i++ ) { 352 callback.call( thisArg, this[i], i, this ); 353 } 354 }; 355 } 356 if ( window.NodeList && !NodeList.prototype.contains ) { 357 NodeList.prototype.contains = function ( item ) { 358 return Array.prototype.indexOf.call( this, item ) >= 0; 359 }; 360 } 361 if ( window.HTMLCollection && !HTMLCollection.prototype.contains ) { 362 HTMLCollection.prototype.contains = function ( item ) { 363 return Array.prototype.indexOf.call( this, item ) >= 0; 364 }; 365 } 366 ( function ( arr ) { 367 arr.forEach( function ( item ) { 368 if ( item.hasOwnProperty( 'remove' ) ) { 369 return; 370 } 371 Object.defineProperty( item, 'remove', { 372 configurable: true, 373 enumerable: true, 374 writable: true, 375 value: function remove() { 376 if ( this.parentNode !== null ) 377 this.parentNode.removeChild( this ); 378 } 379 } ); 380 } ); 381 } )( [Element.prototype, CharacterData.prototype, DocumentType.prototype] ); 382 383 // Syntatical sugar for the dispatch event function. 384 if ( !Element.prototype.trigger ) { 385 Element.prototype.trigger = function ( type, detail ) { 386 var evt = { bubbles: true, cancelable: true }; 387 if ( detail ) { 388 evt.detail = detail; 389 } 390 return this.dispatchEvent( new window.CustomEvent( type, evt ) ); 391 }; 392 } 393 if ( !Window.prototype.trigger ) { 394 Window.prototype.trigger = function ( type, detail ) { 395 var evt = {}; 396 if ( detail ) { 397 evt.detail = detail; 398 } 399 return this.dispatchEvent( new window.CustomEvent( type, evt ) ); 400 }; 401 } 402 403 // Returns the nearest link/button and associated data. 404 if ( !Element.prototype.linkData ) { 405 Element.prototype.linkData = function () { 406 var link = this.closest( 'a,button' ), 407 href = link && link.getAttribute( 'href' ), 408 m = href && /^javascript:(\w+)(?:\('([^']+)')?/i.exec( href ), 409 fn = m && m[1], 410 action = ( fn === 'void' ? m[2] : undefined ); 411 return { 412 link: link, 413 href: href, 414 fn: fn, 415 action: action || ( link && link.getAttribute( 'data-action' ) ) 416 }; 417 }; 418 } 419
420 if ( !Element.prototype.focusAfter ) { 421 // Focus on an element after a delay. 422 Element.prototype.focusAfter = function ( delay, callback ) { 423 clearTimeout( this.$focus || 0 ); 424 if ( !this.focus ) { return; } 425 this.$focus = setTimeout( function () { 426 try { this.focus(); } 427 catch ( ex ) { ; } 428 delete this.$focus; 429 if ( callback === true && this.setSelectionRange ) { 430 this.setSelectionRange( 0, this.value.length ); 431 } else if ( callback && callback.call ) { 432 try { callback.call( this ); } 433 catch ( ex ) { ; } 434 } 435 }.bind( this ), +( delay ) || 0 ); 436 }; 437 } 438 439 if ( !Element.prototype.matches ) { 440 // This Polyfill goes down to IE9 with a jQuery fallback. 441 Element.prototype.matches = 442 Element.prototype.matchesSelector || 443 Element.prototype.mozMatchesSelector || 444 Element.prototype.msMatchesSelector || 445 Element.prototype.oMatchesSelector || 446 Element.prototype.webkitMatchesSelector || 447 function ( selector ) { 448 if ( window.jQuery ) { 449 return $( this ).is( selector ); 450 } else { 451 return false; 452 } 453 } 454 } 455 456 if ( !Element.prototype.closest ) { 457 if ( !Element.prototype.matches ) { 458 // Polyfill for browsers that have no native "matches" function. 459 Element.prototype.closest = function ( s ) { 460 var i, 461 matches = ( this.ownerDocument || this.document ).querySelectorAll( s ), 462 el = this; 463 do { 464 i = matches.length; 465 while ( --i >= 0 && matches.item( i ) !== el ) { }; 466 } while ( ( i < 0 ) && ( el = el.parentElement ) ); 467 return el; 468 }; 469 } else { 470 // More efficient polyfill. 471 Element.prototype.closest = function ( s ) { 472 var el = this, 473 doc = el.ownerDocument || document; 474 if ( !doc.documentElement.contains( el ) ) return null; 475 do { 476 if ( !el.matches ) { return null; } 477 else if ( el.matches( s ) ) { return el; } 478 el = el.parentElement || el.parentNode; 479 } while ( el ); 480 return null; 481 }; 482 } 483 } 484 485 // Single firing event to remove a loading class. 486 function ifLoading() { 487 var cls = this.$loading; 488 if ( cls ) { 489 if ( this.$self ) { 490 this.classList.remove( cls ); 491 } else { 492 this.parentNode.classList.remove( cls ); 493 } 494 } 495 delete this.$loading; 496 delete this.$self; 497 this.removeEventListener( 'load', ifLoading, false ); 498 } 499 500 if ( !HTMLImageElement.prototype.ifloading ) { 501 // If an image hasn't yet loaded, add a class until it has. 502 HTMLImageElement.prototype.ifloading = function ( cls, self ) { 503 // Make sure we can do this. 504 if ( this.complete ) { 505 return; 506 } 507 508 // If we weren't in the middle of a loading event, write it up. 509 if ( !this.$loading ) { 510 this.addEventListener( 'load', ifLoading, false ); 511 this.addEventListener( 'error', ifLoading, false ); 512 } 513 514 // Add the class. 515 this.$loading = cls || 'loading'; 516 this.$self = !!self; 517 if ( self ) { 518 this.classList.add( this.$loading ); 519 } else { 520 this.parentNode.classList.add( this.$loading ); 521 } 522 }; 523 } 524 525 if ( !Element.prototype.scrollParent ) { 526 // Find the first scrollable parent element. 527 Element.prototype.scrollParent = function () { 528 var el = this.parentNode, 529 doc = this.ownerDocument, 530 wn = doc.defaultView; 531 while ( el ) { 532 if ( !el.parentNode || el.parentNode === doc.body || el.parentNode === doc.documentElement || el.parentNode === doc || el.parentNode === doc.defaultView ) { 533 return null; 534 } else if ( wn.getComputedStyle( el ).getPropertyValue( 'overflow' ) !== 'visible' ) { 535 return el; 536 } 537 el = el.parentNode; 538 } 539 return null; 540 }; 541 } 542 543 if ( !Element.prototype.scrollTo ) { 544 // Same as the Window.scrollTo method but for an element. 545 Element.prototype.scrollTo = function ( x, y ) { 546 this.scrollLeft = x; 547 this.scrollTop = y; 548 }; 549 } 550 551 if ( !Element.prototype.scrolling ) { 552 // Smooth scrollBy with a named duration. 553 Element.prototype.scrolling = function ( x, y, duration, callback ) { 554 var wn, opt, fn; 555 if ( !x && !y ) { 556 // Handle any callback. 557 if ( callback ) { 558 try { callback.call( this ); } 559 catch ( ex ) { ; } 560 } 561 return; 562 } 563 564 // Get the window so we can handle the animation frames. 565 if ( this.cancelAnimationFrame ) { 566 wn = this; 567 } else { 568 wn = this.ownerDocument.defaultView; 569 } 570 if ( !wn ) { 571 return; 572 } 573 574 // Cancel any existing animation. 575 if ( this.$scrolling && this.$scrolling.frame ) { 576 wn.cancelAnimationFrame( this.$scrolling.frame ); 577 } 578 delete this.$scrolling; 579 580 // Define the scrolling options. 581 opt = { 582 startX: this.pageXOffset || this.scrollLeft || 0, 583 startY: this.pageYOffset || this.scrollTop || 0, 584 diffX: x, 585 diffY: y, 586 dur: duration || Math.min( 500, Math.max( 250, Math.abs( y / 4 ) ) ), 587 frame: 0, 588 style: this.style || wn.document.documentElement.style 589 }; 590 591 if ( callback && typeof callback === 'function' ) { 592 opt.callback = callback; 593 } 594 595 // Are we trying to move past the start? 596 if ( opt.diffY < 0 && opt.startY === 0 ) { 597 opt.diffY = 0; 598 } 599 if ( opt.diffX < 0 && opt.startX === 0 ) { 600 opt.diffX = 0; 601 } 602 if ( !opt.diffY && !opt.diffX ) { 603 // Handle any callback. 604 if ( opt.callback ) { 605 try { opt.callback.call( this ); } 606 catch ( ex ) { ; } 607 } 608 opt = null; 609 return; 610 } 611 612 if ( opt.dur < 0 ) { 613 x = opt.diffX + opt.startX; 614 y = opt.diffY + opt.startY; 615 this.scrollTo( x, y ); 616 return; 617 } 618 619 this.$scrolling = opt; 620 621 // Animation function. 622 fn = function ( timestamp ) { 623 var diff, percent, x, y, 624 opt = this.$scrolling; 625 626 if ( !opt.begin ) { 627 // Initialize the start time. 628 opt.begin = timestamp; 629 if ( opt.style ) { 630 // Disable smooth scrolling as it doesn't allow for a specified duration. 631 opt.style.setProperty( 'scroll-behavior', 'auto' ); 632 } 633 } else { 634 // How far along? 635 diff = ( timestamp - opt.begin ); 636 percent = Math.min( 1, diff / opt.dur ); 637 // Swing easing. 638 percent = 0.5 - Math.cos( percent * Math.PI ) / 2; 639 x = ( percent * opt.diffX ) + opt.startX; 640 y = ( percent * opt.diffY ) + opt.startY; 641 642 // Set the scroll position. 643 this.scrollTo( x, y ); 644 645 // We're done. 646 if ( percent === 1 ) { 647 if ( opt.style ) { 648 // Clear the inline scroll behavior property. 649 opt.style.removeProperty( 'scroll-behavior' ); 650 // Clear the reference to the DOM style collection. 651 delete opt.style; 652 } 653 654 // Handle any callback. 655 if ( opt.callback ) { 656 try { opt.callback.call( this ); } 657 catch ( ex ) { ; } 658 } 659 delete this.$scrolling; 660 return; 661 } 662 } 663 this.$scrolling.frame = wn.requestAnimationFrame( fn ); 664 }.bind( this ); 665 666 // Start the new animation. 667 this.$scrolling.frame = wn.requestAnimationFrame( fn ); 668 }; 669 } 670 if ( !Window.prototype.scrolling ) { 671 // Add the scrolling function to the window as well. 672 Window.prototype.scrolling = Element.prototype.scrolling; 673 } 674 675 if ( !Document.prototype.getFixedElements ) { 676 // Get all fixed elements on the page. 677 Document.prototype.getFixedElements = function () { 678 var el, style, position, 679 // Only bother to check these tags if they have a fixed position. 680 elements = this.querySelectorAll( "aside,div,header,nav,ul" ), 681 fixed = []; 682 for ( var i = 0; i < elements.length; i++ ) { 683 el = elements[i]; 684 style = window.getComputedStyle( el ); 685 position = style.getPropertyValue( 'position' ); 686 if ( position === 'fixed' || position === 'sticky' ) 687 fixed.push( el ); 688 } 689 return fixed; 690 } 691 }; 692 693 if ( !Document.prototype.fixedOffset ) { 694 // How much room do we need for any fixed "sticky" header nav. 695 Document.prototype.fixedOffset = function () { 696 var bounds, 697 width = this.documentElement.clientWidth / 2, 698 fixed = this.getFixedElements(), 699 offset = 0; 700 for ( var i = 0; i < fixed.length; i++ ) { 701 bounds = fixed[i].getBoundingClientRect(); 702 if ( bounds.top === 0 && 703 bounds.left === 0 && 704 bounds.width > width && 705 bounds.height > offset ) { 706 // If the element is at the top of the page, and is wider than half of the viewport. 707 offset = bounds.height; 708 } 709 } 710 return offset; 711 }; 712 } 713 714 if ( !Element.prototype.scrollIntoViewport ) { 715 // Smoothly scroll an element into view. 716 Element.prototype.scrollIntoViewport = function ( options ) { 717 var bounds, before, after, height, width, rect, top, left, offset, doc, y, x, b, dur, fn, 718 container = options && options.container, 719 margin = ( options && options.margin ) || 20; 720 721 // Start with the element dimensions. 722 bounds = this.getBoundingClientRect(); 723 724 // If we have an invisible element. 725 if ( bounds.height === 0 && bounds.top === 0 ) { 726 // Try the element just before. 727 before = this.previousElementSibling && this.previousElementSibling.getBoundingClientRect(); 728 if ( before && before.height ) { 729 bounds = { 730 top: before.bottom + 1, 731 right: before.right, 732 bottom: before.bottom + 2, 733 left: before.left, 734 width: before.width, 735 height: 1 736 }; 737 } else { 738 after = this.nextElementSibling && this.nextElementSibling.getBoundingClientRect(); 739 } 740 // Try the element just after. 741 if ( after && after.height ) { 742 bounds = { 743 top: after.top - 2, 744 right: after.right, 745 bottom: after.top - 1, 746 left: after.left, 747 width: after.width, 748 height: 1 749 }; 750 } else if ( !bounds ) { 751 // Try the parent. 752 bounds = this.parentNode.getBoundingClientRect(); 753 if ( !bounds.height ) { 754 // Not visible. 755 return; 756 } 757 } 758 } else if ( bounds.height === 0 && this.nodeName === 'INPUT' ) { 759 // Try the parent. 760 bounds = this.parentNode.getBoundingClientRect(); 761 if ( !bounds.height ) { 762 // Not visible. 763 return; 764 } 765 } 766 767 // Get the container that will be scrolled. 768 if ( container === false ) { 769 // Force a document scroll. 770 } else if ( !container ) { 771 // Get the nearest parent scroll element. 772 container = this.scrollParent(); 773 } else if ( !container.ownerDocument ) { 774 console.log( 'Invalid container', container ); 775 return; 776 } else if ( !container.contains( this ) ) { 777 console.log( 'Element not found in container', this, container ); 778 return; 779 } 780 781 // Get the height and position of the container. 782 if ( container ) { 783 height = container.clientHeight; 784 if ( !height ) { return; } 785 width = container.clientWidth; 786 rect = container.getBoundingClientRect(); 787 top = rect.top; 788 left = rect.left; 789 offset = 0; 790 } else { 791 doc = this.ownerDocument; 792 height = doc.documentElement.clientHeight; 793 width = doc.documentElement.clientWidth; 794 top = 0; 795 if ( options && options.fixed ) { 796 offset = doc.fixedOffset(); 797 } else { 798 offset = 0; 799 } 800 } 801 802 // If the element is taller than the viewport, always assume anchor to the top. 803 if ( bounds.height > height + 1 ) { 804 if ( !options ) { 805 options = {}; 806 } 807 options.top = true; 808 } 809 810 // Do we have to move it into position? 811 y = bounds.top - offset - top - margin; 812 if ( y >= 1 && ( !options || !options.top ) ) { 813 b = options && options.height ? bounds.top + options.height : bounds.bottom; 814 y = b - top - height + margin 815 if ( y <= 1 ) { 816 // Nope. 817 y = 0; 818 } 819 } 820 821 // Do we have to move it into position? 822 x = bounds.left - left - margin; 823 if ( x >= 1 && ( !options || !options.left ) ) { 824 b = options && options.width ? bounds.left + options.width : bounds.right; 825 x = b - left - width + margin; 826 if ( x <= 1 ) { 827 // Nope. 828 x = 0; 829 } 830 } 831 832 // Activate the scrolling. 833 if ( options && options.instant ) { 834 dur = -1; 835 } else { 836 dur = options && options.duration; 837 fn = options && options.callback; 838 } 839 ( container || this.ownerDocument.defaultView ).scrolling( x, y, dur, fn ); 840 }; 841 } 842 843 var regxDate = [ 844 /^\d{4}\-\d{2}\-\d{2}T\d\d\:\d\d/, 845 /^(\d{4})\-(\d{2})\-(\d{2})(?:\s+|$)/, 846 /(^.+ |^\s*)(\d+):(\d+)(:\d+)? ?(?:(am)|(pm))\s*$/i, 847 /(^.+ |^\s*)(\d+):(\d+)(?:(\d+)(\.\d+)?)?\s*$/ 848 ]; 849 850 if ( !Date.parse2 ) { 851 // Parse a date with more options. 852 Date.parse2 = function ( str ) { 853 var d, m, h; 854 if ( !str ) { 855 return null; 856 } else if ( str.constructor === Date ) { 857 return str; 858 } else if ( typeof str !== 'string' ) { 859 d = new Date( str ); 860 } else { 861 for ( var i = 0; i < regxDate.length; i++ ) { 862 m = regxDate[i].exec( str ); 863 if ( !m ) { 864 continue; 865 } else if ( i === 0 ) { 866 // ISO 8601, use the standard parser. 867 break; 868 } else if ( i === 1 ) { 869 // Extract the date portion.
870 d = new Date( +( m[1] ), +( m[2] ) - 1, +( m[3] ) ); 871 } else if ( i === 2 ) { 872 // Extract the date portion. 873 d = new Date( m[1] || new Date() ); 874 if ( isNaN( d ) ) { 875 return null; 876 } 877 // AM:PM time. 878 h = +( m[2] ); 879 if ( m[5] && h === 12 ) { 880 // 12:00 AM 881 d.setHours( 0 ); 882 } else if ( m[6] && h < 12 ) { 883 // < 12:00 PM 884 d.setHours( h + 12 ); 885 } else { 886 // Everything else. 887 d.setHours( h ); 888 } 889 d.setMinutes( +( m[3] ) ); 890 if ( m[4] ) { 891 d.setSeconds( +( m[4].substr( 1 ) ) ); 892 } else { 893 d.setSeconds( 0 ); 894 } 895 d.setMilliseconds( 0 ); 896 } else if ( i === 3 ) { 897 // Extract the date portion. 898 d = new Date( m[1] || new Date() ); 899 if ( isNaN( d ) ) { 900 return null; 901 } 902 // 24 hour time. 903 d.setHours( +( m[2] ) ); 904 d.setMinutes( +( m[3] ) ); 905 d.setSeconds( +( m[4] ) || 0 ); 906 d.setMilliseconds( ( +( m[5] ) || 0 ) * 1000 ); 907 } 908 } 909 if ( !d ) { 910 // Default parser. 911 d = new Date( Date.parse( str ) ); 912 } 913 } 914 return isNaN( d ) ? null : d; 915 }; 916 917 var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; 918 var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; 919 var monthIds = { "Jan": 0, "Feb": 1, "Mar": 2, "Apr": 3, "May": 4, "Jun": 5, "Jul": 6, "Aug": 7, "Sep": 8, "Oct": 9, "Nov": 10, "Dec": 11 }; 920 921 // Format the date, readble. 922 Date.prototype.formatted = function ( pattern ) { 923 var local = new Date( this ); 924 local.setMinutes( local.getMinutes() - local.getTimezoneOffset() ); 925 926 var a, upper, 927 text = local.toJSON(), 928 y = text.slice( 0, 4 ), 929 M = text.slice( 5, 7 ), 930 d = text.slice( 8, 10 ), 931 H = text.slice( 11, 13 ), 932 h = +( H ), 933 m = text.slice( 14, 16 ), 934 s = text.slice( 17, 19 ), 935 f = text.slice( 20, 23 ), 936 day = this.getDay(); 937 938 return ( pattern || "M/d/yyyy" ).replace( /\\.|y{2,4}|M{1,4}|d{1,4}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|t{1,2}|T{1,2}|f{1,3}|rr|RR|ZZZ/g, function ( match ) { 939 switch ( match ) { 940 case 'yy': 941 return y.slice( 2, 4 ); 942 case 'yyyy': 943 return y; 944 case 'M': 945 return +( M ); 946 case 'MM': 947 return M; 948 case 'MMM': 949 return monthNames[+( M ) - 1].slice( 0, 3 ); 950 case 'MMMM': 951 return monthNames[+( M ) - 1]; 952 case 'd': 953 return +( d ); 954 case 'dd': 955 return d; 956 case 'ddd': 957 return dayNames[day].slice( 0, 3 ); 958 case 'dddd': 959 return dayNames[day]; 960 case 'H': 961 return +( H ); 962 case 'HH': 963 return H; 964 case 'h': 965 if ( h === 0 ) { 966 return 12; 967 } else if ( h > 12 ) { 968 return h - 12; 969 } else { 970 return h; 971 } 972 case 'hh': 973 if ( h < 10 ) { 974 return '0' + h; 975 } else { 976 return h; 977 } 978 case 'm': 979 return +( m ); 980 case 'mm': 981 return m; 982 case 's': 983 return +( s ); 984 case 'ss': 985 return s; 986 case 't': 987 return H > 11 ? 'p' : 'a'; 988 case 'tt': 989 return H > 11 ? 'pm' : 'am'; 990 case 'T': 991 return H > 11 ? 'P' : 'A'; 992 case 'TT': 993 return H > 11 ? 'PM' : 'AM'; 994 case 'f': 995 return f.slice( 0, 1 ); 996 case 'ff': 997 return f.slice( 0, 2 ); 998 case 'fff': 999 return f; 1000 case 'rr': 1001 case 'RR': 1002 upper = match === 'RR'; 1003 switch ( d ) { 1004 case 1: 1005 case 21: 1006 case 31: 1007 return upper ? "ST" : "st"; 1008 case 2: 1009 case 22: 1010 return upper ? "ND" : "nd"; 1011 case 3: 1012 case 23: 1013 return upper ? "RD" : "rd"; 1014 default: 1015 return upper ? "TH" : "th"; 1016 } 1017 break; 1018 case 'ZZZ': 1019 if ( Date.timeZoneAbbreviation ) { 1020 return Date.timeZoneAbbreviation( local ); 1021 } else { 1022 return ""; 1023 } 1024 default: 1025 return match[0] === '\\' ? match[1] : match; 1026 } 1027 } ); 1028 }; 1029 1030 Date.timeZoneAbbreviation = function ( date ) { 1031 var dst = jstz.date_is_dst( date ), 1032 suffix = dst ? "DT" : "ST", 1033 m = /_tz=([^;]+);/.exec( String( document.cookie ) ), 1034 tz = m && decodeURIComponent( m[1] ), 1035 friendly = tz && jstz.olson.friendly[tz]; 1036 1037 // Return the abbreviation based on the current user's time zone. 1038 switch ( friendly ) { 1039 case "Hawaiian Standard Time": 1040 return "H" + suffix; 1041 case "Alaskan Standard Time": 1042 return "A" + suffix; 1043 case "Pacific Standard Time": 1044 return "P" + suffix; 1045 case "Mountain Standard Time": 1046 return "M" + suffix; 1047 case "Central Standard Time": 1048 return "C" + suffix; 1049 case "Eastern Standard Time":
1050 return "E" + suffix; 1051 case "W. Australia Standard Time": 1052 return "AW" + suffix; 1053 case "Cen. Australia Standard Time": 1054 case "AUS Central Standard Time": 1055 return "AC" + suffix; 1056 case "AUS Eastern Standard Time": 1057 case "E. Australia Standard Time": 1058 return "AE" + suffix; 1059 case "Central Pacific Standard Time": 1060 return "CP" + suffix; 1061 case "New Zealand Standard Time": 1062 return "NZ" + suffix; 1063 case "GMT Standard Time": 1064 return "GMT"; 1065 case "Central Europe Standard Time": 1066 return suffix == "DT" ? "CEST" : "CET"; 1067 default: 1068 // Not defined yet. 1069 return ""; 1070 } 1071 }; 1072 1073 Date.isLeapYear = function ( year ) { 1074 return ( ( ( year % 4 === 0 ) && ( year % 100 !== 0 ) ) || ( year % 400 === 0 ) ); 1075 }; 1076 1077 Date.getDaysInMonth = function ( year, month ) { 1078 return [31, ( Date.isLeapYear( year ) ? 29 : 28 ), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; 1079 }; 1080 1081 Date.prototype.isLeapYear = function () { 1082 return Date.isLeapYear( this.getFullYear() ); 1083 }; 1084 1085 Date.prototype.getDaysInMonth = function () { 1086 return Date.getDaysInMonth( this.getFullYear(), this.getMonth() ); 1087 }; 1088 1089 // Add years to the current date object and return it. 1090 Date.prototype.addYears = function ( yyyy ) { 1091 if ( !yyyy || isNaN( yyyy = +( yyyy ) ) ) { 1092 return this; 1093 } 1094 this.setFullYear( this.getFullYear() + yyyy ); 1095 return this; 1096 }; 1097 1098 // Add months to the current date object and return it. 1099 Date.prototype.addMonths = function ( M ) { 1100 var d = this.getDate(); 1101 if ( !M || isNaN( M = +( M ) ) ) { 1102 return this; 1103 } 1104 this.setMonth( this.getMonth() + M ); 1105 // Ensure the days won't push us to the next month. 1106 d = Math.max( 0, Math.min( this.getDaysInMonth(), d ) ); 1107 // Set the days. 1108 this.setDate( d ); 1109 return this; 1110 }; 1111 1112 // Add days to the current date object and return it. 1113 Date.prototype.addDays = function ( d ) { 1114 if ( !d || isNaN( d = +( d ) ) ) { 1115 return this; 1116 } 1117 this.setDate( this.getDate() + d ); 1118 return this; 1119 }; 1120 1121 // Set the years, ensuring the day doesn't exceed the end of the month. 1122 Date.prototype.setYears = function ( yyyy ) { 1123 var d = this.getDate(); 1124 if ( !yyyy || isNaN( yyyy = +( yyyy ) ) ) { 1125 return; 1126 } 1127 // Reset the date to the beginning of the month so we stay in the same month. 1128 this.setDate( 1 ); 1129 this.setFullYear( yyyy ); 1130 // Ensure the days won't push us to the next month. 1131 d = Math.max( 0, Math.min( this.getDaysInMonth(), d ) ); 1132 // Set the days. 1133 this.setDate( d ); 1134 return this; 1135 }; 1136 1137 // Set the years, ensuring the day doesn't exceed the end of the month. 1138 Date.prototype.setMonths = function ( M ) { 1139 var d = this.getDate(); 1140 if ( !M || isNaN( M = +( M ) ) ) { 1141 return; 1142 } 1143 // Reset the date to the beginning of the month so we stay in the same month. 1144 this.setDate( 1 ); 1145 // Set the month. 1146 M = Math.max( 1, Math.min( 12, M ) ); 1147 this.setMonth( M - 1 ); 1148 // Ensure the days won't push us to the next month. 1149 d = Math.max( 0, Math.min( this.getDaysInMonth(), d ) ); 1150 // Set the days. 1151 this.setDate( d ); 1152 return this; 1153 }; 1154 1155 // Set the days as a 1-31, ensuring the day doesn't exceed the end of the month. 1156 Date.prototype.setDays = function ( d ) { 1157 if ( !d || isNaN( d = +( d ) ) ) { 1158 return; 1159 } 1160 // Ensure the days won't push us to the next month. 1161 d = Math.max( 0, Math.min( this.getDaysInMonth(), d ) ); 1162 // Set the days. 1163 this.setDate( d ); 1164 return this; 1165 }; 1166 1167 // Set an exact date and time. 1168 Date.prototype.set = function ( yyyy, M, d, H, m, s ) { 1169 this.setYears( yyyy ); 1170 this.setMonths( M ); 1171 this.setDays( d ); 1172 H = Math.max( 0, Math.min( 23, +( H ) || 0 ) ); 1173 m = Math.max( 0, Math.min( 59, +( m ) || 0 ) ); 1174 s = Math.max( 0, Math.min( 59, +( s ) || 0 ) ); 1175 this.setHours( H, m, s, 0 ); 1176 return this; 1177 }; 1178 } 1179 1180 // CMS7 register script. 1181 if ( window.register ) { 1182 window.register( "j/poly" ); 1183 } 1184} )();
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.