1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 2'use strict'; 3 4var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 5 6function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 7 8/** 9 * SMA JavaScript Library v1.0.0 10 * 11 * Copyright © 2019 CIDER INC. All rights reserved. 12 * 13 * Date: 2019.10.30 14 */ 15 16var SMA = function () { 17 function SMA(artist_id) { 18 var jQuery = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : $; 19 20 _classCallCheck(this, SMA); 21 22 this.artist_id = artist_id; 23 this.$ = jQuery; 24 } 25 26 /** 27 * å種URL 28 */ 29 30 _createClass(SMA, [{ 31 key: 'ajax', 32 33 34 /** 35 * Ajax 36 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 37 * @param {String} url url 38 */ 39 40 value: function ajax(callback, url) { 41 this.$.ajax({ 42 url: url, 43 dataType: 'json' 44 }).done(callback); 45 } 46 47 /** 48 * URLãã©ã¡ã¼ã¿ã®ãªãã·ã§ã³é ç®ã使 49 * @param {Object} listObj ãªãã·ã§ã³ã®ãªãã¸ã§ã¯ã 50 * { 51 * opt: 20 52 * } 53 * @return {String} çæãããæåå 54 * &opt=20 55 */ 56 57 }, { 58 key: 'optionBuildQuery', 59 value: function optionBuildQuery(listObj) { 60 var options = ''; 61 Object.keys(listObj).forEach(function (val) { 62 if (listObj[val]) { 63 options += '&' + val + '=' + listObj[val]; 64 } 65 }); 66 67 return options; 68 } 69 70 /** 71 * NEWS 72 */ 73 74 }, { 75 key: 'URL', 76 get: function get() { 77 return { 78 base: 'https://www.sma.co.jp/s/sma/api/list/', 79 80 // NEWSä¸è¦§ 81 news: 'ver2_news_list', 82 83 // NEWSä¸è¦§ï¼æ¬æä»ãï¼ 84 news2: 'ver2_news_list2', 85 86 // NEWS詳細 87 newsDetail: 'ver2_news_detail', 88 89 // LIVEä¸è¦§ 90 live: 'ver2_live_list', 91 92 // RELEASE ä¸è¦§ 93 release: 'ver2_release_list', 94 95 // RELEASE 詳細 96 releaseDitail: 'ver2_release_detail', 97 98 // MEDIA ä¸è¦§ 99 media: 'ver2_media_list', 100 101 // BIOGRAPHY 102 bio: 'ver2_biography', 103 104 // BIOGRAPHY ã¡ã¤ã³ãã¸ã¥ã¢ã« 105 mainVisual: 'ver2_main_visual', 106 107 // SNS ä¸è¦§ 108 sns: 'ver2_sns', 109 110 // å¤é¨ãªã³ã¯ ä¸è¦§ 111 link: 'ver2_link_list', 112 113 // MEMBER ä¸è¦§ 114 member: 'ver2_member_list', 115 116 // ããã¼ ä¸è¦§ 117 banner: 'ver2_banner_list', 118 119 // GALLERY ä¸è¦§ 120 gallery: 'ver2_gallery_list', 121 122 // SCHEDULE LIVE 123 scheduleLive: 'ver2_schedule_live', 124 125 // DCHEDULE MEDIA 126 scheduleMedia: 'ver2_schedule_media', 127 128 // SCHEDULE RELEASE 129 scheduleRelease: 'ver2_schedule_disco' 130 }; 131 } 132 }, { 133 key: 'news', 134 get: function get() { 135 var _this = this; 136 137 return { 138 139 /** 140 * NEWS LIST 141 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 142 * @param {Number} [rw=20] åå¾ä»¶æ° 143 * @param {Number} [page=0] ãã¼ã¸æ° 144 * @return {Object} NEWSãã¼ã¿ 145 */ 146 147 list: function list(callback) { 148 var rw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20; 149 var page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 150 151 var url = '' + _this.URL.base + _this.URL.news + '?arti=' + _this.artist_id + '&rw=' + rw + '&page=' + page; 152 _this.ajax(callback, url); 153 }, 154 155 /** 156 * NEWS DETAIL 157 * @param {Number} code è¨äºã³ã¼ã 158 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 159 * @return {Object} NEWSãã¼ã¿ 160 */ 161 162 detail: function detail(code, callback) { 163 var url = '' + _this.URL.base + _this.URL.newsDetail + '?code=' + code; 164 _this.ajax(callback, url); 165 }, 166 167 /** 168 * æ¬æä»ãNEWS LIST 169 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 170 * @param {Number} [rw=20] åå¾ä»¶æ° 171 * @param {Number} [page=0] ãã¼ã¸æ° 172 * @return {Object} NEWSãã¼ã¿ 173 */ 174 175 list2: function list2(callback) { 176 var rw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20; 177 var page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 178 179 var url = '' + _this.URL.base + _this.URL.news2 + '?arti=' + _this.artist_id + '&rw=' + rw + '&page=' + page; 180 _this.ajax(callback, url); 181 } 182 }; 183 } 184 185 /** 186 * LIVE 187 */ 188 189 }, { 190 key: 'live', 191 get: function get() { 192 var _this2 = this; 193 194 return { 195 196 /** 197 * LIVE LIST 198 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 199 * @param {Number} [rw=20] åå¾ä»¶æ° 200 * @param {Number} [page=0] ãã¼ã¸æ° 201 * @return {Object} LIVEãã¼ã¿ 202 */ 203 204 list: function list(callback) { 205 var rw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20; 206 var page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 207 208 var url = '' + _this2.URL.base + _this2.URL.live + '?arti=' + _this2.artist_id + '&rw=' + rw + '&page=' + page; 209 _this2.ajax(callback, url); 210 } 211 }; 212 } 213 214 /** 215 * RELEASE 216 */ 217 218 }, { 219 key: 'release', 220 get: function get() { 221 var _this3 = this; 222 223 return { 224 225 /** 226 * RELEASE LIST 227 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 228 * @param {Number} [rw=20] åå¾ä»¶æ° 229 * @param {Number} [page=0] ãã¼ã¸æ° 230 * @param {String} [ct=''] ã«ãã´ãªã¼ã³ã¼ã 231 * [ã«ãã´ãªã³ã¼ã] 232 * album/single/analog/DVD/BD/video/book/download/others 233 * 234 * [SMAãµã¤ã表è¨] 235 * MEDIA/ALBUM/SINGLE/ANALOG/DVD/BD/VIDEO/BOOK/DOWNLOAD/OTHERS 236 * @param {String} [dy=''] çºå£²æ¥ 237 * @return {Object} RELEASEãã¼ã¿ 238 */ 239 240 list: function list(callback) { 241 var rw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20; 242 var page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 243 var ct = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; 244 var dy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ''; 245 246 var url = '' + _this3.URL.base + _this3.URL.release + '?arti=' + _this3.artist_id + '&rw=' + rw + '&page=' + page; 247 url += _this3.optionBuildQuery({ 248 ct: ct, 249 dy: dy 250 }); 251 _this3.ajax(callback, url); 252 }, 253 254 /** 255 * RELEASE DETAIL 256 * @param {Number} titl ãªãªã¼ã¹ã³ã¼ã 257 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 258 * @return {Object} RELEASEãã¼ã¿ 259 */ 260 261 detail: function detail(titl, callback) { 262 var url = '' + _this3.URL.base + _this3.URL.releaseDitail + '?titl=' + titl; 263 _this3.ajax(callback, url); 264 } 265 }; 266 } 267 268 /** 269 * MEDIA 270 */ 271 272 }, { 273 key: 'media', 274 get: function get() { 275 var _this4 = this; 276 277 return { 278 279 /** 280 * MEDIA LIST 281 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 282 * @param {Number} [rw=20] åå¾ä»¶æ° 283 * @param {Number} [page=0] ãã¼ã¸æ° 284 * @param {String} [ct=''] ã«ãã´ãªã¼ã³ã¼ã 285 * [ã«ãã´ãªã³ã¼ã] 286 * tv/radio/movie/magazine/internet 287 * 288 * [SMAãµã¤ã表è¨] 289 * ãã¬ã/ã©ã¸ãª/æ ç»/éèª/WEB 290 * @param {String} [dy=''] æ¥ä» 291 * @param {String} [so=''] 並ã³é æå® 292 * [æªæå®æ] 293 * 1. ä¸è¦§è¡¨ç¤ºé å¤ãå°ããé 294 * 2. æ²è¼éå§æ¥æ å¤ãé 295 * [R] 296 * 1. æ²è¼éå§æ¥æ æ°ããé 297 * 2. ä¸è¦§è¡¨ç¤ºé å¤ãå°ããé 298 * ã³ã¼ãã¬ã¼ããµã¤ãã®ææ°æ å ±ãã«ãã´ãªæå®æã¨åçã«ãªãã¾ã 299 * [D] 300 * 1. æ¥ä» å¤ãé 301 * 2. ä¸è¦§è¡¨ç¤ºé å¤ãå°ããé 302 * 3. æ²è¼éå§æ¥æ æ°ããé 303 * dyã¨åããã¦ä½¿ç¨ãããã¨ã§ã³ã¼ãã¬ã¼ããµã¤ãã®å¹´ææå®æã¨åçã«ãªãã¾ã 304 * [DD] 305 * 1. æ¥ä» æ°ããé 306 * 2. ä¸è¦§è¡¨ç¤ºé å¤ãå°ããé 307 * 3. æ²è¼éå§æ¥æ æ°ããé 308 * @return {Object} MEDIAãã¼ã¿ 309 */ 310 311 list: function list(callback) { 312 var rw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20; 313 var page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 314 var ct = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; 315 var dy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ''; 316 var so = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : ''; 317 318 var url = '' + _this4.URL.base + _this4.URL.media + '?arti=' + _this4.artist_id + '&rw=' + rw + '&page=' + page; 319 url += _this4.optionBuildQuery({ 320 ct: ct, 321 dy: dy, 322 so: so 323 }); 324 _this4.ajax(callback, url); 325 } 326 }; 327 } 328 329 /** 330 * BIO 331 */ 332 333 }, { 334 key: 'bio', 335 get: function get() { 336 var _this5 = this; 337 338 return { 339 340 /** 341 * BIO text 342 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 343 * @return {Object} BIO textãã¼ã¿ 344 */ 345 346 text: function text(callback) { 347 var url = '' + _this5.URL.base + _this5.URL.bio + '?arti=' + _this5.artist_id; 348 _this5.ajax(callback, url); 349 }, 350 351 /** 352 * BIO main visual 353 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 354 * @return {Object} BIO main visualãã¼ã¿ 355 */ 356 357 visual: function visual(callback) { 358 var url = '' + _this5.URL.base + _this5.URL.mainVisual + '?arti=' + _this5.artist_id; 359 _this5.ajax(callback, url); 360 } 361 }; 362 } 363 364 /** 365 * SNS 366 */ 367 368 }, { 369 key: 'sns', 370 get: function get() { 371 var _this6 = this; 372 373 return { 374 375 /** 376 * SNS list 377 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 378 * @return {Object} SNS listãã¼ã¿ 379 */ 380 381 list: function list(callback) { 382 var url = '' + _this6.URL.base + _this6.URL.sns + '?arti=' + _this6.artist_id; 383 _this6.ajax(callback, url); 384 } 385 }; 386 } 387 388 /** 389 * LINK 390 */ 391 392 }, { 393 key: 'link', 394 get: function get() { 395 var _this7 = this; 396 397 return { 398 399 /** 400 * LINK list 401 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 402 * @return {Object} LINK listãã¼ã¿ 403 */ 404 405 list: function list(callback) { 406 var url = '' + _this7.URL.base + _this7.URL.link + '?arti=' + _this7.artist_id; 407 _this7.ajax(callback, url); 408 } 409 }; 410 } 411 412 /** 413 * MEMBER 414 */ 415 416 }, { 417 key: 'member', 418 get: function get() { 419 var _this8 = this; 420 421 return { 422 423 /** 424 * MEMBER list 425 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 426 * @return {Object} MEMBER listãã¼ã¿ 427 */ 428 429 list: function list(callback) { 430 var url = '' + _this8.URL.base + _this8.URL.member + '?arti=' + _this8.artist_id; 431 _this8.ajax(callback, url); 432 } 433 }; 434 } 435 436 /** 437 * BANNER 438 */ 439 440 }, { 441 key: 'banner', 442 get: function get() { 443 var _this9 = this; 444 445 return { 446 447 /** 448 * BANNER list 449 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 450 * @return {Object} BANNER listãã¼ã¿ 451 */ 452 453 list: function list(callback) { 454 var url = '' + _this9.URL.base + _this9.URL.banner + '?arti=' + _this9.artist_id; 455 _this9.ajax(callback, url); 456 } 457 }; 458 } 459 460 /** 461 * GALLERY 462 */ 463 464 }, { 465 key: 'gallery', 466 get: function get() { 467 var _this10 = this; 468 469 return { 470 471 /** 472 * GALLERY list 473 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 474 * @param {Number} [rw=20] åå¾ä»¶æ° 475 * @param {Number} [page=0] ãã¼ã¸æ° 476 * @return {Object} GALLERY listãã¼ã¿ 477 */ 478 479 list: function list(callback) { 480 var rw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20; 481 var page = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 482 483 var url = '' + _this10.URL.base + _this10.URL.gallery + '?arti=' + _this10.artist_id + '&rw=' + rw + '&page=' + page; 484 _this10.ajax(callback, url); 485 } 486 }; 487 } 488 489 /** 490 * SCHEDULE LIVE 491 */ 492 493 }, { 494 key: 'scheduleLive', 495 get: function get() { 496 var _this11 = this; 497 498 return { 499 500 /** 501 * SCHEDULE LIVE list 502 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 503 * @param {String} dy æ¥ä»ç¯å² 504 * YYYYMMã¾ãã¯YYYYMMDD 505 * @return {Object} SCHEDULE LIVE listãã¼ã¿ 506 */ 507 508 list: function list(callback, dy) { 509 var url = '' + _this11.URL.base + _this11.URL.scheduleLive + '?dy=' + dy; 510 _this11.ajax(callback, url); 511 } 512 }; 513 } 514 515 /** 516 * SCHEDULE MEDIA 517 */ 518 519 }, { 520 key: 'scheduleMedia', 521 get: function get() { 522 var _this12 = this; 523 524 return { 525 526 /** 527 * SCHEDULE LIVE list 528 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 529 * @param {String} dy æ¥ä»ç¯å² 530 * YYYYMMã¾ãã¯YYYYMMDD 531 * @return {Object} SCHEDULE MEDIA listãã¼ã¿ 532 */ 533 534 list: function list(callback, dy) { 535 var url = '' + _this12.URL.base + _this12.URL.scheduleMedia + '?dy=' + dy; 536 _this12.ajax(callback, url); 537 } 538 }; 539 } 540 541 /** 542 * SCHEDULE RELEASE 543 */ 544 545 }, { 546 key: 'scheduleRelease', 547 get: function get() { 548 var _this13 = this; 549 550 return { 551 552 /** 553 * SCHEDULE LIVE list 554 * @param {Function} callback ã³ã¼ã«ããã¯é¢æ° 555 * @param {String} dy æ¥ä»ç¯å² 556 * YYYYMMã¾ãã¯YYYYMMDD 557 * @return {Object} SCHEDULE RELEASE listãã¼ã¿ 558 */ 559 560 list: function list(callback, dy) { 561 var url = '' + _this13.URL.base + _this13.URL.scheduleRelease + '?dy=' + dy; 562 _this13.ajax(callback, url); 563 } 564 }; 565 } 566 }]); 567 568 return SMA; 569}(); 570 571module.exports = SMA; 572 573},{}],2:[function(require,module,exports){ 574(function (global){ 575'use strict'; 576 577global.$ = require('jquery'); 578global.TM = require('gsap'); 579var SMAClass = require('./SMA'); 580global.SMA = new SMAClass(272); 581//global.SMA = new SMAClass('a107'); 582 583global.isTouchDevice = window.ontouchstart === null; 584 585global.weekTable = { 586 'æ¥': 'SUN', 587 'æ': 'MON', 588 'ç«': 'TUE', 589 'æ°´': 'WED', 590 'æ¨': 'THU', 591 'é': 'FRI', 592 'å': 'SAT' 593}; 594 595global.END = 'oTransitionEnd mozTransitionEnd webkitTransitionEnd transitionend'; 596 597$(function () { 598 599 /** 600 * header 601 */ 602 603 var $header = $('header'); 604 $('header .menu').on('click', function () { 605 if ($header.hasClass('open')) { 606 $header.on(END, function () { 607 $(this).off(END).removeClass('open out'); 608 }).addClass('out'); 609 } else { 610 $header.addClass('open'); 611 } 612 }); 613 614 $(window).on('scroll', function () { 615 var st = $(this).scrollTop(); 616 if (st > 500) { 617 $header.addClass('scroll'); 618 } else { 619 $header.removeClass('scroll'); 620 } 621 }); 622 623 /** 624 * target="_blank" ãªaã¿ã°ã«relãè¨å® 625 */ 626 627 $('a[target="_blank"]').attr({ 628 rel: 'noopener' 629 }); 630}); 631 632}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 633},{"./SMA":1,"gsap":4,"jquery":5}],3:[function(require,module,exports){ 634'use strict'; 635 636require('./_modules/common'); 637 638$(function () { 639 640 setTimeout(function () { 641 $('h1').addClass('show'); 642 }, 300); 643 644 setTimeout(function () { 645 $('section').addClass('show'); 646 }, 950); 647 648 /* 649 SMA.bio.visual(res => { 650 $('.main_img').attr({ 651 src: res.list[0].img 652 }); 653 }); 654 */ 655 656 SMA.bio.text(f
656unction (res) { 657 for (var i in res) { 658 if (res[i].profile) { 659 $('.pf').append(res[i].profile); 660 } 661 662 if (res[i].img) { 663 $('.main_img').attr({ 664 src: res[i].img 665 }); 666 } 667 } 668 }); 669}); 670 671},{"./_modules/common":2}],4:[function(require,module,exports){ 672(function (global){ 673/*! 674 * VERSION: 1.20.5 675 * DATE: 2018-05-21 676 * UPDATES AND DOCS AT: http://greensock.com 677 * 678 * Includes all of the following: TweenLite, TweenMax, TimelineLite, TimelineMax, EasePack, CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin 679 * 680 * @license Copyright (c) 2008-2018, GreenSock. All rights reserved. 681 * This work is subject to the terms at http://greensock.com/standard-license or for 682 * Club GreenSock members, the software agreement that was issued with your membership. 683 * 684 * @author: Jack Doyle, [email protected] 685 **/ 686var _gsScope = (typeof(module) !== "undefined" && module.exports && typeof(global) !== "undefined") ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node 687(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push( function() { 688 689 "use strict"; 690 691 _gsScope._gsDefine("TweenMax", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) { 692 693 var _slice = function(a) { //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 694 var b = [], 695 l = a.length, 696 i; 697 for (i = 0; i !== l; b.push(a[i++])); 698 return b; 699 }, 700 _applyCycle = function(vars, targets, i) { 701 var alt = vars.cycle, 702 p, val; 703 for (p in alt) { 704 val = alt[p]; 705 vars[p] = (typeof(val) === "function") ? val(i, targets[i]) : val[i % val.length]; 706 } 707 delete vars.cycle; 708 }, 709 TweenMax = function(target, duration, vars) { 710 TweenLite.call(this, target, duration, vars); 711 this._cycle = 0; 712 this._yoyo = (this.vars.yoyo === true || !!this.vars.yoyoEase); 713 this._repeat = this.vars.repeat || 0; 714 this._repeatDelay = this.vars.repeatDelay || 0; 715 if (this._repeat) { 716 this._uncache(true); //ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it. 717 } 718 this.render = TweenMax.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method) 719 }, 720 _tinyNum = 0.0000000001, 721 TweenLiteInternals = TweenLite._internals, 722 _isSelector = TweenLiteInternals.isSelector, 723 _isArray = TweenLiteInternals.isArray, 724 p = TweenMax.prototype = TweenLite.to({}, 0.1, {}), 725 _blankArray = []; 726 727 TweenMax.version = "1.20.5"; 728 p.constructor = TweenMax; 729 p.kill()._gc = false; 730 TweenMax.killTweensOf = TweenMax.killDelayedCallsTo = TweenLite.killTweensOf; 731 TweenMax.getTweensOf = TweenLite.getTweensOf; 732 TweenMax.lagSmoothing = TweenLite.lagSmoothing; 733 TweenMax.ticker = TweenLite.ticker; 734 TweenMax.render = TweenLite.render; 735 736 p.invalidate = function() { 737 this._yoyo = (this.vars.yoyo === true || !!this.vars.yoyoEase); 738 this._repeat = this.vars.repeat || 0; 739 this._repeatDelay = this.vars.repeatDelay || 0; 740 this._yoyoEase = null; 741 this._uncache(true); 742 return TweenLite.prototype.invalidate.call(this); 743 }; 744 745 p.updateTo = function(vars, resetDuration) { 746 var curRatio = this.ratio, 747 immediate = this.vars.immediateRender || vars.immediateRender, 748 p; 749 if (resetDuration && this._startTime < this._timeline._time) { 750 this._startTime = this._timeline._time; 751 this._uncache(false); 752 if (this._gc) { 753 this._enabled(true, false); 754 } else { 755 this._timeline.insert(this, this._startTime - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct. 756 } 757 } 758 for (p in vars) { 759 this.vars[p] = vars[p]; 760 } 761 if (this._initted || immediate) { 762 if (resetDuration) { 763 this._initted = false; 764 if (immediate) { 765 this.render(0, true, true); 766 } 767 } else { 768 if (this._gc) { 769 this._enabled(true, false); 770 } 771 if (this._notifyPluginsOfEnabled && this._firstPT) { 772 TweenLite._onPluginEvent("_onDisable", this); //in case a plugin like MotionBlur must perform some cleanup tasks 773 } 774 if (this._time / this._duration > 0.998) { //if the tween has finished (or come extremely close to finishing), we just need to rewind it to 0 and then render it again at the end which forces it to re-initialize (parsing the new vars). We allow tweens that are close to finishing (but haven't quite finished) to work this way too because otherwise, the values are so small when determining where to project the starting values that binary math issues creep in and can make the tween appear to render incorrectly when run backwards. 775 var prevTime = this._totalTime; 776 this.render(0, true, false); 777 this._initted = false;
778 this.render(prevTime, true, false); 779 } else { 780 this._initted = false; 781 this._init(); 782 if (this._time > 0 || immediate) { 783 var inv = 1 / (1 - curRatio), 784 pt = this._firstPT, endValue; 785 while (pt) { 786 endValue = pt.s + pt.c; 787 pt.c *= inv; 788 pt.s = endValue - pt.c; 789 pt = pt._next; 790 } 791 } 792 } 793 } 794 } 795 return this; 796 }; 797 798 p.render = function(time, suppressEvents, force) { 799 if (!this._initted) if (this._duration === 0 && this.vars.repeat) { //zero duration tweens that render immediately have render() called from TweenLite's constructor, before TweenMax's constructor has finished setting _repeat, _repeatDelay, and _yoyo which are critical in determining totalDuration() so we need to call invalidate() which is a low-kb way to get those set properly. 800 this.invalidate(); 801 } 802 var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), 803 prevTime = this._time, 804 prevTotalTime = this._totalTime, 805 prevCycle = this._cycle, 806 duration = this._duration, 807 prevRawPrevTime = this._rawPrevTime, 808 isComplete, callback, pt, cycleDuration, r, type, pow, rawPrevTime, yoyoEase; 809 if (time >= totalDur - 0.0000001 && time >= 0) { //to work around occasional floating point math artifacts. 810 this._totalTime = totalDur; 811 this._cycle = this._repeat; 812 if (this._yoyo && (this._cycle & 1) !== 0) { 813 this._time = 0; 814 this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0; 815 } else { 816 this._time = duration; 817 this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1; 818 } 819 if (!this._reversed) { 820 isComplete = true; 821 callback = "onComplete"; 822 force = (force || this._timeline.autoRemoveChildren); //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 823 } 824 if (duration === 0) if (this._initted || !this.vars.lazy || force) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 825 if (this._startTime === this._timeline._duration) { //if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent rounding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate. 826 time = 0; 827 } 828 if (prevRawPrevTime < 0 || (time <= 0 && time >= -0.0000001) || (prevRawPrevTime === _tinyNum && this.data !== "isPause")) if (prevRawPrevTime !== time) { //note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause. 829 force = true; 830 if (prevRawPrevTime > _tinyNum) { 831 callback = "onReverseComplete"; 832 } 833 } 834 this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 835 } 836 837 } else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0. 838 this._totalTime = this._time = this._cycle = 0; 839 this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0; 840 if (prevTotalTime !== 0 || (duration === 0 && prevRawPrevTime > 0)) { 841 callback = "onReverseComplete"; 842 isComplete = this._reversed; 843 } 844 if (time < 0) { 845 this._active = false;
846 if (duration === 0) if (this._initted || !this.vars.lazy || force) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 847 if (prevRawPrevTime >= 0) { 848 force = true; 849 } 850 this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 851 } 852 } 853 if (!this._initted) { //if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. 854 force = true; 855 } 856 } else { 857 this._totalTime = this._time = time; 858 if (this._repeat !== 0) { 859 cycleDuration = duration + this._repeatDelay; 860 this._cycle = (this._totalTime / cycleDuration) >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) 861 if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) { 862 this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning) 863 } 864 this._time = this._totalTime - (this._cycle * cycleDuration); 865 if (this._yoyo) if ((this._cycle & 1) !== 0) { 866 this._time = duration - this._time; 867 yoyoEase = this._yoyoEase || this.vars.yoyoEase; //note: we don't set this._yoyoEase in _init() like we do other properties because it's TweenMax-specific and doing it here allows us to optimize performance (most tweens don't have a yoyoEase). Note that we also must skip the this.ratio calculation further down right after we _init() in this function, because we're doing it here. 868 if (yoyoEase) { 869 if (!this._yoyoEase) { 870 if (yoyoEase === true && !this._initted) { //if it's not initted and yoyoEase is true, this._ease won't have been populated yet so we must discern it here. 871 yoyoEase = this.vars.ease; 872 this._yoyoEase = yoyoEase = !yoyoEase ? TweenLite.defaultEase : (yoyoEase instanceof Ease) ? yoyoEase : (typeof(yoyoEase) === "function") ? new Ease(yoyoEase, this.vars.easeParams) : Ease.map[yoyoEase] || TweenLite.defaultEase; 873 } else { 874 this._yoyoEase = yoyoEase = (yoyoEase === true) ? this._ease : (yoyoEase instanceof Ease) ? yoyoEase : Ease.map[yoyoEase]; 875 } 876 } 877 this.ratio = yoyoEase ? 1 - yoyoEase.getRatio((duration - this._time) / duration) : 0; 878 } 879 } 880 if (this._time > duration) { 881 this._time = duration; 882 } else if (this._time < 0) { 883 this._time = 0; 884 } 885 } 886 if (this._easeType && !yoyoEase) { 887 r = this._time / duration; 888 type = this._easeType; 889 pow = this._easePower; 890 if (type === 1 || (type === 3 && r >= 0.5)) { 891 r = 1 - r; 892 } 893 if (type === 3) { 894 r *= 2; 895 } 896 if (pow === 1) { 897 r *= r; 898 } else if (pow === 2) { 899 r *= r * r; 900 } else if (pow === 3) { 901 r *= r * r * r; 902 } else if (pow === 4) { 903 r *= r * r * r * r; 904 } 905 906 if (type === 1) { 907 this.ratio = 1 - r; 908 } else if (type === 2) { 909 this.ratio = r; 910 } else if (this._time / duration < 0.5) { 911 this.ratio = r / 2; 912 } else { 913 this.ratio = 1 - (r / 2); 914 } 915 916 } else if (!yoyoEase) { 917 this.ratio = this._ease.getRatio(this._time / duration); 918 } 919 920 } 921 922 if (prevTime === this._time && !force && prevCycle === this._cycle) { 923 if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) { //so that onUp
923date fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate. 924 this._callback("onUpdate"); 925 } 926 return; 927 } else if (!this._initted) { 928 this._init(); 929 if (!this._initted || this._gc) { //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that overwriting occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example. 930 return; 931 } else if (!force && this._firstPT && ((this.vars.lazy !== false && this._duration) || (this.vars.lazy && !this._duration))) { //we stick it in the queue for rendering at the very end of the tick - this is a performance optimization because browsers invalidate styles and force a recalculation if you read, write, and then read style data (so it's better to read/read/read/write/write/write than read/write/read/write/read/write). The down side, of course, is that usually you WANT things to render immediately because you may have code running right after that which depends on the change. Like imagine running TweenLite.set(...) and then immediately after that, creating a nother tween that animates the same property to another value; the starting values of that 2nd tween wouldn't be accurate if lazy is true. 932 this._time = prevTime; 933 this._totalTime = prevTotalTime; 934 this._rawPrevTime = prevRawPrevTime; 935 this._cycle = prevCycle; 936 TweenLiteInternals.lazyTweens.push(this); 937 this._lazy = [time, suppressEvents]; 938 return; 939 } 940 //_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently. 941 if (this._time && !isComplete && !yoyoEase) { 942 this.ratio = this._ease.getRatio(this._time / duration); 943 } else if (isComplete && this._ease._calcEnd && !yoyoEase) { 944 this.ratio = this._ease.getRatio((this._time === 0) ? 0 : 1); 945 } 946 } 947 if (this._lazy !== false) { 948 this._lazy = false; 949 } 950 951 if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) { 952 this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. 953 } 954 if (prevTotalTime === 0) { 955 if (this._initted === 2 && time > 0) { 956 //this.invalidate(); 957 this._init(); //will just apply overwriting since _initted of (2) means it was a from() tween that had immediateRender:true 958 } 959 if (this._startAt) { 960 if (time >= 0) { 961 this._startAt.render(time, true, force); 962 } else if (!callback) { 963 callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area. 964 } 965 } 966 if (this.vars.onStart) if (this._totalTime !== 0 || duration === 0) if (!suppressEvents) { 967 this._callback("onStart"); 968 } 969 } 970 971 pt = this._firstPT; 972 while (pt) { 973 if (pt.f) { 974 pt.t[pt.p](pt.c * this.ratio + pt.s); 975 } else { 976 pt.t[pt.p] = pt.c * this.ratio + pt.s; 977 } 978 pt = pt._next; 979 } 980 981 if (this._onUpdate) { 982 if (time < 0) if (this._startAt && this._startTime) { //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values. 983 this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete. 984 } 985 if (!suppressEvents) if (this._totalTime !== prevTotalTime || callback) {
986 this._callback("onUpdate"); 987 } 988 } 989 if (this._cycle !== prevCycle) if (!suppressEvents) if (!this._gc) if (this.vars.onRepeat) { 990 this._callback("onRepeat"); 991 } 992 if (callback) if (!this._gc || force) { //check gc because there's a chance that kill() could be called in an onUpdate 993 if (time < 0 && this._startAt && !this._onUpdate && this._startTime) { //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values. 994 this._startAt.render(time, true, force); 995 } 996 if (isComplete) { 997 if (this._timeline.autoRemoveChildren) { 998 this._enabled(false, false); 999 } 1000 this._active = false; 1001 } 1002 if (!suppressEvents && this.vars[callback]) { 1003 this._callback(callback); 1004 } 1005 if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { //the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon sce
1005nario, but possible nonetheless. 1006 this._rawPrevTime = 0; 1007 } 1008 } 1009 }; 1010 1011//---- STATIC FUNCTIONS ----------------------------------------------------------------------------------------------------------- 1012 1013 TweenMax.to = function(target, duration, vars) { 1014 return new TweenMax(target, duration, vars); 1015 }; 1016 1017 TweenMax.from = function(target, duration, vars) { 1018 vars.runBackwards = true; 1019 vars.immediateRender = (vars.immediateRender != false); 1020 return new TweenMax(target, duration, vars); 1021 }; 1022 1023 TweenMax.fromTo = function(target, duration, fromVars, toVars) { 1024 toVars.startAt = fromVars; 1025 toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false); 1026 return new TweenMax(target, duration, toVars); 1027 }; 1028 1029 TweenMax.staggerTo = TweenMax.allTo = function(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 1030 stagger = stagger || 0; 1031 var delay = 0, 1032 a = [], 1033 finalComplete = function() { 1034 if (vars.onComplete) { 1035 vars.onComplete.apply(vars.onCompleteScope || this, arguments); 1036 } 1037 onCompleteAll.apply(onCompleteAllScope || vars.callbackScope || this, onCompleteAllParams || _blankArray); 1038 }, 1039 cycle = vars.cycle, 1040 fromCycle = (vars.startAt && vars.startAt.cycle), 1041 l, copy, i, p; 1042 if (!_isArray(targets)) { 1043 if (typeof(targets) === "string") { 1044 targets = TweenLite.selector(targets) || targets; 1045 } 1046 if (_isSelector(targets)) { 1047 targets = _slice(targets); 1048 } 1049 } 1050 targets = targets || []; 1051 if (stagger < 0) { 1052 targets = _slice(targets); 1053 targets.reverse(); 1054 stagger *= -1; 1055 } 1056 l = targets.length - 1; 1057 for (i = 0; i <= l; i++) { 1058 copy = {}; 1059 for (p in vars) { 1060 copy[p] = vars[p]; 1061 } 1062 if (cycle) { 1063 _applyCycle(copy, targets, i); 1064 if (copy.duration != null) { 1065 duration = copy.duration; 1066 delete copy.duration; 1067 } 1068 } 1069 if (fromCycle) { 1070 fromCycle = copy.startAt = {}; 1071 for (p in vars.startAt) { 1072 fromCycle[p] = vars.startAt[p]; 1073 } 1074 _applyCycle(copy.startAt, targets, i); 1075 } 1076 copy.delay = delay + (copy.delay || 0); 1077 if (i === l && onCompleteAll) { 1078 copy.onComplete = finalComplete; 1079 } 1080 a[i] = new TweenMax(targets[i], duration, copy); 1081 delay += stagger; 1082 } 1083 return a; 1084 }; 1085 1086 TweenMax.staggerFrom = TweenMax.allFrom = function(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 1087 vars.runBackwards = true; 1088 vars.immediateRender = (vars.immediateRender != false); 1089 return TweenMax.staggerTo(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 1090 }; 1091 1092 TweenMax.staggerFromTo = TweenMax.allFromTo = function(targets, duration, fromVars, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 1093 toVars.startAt = fromVars; 1094 toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false); 1095 return TweenMax.staggerTo(targets, duration, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 1096 }; 1097 1098 TweenMax.delayedCall = function(delay, callback, params, scope, useFrames) { 1099 return new TweenMax(callback, 0, {delay:delay, onComplete:callback, onCompleteParams:params, callbackScope:scope, onReverseComplete:callback, onReverseCompleteParams:params, immediateRender:false, useFrames:useFrames, overwrite:0}); 1100 }; 1101 1102 TweenMax.set = function(target, vars) { 1103 return new TweenMax(target, 0, vars); 1104 }; 1105 1106 TweenMax.isTweening = function(target) { 1107 return (TweenLite.getTweensOf(target, true).length > 0); 1108 }; 1109 1110 var _getChildrenOf = function(timeline, includeTimelines) { 1111 var a = [], 1112 cnt = 0, 1113 tween = timeline._first; 1114 while (tween) { 1115 if (tween instanceof TweenLite) { 1116 a[cnt++] = tween; 1117 } else { 1118 if (includeTimelines) { 1119 a[cnt++] = tween; 1120 } 1121 a = a.concat(_getChildrenOf(tween, includeTimelines)); 1122 cnt = a.length; 1123 } 1124 tween = tween._next; 1125 } 1126 return a; 1127 }, 1128 getAllTweens = TweenMax.getAllTweens = function(includeTimelines) { 1129 return _getChildrenOf(Animation._rootTimeline, includeTimelines).concat( _getChildrenOf(Animation._rootFramesTimeline, includeTimelines) ); 1130 }; 1131 1132 TweenMax.killAll = function(complete, tweens, delayedCalls, timelines) { 1133 if (tweens == null) { 1134 tweens = true; 1135 } 1136 if (delayedCalls == null) { 1137 delayedCalls = true; 1138 } 1139 var a = getAllTweens((timelines != false)), 1140 l = a.length, 1141 allTrue = (tweens && delayedCalls && timelines), 1142 isDC, tween, i; 1143 for (i = 0; i < l; i++) { 1144 tween = a[i]; 1145 if (allTrue || (tween instanceof SimpleTimeline) || ((isDC = (tween.target === tween.vars.onComplete)) && delayedCalls) || (tweens && !isDC)) { 1146 if (complete) { 1147 tween.totalTime(tween._reversed ? 0 : tween.totalDuration()); 1148 } else { 1149 tween._enabled(false, false); 1150 } 1151 } 1152 } 1153 }; 1154 1155 TweenMax.killChildTweensOf = function(parent, complete) { 1156 if (parent == null) { 1157 return; 1158 } 1159 var tl = TweenLiteInternals.tweenLookup, 1160 a, curParent, p, i, l; 1161 if (typeof(parent) === "string") { 1162 parent = TweenLite.selector(parent) || parent; 1163 } 1164 if (_isSelector(parent)) { 1165 parent = _slice(parent); 1166 } 1167 if (_isArray(parent)) { 1168 i = parent.length; 1169 while (--i > -1) { 1170 TweenMax.killChildTweensOf(parent[i], complete); 1171 } 1172 return; 1173 } 1174 a = []; 1175 for (p in tl) { 1176 curParent = tl[p].target.parentNode; 1177 while (curParent) { 1178 if (curParent === parent) { 1179 a = a.concat(tl[p].tweens); 1180 } 1181 curParent = curParent.parentNode; 1182 } 1183 } 1184 l = a.length; 1185 for (i = 0; i < l; i++) { 1186 if (complete) { 1187 a[i].totalTime(a[i].totalDuration()); 1188 } 1189 a[i]._enabled(false, false); 1190 } 1191 }; 1192 1193 var _changePause = function(pause, tweens, delayedCalls, timelines) { 1194 tweens = (tweens !== false); 1195 delayedCalls = (delayedCalls !== false); 1196 timelines = (timelines !== false); 1197 var a = getAllTweens(timelines), 1198 allTrue = (tweens && delayedCalls && timelines), 1199 i = a.length, 1200 isDC, tween; 1201 while (--i > -1) { 1202 tween = a[i]; 1203 if (allTrue || (tween instanceof SimpleTimeline) || ((isDC = (tween.target === tween.vars.onComplete)) && delayedCalls) || (tweens && !isDC)) { 1204 tween.paused(pause); 1205 } 1206 } 1207 }; 1208 1209 TweenMax.pauseAll = function(tweens, delayedCalls, timelines) { 1210 _changePause(true, tweens, delayedCalls, timelines); 1211 }; 1212
1213 TweenMax.resumeAll = function(tweens, delayedCalls, timelines) { 1214 _changePause(false, tweens, delayedCalls, timelines); 1215 }; 1216 1217 TweenMax.globalTimeScale = function(value) { 1218 var tl = Animation._rootTimeline, 1219 t = TweenLite.ticker.time; 1220 if (!arguments.length) { 1221 return tl._timeScale; 1222 } 1223 value = value || _tinyNum; //can't allow zero because it'll throw the math off 1224 tl._startTime = t - ((t - tl._startTime) * tl._timeScale / value); 1225 tl = Animation._rootFramesTimeline; 1226 t = TweenLite.ticker.frame; 1227 tl._startTime = t - ((t - tl._startTime) * tl._timeScale / value); 1228 tl._timeScale = Animation._rootTimeline._timeScale = value; 1229 return value; 1230 }; 1231 1232 1233//---- GETTERS / SETTERS ---------------------------------------------------------------------------------------------------------- 1234 1235 p.progress = function(value, suppressEvents) { 1236 return (!arguments.length) ? this._time / this.duration() : this.totalTime( this.duration() * ((this._yoyo && (this._cycle & 1) !== 0) ? 1 - value : value) + (this._cycle * (this._duration + this._repeatDelay)), suppressEvents); 1237 }; 1238 1239 p.totalProgress = function(value, suppressEvents) { 1240 return (!arguments.length) ? this._totalTime / this.totalDuration() : this.totalTime( this.totalDuration() * value, suppressEvents); 1241 }; 1242 1243 p.time = function(value, suppressEvents) { 1244 if (!arguments.length) { 1245 return this._time; 1246 } 1247 if (this._dirty) { 1248 this.totalDuration(); 1249 } 1250 if (value > this._duration) { 1251 value = this._duration; 1252 } 1253 if (this._yoyo && (this._cycle & 1) !== 0) { 1254 value = (this._duration - value) + (this._cycle * (this._duration + this._repeatDelay)); 1255 } else if (this._repeat !== 0) { 1256 value += this._cycle * (this._duration + this._repeatDelay); 1257 } 1258 return this.totalTime(value, suppressEvents); 1259 }; 1260 1261 p.duration = function(value) { 1262 if (!arguments.length) { 1263 return this._duration; //don't set _dirty = false because there could be repeats that haven't been factored into the _totalDuration yet. Otherwise, if you create a repeated TweenMax and then immediately check its duration(), it would cache the value and the totalDuration would not be correct, thus repeats wouldn't take effect. 1264 } 1265 return Animation.prototype.duration.call(this, value); 1266 }; 1267 1268 p.totalDuration = function(value) { 1269 if (!arguments.length) { 1270 if (this._dirty) { 1271 //instead of Infinity, we use 999999999999 so that we can accommodate reverses 1272 this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat); 1273 this._dirty = false; 1274 } 1275 return this._totalDuration; 1276 } 1277 return (this._repeat === -1) ? this : this.duration( (value - (this._repeat * this._repeatDelay)) / (this._repeat + 1) ); 1278 }; 1279 1280 p.repeat = function(value) { 1281 if (!arguments.length) { 1282 return this._repeat; 1283 } 1284 this._repeat = value; 1285 return this._uncache(true); 1286 }; 1287 1288 p.repeatDelay = function(value) { 1289 if (!arguments.length) { 1290 return this._repeatDelay; 1291 } 1292 this._repeatDelay = value; 1293 return this._uncache(true); 1294 }; 1295 1296 p.yoyo = function(value) { 1297 if (!arguments.length) { 1298 return this._yoyo; 1299 } 1300 this._yoyo = value; 1301 return this; 1302 }; 1303 1304 1305 return TweenMax; 1306 1307 }, true); 1308 1309 1310 1311 1312 1313 1314 1315 1316/* 1317 * ---------------------------------------------------------------- 1318 * TimelineLite 1319 * ---------------------------------------------------------------- 1320 */ 1321 _gsScope._gsDefine("TimelineLite", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) { 1322 1323 var TimelineLite = function(vars) { 1324 SimpleTimeline.call(this, vars); 1325 this._labels = {}; 1326 this.autoRemoveChildren = (this.vars.autoRemoveChildren === true); 1327 this.smoothChildTiming = (this.vars.smoothChildTiming === true); 1328 this._sortChildren = true; 1329 this._onUpdate = this.vars.onUpdate; 1330 var v = this.vars, 1331 val, p; 1332 for (p in v) { 1333 val = v[p]; 1334 if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) { 1335 v[p] = this._swapSelfInParams(val); 1336 } 1337 } 1338 if (_isArray(v.tweens)) { 1339 this.add(v.tweens, 0, v.align, v.stagger); 1340 } 1341 }, 1342 _tinyNum = 0.0000000001, 1343 TweenLiteInternals = TweenLite._internals, 1344 _internals = TimelineLite._internals = {}, 1345 _isSelector = TweenLiteInternals.isSelector, 1346 _isArray = TweenLiteInternals.isArray, 1347 _lazyTweens = TweenLiteInternals.lazyTweens, 1348 _lazyRender = TweenLiteInternals.lazyRender, 1349 _globals = _gsScope._gsDefine.globals, 1350 _copy = function(vars) { 1351 var copy = {}, p; 1352 for (p in vars) { 1353 copy[p] = vars[p]; 1354 } 1355 return copy; 1356 }, 1357 _applyCycle = function(vars, targets, i) { 1358 var alt = vars.cycle, 1359 p, val; 1360 for (p in alt) { 1361 val = alt[p]; 1362 vars[p] = (typeof(val) === "function") ? val(i, targets[i]) : val[i % val.length]; 1363 } 1364 delete vars.cycle; 1365 }, 1366 _pauseCallback = _internals.pauseCallback = function() {}, 1367 _slice = function(a) { //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 1368 var b = [], 1369 l = a.length, 1370 i; 1371 for (i = 0; i !== l; b.push(a[i++])); 1372 return b; 1373 }, 1374 p = TimelineLite.prototype = new SimpleTimeline(); 1375
1376 TimelineLite.version = "1.20.4"; 1377 p.constructor = TimelineLite; 1378 p.kill()._gc = p._forcingPlayhead = p._hasPause = false; 1379 1380 /* might use later... 1381 //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales. 1382 function localToGlobal(time, animation) { 1383 while (animation) { 1384 time = (time / animation._timeScale) + animation._startTime; 1385 animation = animation.timeline; 1386 } 1387 return time; 1388 } 1389 1390 //translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales 1391 function globalToLocal(time, animation) { 1392 var scale = 1; 1393 time -= localToGlobal(0, animation); 1394 while (animation) { 1395 scale *= animation._timeScale; 1396 animation = animation.timeline; 1397 } 1398 return time * scale; 1399 } 1400 */ 1401 1402 p.to = function(target, duration, vars, position) { 1403 var Engine = (vars.repeat && _globals.TweenMax) || TweenLite; 1404 return duration ? this.add( new Engine(target, duration, vars), position) : this.set(target, vars, position); 1405 }; 1406 1407 p.from = function(target, duration, vars, position) { 1408 return this.add( ((vars.repeat && _globals.TweenMax) || TweenLite).from(target, duration, vars), position); 1409 }; 1410 1411 p.fromTo = function(target, duration, fromVars, toVars, position) { 1412 var Engine = (toVars.repeat && _globals.TweenMax) || TweenLite; 1413 return duration ? this.add( Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position); 1414 }; 1415 1416 p.staggerTo = function(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 1417 var tl = new TimelineLite({onComplete:onCompleteAll, onCompleteParams:onCompleteAllParams, callbackScope:onCompleteAllScope, smoothChildTiming:this.smoothChildTiming}), 1418 cycle = vars.cycle, 1419 copy, i; 1420 if (typeof(targets) === "string") { 1421 targets = TweenLite.selector(targets) || targets; 1422 } 1423 targets = targets || []; 1424 if (_isSelector(targets)) { //senses if the targets object is a selector. If it is, we should translate it into an array. 1425 targets = _slice(targets); 1426 } 1427 stagger = stagger || 0; 1428 if (stagger < 0) { 1429 targets = _slice(targets); 1430 targets.reverse(); 1431 stagger *= -1; 1432 } 1433 for (i = 0; i < targets.length; i++) { 1434 copy = _copy(vars); 1435 if (copy.startAt) { 1436 copy.startAt = _copy(copy.startAt); 1437 if (copy.startAt.cycle) { 1438 _applyCycle(copy.startAt, targets, i); 1439 } 1440 } 1441 if (cycle) { 1442 _applyCycle(copy, targets, i); 1443 if (copy.duration != null) { 1444 duration = copy.duration; 1445 delete copy.duration; 1446 } 1447 } 1448 tl.to(targets[i], duration, copy, i * stagger); 1449 } 1450 return this.add(tl, position); 1451 }; 1452 1453 p.staggerFrom = function(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 1454 vars.immediateRender = (vars.immediateRender != false); 1455 vars.runBackwards = true; 1456 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 1457 }; 1458 1459 p.staggerFromTo = function(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 1460 toVars.startAt = fromVars; 1461 toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false); 1462 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 1463 }; 1464 1465 p.call = function(callback, params, scope, position) { 1466 return this.add( TweenLite.delayedCall(0, callback, params, scope), position); 1467 }; 1468 1469 p.set = function(target, vars, position) { 1470 position = this._parseTimeOrLabel(position, 0, true); 1471 if (vars.immediateRender == null) { 1472 vars.immediateRender = (position === this._time && !this._paused); 1473 } 1474 return this.add( new TweenLite(target, 0, vars), position); 1475 }; 1476 1477 TimelineLite.exportRoot = function(vars, ignoreDelayedCalls) { 1478 vars = vars || {}; 1479 if (vars.smoothChildTiming == null) { 1480 vars.smoothChildTiming = true; 1481 } 1482 var tl = new TimelineLite(vars), 1483 root = tl._timeline, 1484 hasNegativeStart, time, tween, next; 1485 if (ignoreDelayedCalls == null) { 1486 ignoreDelayedCalls = true; 1487 } 1488 root._remove(tl, true); 1489 tl._startTime = 0; 1490 tl._rawPrevTime = tl._time = tl._totalTime = root._time; 1491 tween = root._first; 1492 while (tween) { 1493 next = tween._next; 1494 if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) { 1495 time = tween._startTime - tween._delay; 1496 if (time < 0) { 1497 hasNegativeStart = 1; 1498 } 1499 tl.add(tween, time); 1500 } 1501 tween = next; 1502 } 1503 root.add(tl, 0); 1504 if (hasNegativeStart) { //calling totalDuration() will force the adjustment necessary to shift the children forward so none of them start before zero, and moves the timeline backwards the same amount, so the playhead is still aligned where it should be globally, but the timeline doesn't have illegal children that start before zero. 1505 tl.totalDuration(); 1506 } 1507 return tl; 1508 }; 1509 1510 p.add = function(value, position, align, stagger) { 1511 var curTime, l, i, child, tl, beforeRawTime; 1512 if (typeof(position) !== "number") { 1513 position = this._parseTimeOrLabel(position, 0, true, value); 1514 } 1515 if (!(value instanceof Animation)) { 1516 if ((value instanceof Array) || (value && value.push && _isArray(value))) {
1517 align = align || "normal"; 1518 stagger = stagger || 0; 1519 curTime = position; 1520 l = value.length; 1521 for (i = 0; i < l; i++) { 1522 if (_isArray(child = value[i])) { 1523 child = new TimelineLite({tweens:child}); 1524 } 1525 this.add(child, curTime); 1526 if (typeof(child) !== "string" && typeof(child) !== "function") { 1527 if (align === "sequence") { 1528 curTime = child._startTime + (child.totalDuration() / child._timeScale); 1529 } else if (align === "start") { 1530 child._startTime -= child.delay(); 1531 } 1532 } 1533 curTime += stagger; 1534 } 1535 return this._uncache(true); 1536 } else if (typeof(value) === "string") { 1537 return this.addLabel(value, position); 1538 } else if (typeof(value) === "function") { 1539 value = TweenLite.delayedCall(0, value); 1540 } else { 1541 throw("Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string."); 1542 } 1543 } 1544 1545 SimpleTimeline.prototype.add.call(this, value, position); 1546 1547 if (value._time) { //in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning. 1548 value.render((this.rawTime() - value._startTime) * value._timeScale, false, false); 1549 } 1550 1551 //if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate. 1552 if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) { 1553 //in case any of the ancestors had completed but should now be enabled... 1554 tl = this; 1555 beforeRawTime = (tl.rawTime() > value._startTime); //if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect. 1556 while (tl._timeline) { 1557 if (beforeRawTime && tl._timeline.smoothChildTiming) { 1558 tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it. 1559 } else if (tl._gc) { 1560 tl._enabled(true, false); 1561 } 1562 tl = tl._timeline; 1563 } 1564 } 1565 1566 return this; 1567 }; 1568 1569 p.remove = function(value) { 1570 if (value instanceof Animation) { 1571 this._remove(value, false); 1572 var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline; //now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline. 1573 value._startTime = (value._paused ? value._pauseTime : tl._time) - ((!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale); //ensure that if it gets played again, the timing is correct. 1574 return this; 1575 } else if (value instanceof Array || (value && value.push && _isArray(value))) { 1576 var i = value.length; 1577 while (--i > -1) { 1578 this.remove(value[i]); 1579 } 1580 return this; 1581 } else if (typeof(value) === "string") { 1582 return this.removeLabel(value); 1583 } 1584 return this.kill(null, value); 1585 }; 1586 1587 p._remove = function(tween, skipDisable) { 1588 SimpleTimeline.prototype._remove.call(this, tween, skipDisable); 1589 var last = this._last; 1590 if (!last) { 1591 this._time = this._totalTime = this._duration = this._totalDuration = 0; 1592 } else if (this._time > this.duration()) { 1593 this._time = this._duration; 1594 this._totalTime = this._totalDuration; 1595 } 1596 return this; 1597 }; 1598 1599 p.append = function(value, offsetOrLabel) { 1600 return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value)); 1601 }; 1602 1603 p.insert = p.insertMultiple = function(value, position, align, stagger) { 1604 return this.add(value, position || 0, align, stagger); 1605 }; 1606 1607 p.appendMultiple = function(tweens, offsetOrLabel, align, stagger) { 1608 return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger); 1609 }; 1610 1611 p.addLabel = function(label, position) { 1612 this._labels[label] = this._parseTimeOrLabel(position); 1613 return this; 1614 }; 1615 1616 p.addPause = function(position, callback, params, scope) { 1617 var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this); 1618 t.vars.onComplete = t.vars.onReverseComplete = callback;
1619 t.data = "isPause"; 1620 this._hasPause = true; 1621 return this.add(t, position); 1622 }; 1623 1624 p.removeLabel = function(label) { 1625 delete this._labels[label]; 1626 return this; 1627 }; 1628 1629 p.getLabelTime = function(label) { 1630 return (this._labels[label] != null) ? this._labels[label] : -1; 1631 }; 1632 1633 p._parseTimeOrLabel = function(timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) { 1634 var clippedDuration, i; 1635 //if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration(). 1636 if (ignore instanceof Animation && ignore.timeline === this) { 1637 this.remove(ignore); 1638 } else if (ignore && ((ignore instanceof Array) || (ignore.push && _isArray(ignore)))) { 1639 i = ignore.length; 1640 while (--i > -1) { 1641 if (ignore[i] instanceof Animation && ignore[i].timeline === this) { 1642 this.remove(ignore[i]); 1643 } 1644 } 1645 } 1646 clippedDuration = (typeof(timeOrLabel) === "number" && !offsetOrLabel) ? 0 : (this.duration() > 99999999999) ? this.recent().endTime(false) : this._duration; //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead. 1647 if (typeof(offsetOrLabel) === "string") { 1648 return this._parseTimeOrLabel(offsetOrLabel, (appendIfAbsent && typeof(timeOrLabel) === "number" && this._labels[offsetOrLabel] == null) ? timeOrLabel - clippedDuration : 0, appendIfAbsent); 1649 } 1650 offsetOrLabel = offsetOrLabel || 0; 1651 if (typeof(timeOrLabel) === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) { //if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value). 1652 i = timeOrLabel.indexOf("="); 1653 if (i === -1) { 1654 if (this._labels[timeOrLabel] == null) { 1655 return appendIfAbsent ? (this._labels[timeOrLabel] = clippedDuration + offsetOrLabel) : offsetOrLabel; 1656 } 1657 return this._labels[timeOrLabel] + offsetOrLabel; 1658 } 1659 offsetOrLabel = parseInt(timeOrLabel.charAt(i-1) + "1", 10) * Number(timeOrLabel.substr(i+1)); 1660 timeOrLabel = (i > 1) ? this._parseTimeOrLabel(timeOrLabel.substr(0, i-1), 0, appendIfAbsent) : clippedDuration; 1661 } else if (timeOrLabel == null) { 1662 timeOrLabel = clippedDuration; 1663 } 1664 return Number(timeOrLabel) + offsetOrLabel; 1665 }; 1666 1667 p.seek = function(position, suppressEvents) { 1668 return this.totalTime((typeof(position) === "number") ? position : this._parseTimeOrLabel(position), (suppressEvents !== false)); 1669 }; 1670 1671 p.stop = function() { 1672 return this.paused(true); 1673 }; 1674 1675 p.gotoAndPlay = function(position, suppressEvents) { 1676 return this.play(position, suppressEvents); 1677 }; 1678 1679 p.gotoAndStop = function(position, suppressEvents) { 1680 return this.pause(position, suppressEvents); 1681 }; 1682 1683 p.render = function(time, suppressEvents, force) { 1684 if (this._gc) { 1685 this._enabled(true, false); 1686 } 1687 var prevTime = this._time, 1688 totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), 1689 prevStart = this._startTime, 1690 prevTimeScale = this._timeScale, 1691 prevPaused = this._paused, 1692 tween, isComplete, next, callback, internalForce, pauseTween, curTime; 1693 if (prevTime !== this._time) { //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). 1694 time += this._time - prevTime; 1695 } 1696 if (time >= totalDur - 0.0000001 && time >= 0) { //to work around occasional floating point math artifacts. 1697 this._totalTime = this._time = totalDur; 1698 if (!this._reversed) if (!this._hasPausedChild()) { 1699 isComplete = true; 1700 callback = "onComplete"; 1701 internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 1702 if (this._duration === 0) if ((time <= 0 && time >= -0.0000001) || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) { 1703 internalForce = true; 1704 if (this._rawPrevTime > _tinyNum) { 1705 callback = "onReverseComplete"; 1706 } 1707 } 1708 } 1709 this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 1710 time = totalDur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. 1711 1712 } else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0. 1713 this._totalTime = this._time = 0; 1714 if (prevTime !== 0 || (this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || (time < 0 && this._rawPrevTime >= 0)))) { 1715 callback = "onReverseComplete"; 1716 isComplete = this._reversed; 1717 } 1718 if (time < 0) { 1719 this._active = false;
1720 if (this._timeline.autoRemoveChildren && this._reversed) { //ensures proper GC if a timeline is resumed after it's finished reversing. 1721 internalForce = isComplete = true; 1722 callback = "onReverseComplete"; 1723 } else if (this._rawPrevTime >= 0 && this._first) { //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state. 1724 internalForce = true; 1725 } 1726 this._rawPrevTime = time; 1727 } else { 1728 this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 1729 if (time === 0 && isComplete) { //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good). 1730 tween = this._first; 1731 while (tween && tween._startTime === 0) { 1732 if (!tween._duration) { 1733 isComplete = false; 1734 } 1735 tween = tween._next; 1736 } 1737 } 1738 time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline) 1739 if (!this._initted) { 1740 internalForce = true; 1741 } 1742 } 1743 1744 } else { 1745 1746 if (this._hasPause && !this._forcingPlayhead && !suppressEvents) { 1747 if (time >= prevTime) { 1748 tween = this._first; 1749 while (tween && tween._startTime <= time && !pauseTween) { 1750 if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) { 1751 pauseTween = tween; 1752 } 1753 tween = tween._next; 1754 } 1755 } else { 1756 tween = this._last; 1757 while (tween && tween._startTime >= time && !pauseTween) { 1758 if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) { 1759 pauseTween = tween; 1760 } 1761 tween = tween._prev; 1762 } 1763 } 1764 if (pauseTween) { 1765 this._time = time = pauseTween._startTime; 1766 this._totalTime = time + (this._cycle * (this._totalDuration + this._repeatDelay)); 1767 } 1768 } 1769 1770 this._totalTime = this._time = this._rawPrevTime = time; 1771 } 1772 if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) { 1773 return; 1774 } else if (!this._initted) { 1775 this._initted = true; 1776 } 1777 1778 if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) { 1779 this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. 1780 } 1781 1782 if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) { 1783 this._callback("onStart"); 1784 } 1785 1786 curTime = this._time; 1787 if (curTime >= prevTime) { 1788 tween = this._first; 1789 while (tween) { 1790 next = tween._next; //record it here because the value could change after rendering... 1791 if (curTime !== this._time || (this._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 1792 break; 1793 } else if (tween._active || (tween._startTime <= curTime && !tween._paused && !tween._gc)) { 1794 if (pauseTween === tween) { 1795 this.pause(); 1796 } 1797 if (!tween._reversed) { 1798 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 1799 } else { 1800 tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force); 1801 } 1802 } 1803 tween = next; 1804 } 1805 } else { 1806 tween = this._last; 1807 while (tween) { 1808 next = tween._prev; //record it here because the value could change after rendering... 1809 if (curTime !== this._time || (this._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 1810 break; 1811 } else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) { 1812 if (pauseTween === tween) { 1813 pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse. 1814 while (pauseTween && pauseTween.endTime() > this._time) { 1815 pauseTween.render( (pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force); 1816 pauseTween = pauseTween._prev; 1817 } 1818 pauseTween = null; 1819 this.pause(); 1820 } 1821 if (!tween._reversed) { 1822 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 1823 } else { 1824 tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force); 1825 } 1826 } 1827 tween = next; 1828 } 1829 } 1830 1831 if (this._onUpdate) if (!suppressEvents) { 1832 if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 1833 _lazyRender(); 1834 }
1835 this._callback("onUpdate"); 1836 } 1837 1838 if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate 1839 if (isComplete) { 1840 if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values. 1841 _lazyRender(); 1842 } 1843 if (this._timeline.autoRemoveChildren) { 1844 this._enabled(false, false); 1845 } 1846 this._active = false; 1847 } 1848 if (!suppressEvents && this.vars[callback]) { 1849 this._callback(callback); 1850 } 1851 } 1852 }; 1853 1854 p._hasPausedChild = function() { 1855 var tween = this._first; 1856 while (tween) { 1857 if (tween._paused || ((tween instanceof TimelineLite) && tween._hasPausedChild())) { 1858 return true; 1859 } 1860 tween = tween._next; 1861 } 1862 return false; 1863 }; 1864 1865 p.getChildren = function(nested, tweens, timelines, ignoreBeforeTime) { 1866 ignoreBeforeTime = ignoreBeforeTime || -9999999999; 1867 var a = [], 1868 tween = this._first, 1869 cnt = 0; 1870 while (tween) { 1871 if (tween._startTime < ignoreBeforeTime) { 1872 //do nothing 1873 } else if (tween instanceof TweenLite) { 1874 if (tweens !== false) { 1875 a[cnt++] = tween; 1876 } 1877 } else { 1878 if (timelines !== false) { 1879 a[cnt++] = tween; 1880 } 1881 if (nested !== false) { 1882 a = a.concat(tween.getChildren(true, tweens, timelines)); 1883 cnt = a.length; 1884 } 1885 } 1886 tween = tween._next; 1887 } 1888 return a; 1889 }; 1890 1891 p.getTweensOf = function(target, nested) { 1892 var disabled = this._gc, 1893 a = [], 1894 cnt = 0, 1895 tweens, i; 1896 if (disabled) { 1897 this._enabled(true, true); //getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here. 1898 } 1899 tweens = TweenLite.getTweensOf(target); 1900 i = tweens.length; 1901 while (--i > -1) { 1902 if (tweens[i].timeline === this || (nested && this._contains(tweens[i]))) { 1903 a[cnt++] = tweens[i]; 1904 } 1905 } 1906 if (disabled) { 1907 this._enabled(false, true); 1908 } 1909 return a; 1910 }; 1911 1912 p.recent = function() { 1913 return this._recent; 1914 }; 1915 1916 p._contains = function(tween) { 1917 var tl = tween.timeline; 1918 while (tl) { 1919 if (tl === this) { 1920 return true; 1921 } 1922 tl = tl.timeline; 1923 } 1924 return false; 1925 }; 1926 1927 p.shiftChildren = function(amount, adjustLabels, ignoreBeforeTime) { 1928 ignoreBeforeTime = ignoreBeforeTime || 0; 1929 var tween = this._first, 1930 labels = this._labels, 1931 p; 1932 while (tween) { 1933 if (tween._startTime >= ignoreBeforeTime) { 1934 tween._startTime += amount; 1935 } 1936 tween = tween._next; 1937 }
1938 if (adjustLabels) { 1939 for (p in labels) { 1940 if (labels[p] >= ignoreBeforeTime) { 1941 labels[p] += amount; 1942 } 1943 } 1944 } 1945 return this._uncache(true); 1946 }; 1947 1948 p._kill = function(vars, target) { 1949 if (!vars && !target) { 1950 return this._enabled(false, false); 1951 } 1952 var tweens = (!target) ? this.getChildren(true, true, false) : this.getTweensOf(target), 1953 i = tweens.length, 1954 changed = false; 1955 while (--i > -1) { 1956 if (tweens[i]._kill(vars, target)) { 1957 changed = true; 1958 } 1959 } 1960 return changed; 1961 }; 1962 1963 p.clear = function(labels) { 1964 var tweens = this.getChildren(false, true, true), 1965 i = tweens.length; 1966 this._time = this._totalTime = 0; 1967 while (--i > -1) { 1968 tweens[i]._enabled(false, false); 1969 } 1970 if (labels !== false) { 1971 this._labels = {}; 1972 } 1973 return this._uncache(true); 1974 }; 1975 1976 p.invalidate = function() { 1977 var tween = this._first; 1978 while (tween) { 1979 tween.invalidate(); 1980 tween = tween._next; 1981 } 1982 return Animation.prototype.invalidate.call(this);; 1983 }; 1984 1985 p._enabled = function(enabled, ignoreTimeline) { 1986 if (enabled === this._gc) { 1987 var tween = this._first; 1988 while (tween) { 1989 tween._enabled(enabled, true); 1990 tween = tween._next; 1991 } 1992 } 1993 return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline); 1994 }; 1995 1996 p.totalTime = function(time, suppressEvents, uncapped) { 1997 this._forcingPlayhead = true; 1998 var val = Animation.prototype.totalTime.apply(this, arguments); 1999 this._forcingPlayhead = false; 2000 return val; 2001 }; 2002 2003 p.duration = function(value) { 2004 if (!arguments.length) { 2005 if (this._dirty) { 2006 this.totalDuration(); //just triggers recalculation 2007 } 2008 return this._duration; 2009 } 2010 if (this.duration() !== 0 && value !== 0) { 2011 this.timeScale(this._duration / value); 2012 } 2013 return this; 2014 }; 2015 2016 p.totalDuration = function(value) { 2017 if (!arguments.length) { 2018 if (this._dirty) { 2019 var max = 0, 2020 tween = this._last, 2021 prevStart = 999999999999, 2022 prev, end; 2023 while (tween) { 2024 prev = tween._prev; //record it here in case the tween changes position in the sequence... 2025 if (tween._dirty) { 2026 tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it. 2027 } 2028 if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) { //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence 2029 this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel(). 2030 this.add(tween, tween._startTime - tween._delay); 2031 this._calculatingDuration = 0; 2032 } else { 2033 prevStart = tween._startTime; 2034 } 2035 if (tween._startTime < 0 && !tween._paused) { //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found. 2036 max -= tween._startTime; 2037 if (this._timeline.smoothChildTiming) { 2038 this._startTime += tween._startTime / this._timeScale; 2039 this._time -= tween._startTime; 2040 this._totalTime -= tween._startTime; 2041 this._rawPrevTime -= tween._startTime; 2042 } 2043 this.shiftChildren(-tween._startTime, false, -9999999999); 2044 prevStart = 0; 2045 } 2046 end = tween._startTime + (tween._totalDuration / tween._timeScale); 2047 if (end > max) { 2048 max = end; 2049 } 2050 tween = prev; 2051 } 2052 this._duration = this._totalDuration = max; 2053 this._dirty = false; 2054 } 2055 return this._totalDuration; 2056 } 2057 return (value && this.totalDuration()) ? this.timeScale(this._totalDuration / value) : this; 2058 }; 2059 2060 p.paused = function(value) { 2061 if (!value) { //if there's a pause directly at the spot from where we're unpausing, skip it. 2062 var tween = this._first, 2063 time = this._time; 2064 while (tween) { 2065 if (tween._startTime === time && tween.data === "isPause") { 2066 tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire. 2067 } 2068 tween = tween._next; 2069 } 2070 } 2071 return Animation.prototype.paused.apply(this, arguments); 2072 }; 2073 2074 p.usesFrames = function() { 2075 var tl = this._timeline; 2076 while (tl._timeline) { 2077 tl = tl._timeline; 2078 } 2079 return (tl === Animation._rootFramesTimeline); 2080 }; 2081 2082 p.rawTime = function(wrapRepeats) { 2083 return (wrapRepeats && (this._paused || (this._repeat && this.time() > 0 && this.totalProgress() < 1))) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale; 2084 }; 2085 2086 return TimelineLite; 2087 2088 }, true); 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102/* 2103 * ---------------------------------------------------------------- 2104 * TimelineMax 2105 * ---------------------------------------------------------------- 2106 */ 2107 _gsScope._gsDefine("TimelineMax", ["TimelineLite","TweenLite","easing.Ease"], function(TimelineLite, TweenLite, Ease) { 2108 2109 var TimelineMax = function(vars) { 2110 TimelineLite.call(this, vars); 2111 this._repeat = this.vars.repeat || 0; 2112 this._repeatDelay = this.vars.repeatDelay || 0; 2113 this._cycle = 0; 2114 this._yoyo = (this.vars.yoyo === true); 2115 this._dirty = true; 2116 }, 2117 _tinyNum = 0.0000000001, 2118 TweenLiteInternals = TweenLite._internals, 2119 _lazyTweens = TweenLiteInternals.lazyTweens, 2120 _lazyRender = TweenLiteInternals.lazyRender, 2121 _globals = _gsScope._gsDefine.globals,
2122 _easeNone = new Ease(null, null, 1, 0), 2123 p = TimelineMax.prototype = new TimelineLite(); 2124 2125 p.constructor = TimelineMax; 2126 p.kill()._gc = false; 2127 TimelineMax.version = "1.20.4"; 2128 2129 p.invalidate = function() { 2130 this._yoyo = (this.vars.yoyo === true); 2131 this._repeat = this.vars.repeat || 0; 2132 this._repeatDelay = this.vars.repeatDelay || 0; 2133 this._uncache(true); 2134 return TimelineLite.prototype.invalidate.call(this); 2135 }; 2136 2137 p.addCallback = function(callback, position, params, scope) { 2138 return this.add( TweenLite.delayedCall(0, callback, params, scope), position); 2139 }; 2140 2141 p.removeCallback = function(callback, position) { 2142 if (callback) { 2143 if (position == null) { 2144 this._kill(null, callback); 2145 } else { 2146 var a = this.getTweensOf(callback, false), 2147 i = a.length, 2148 time = this._parseTimeOrLabel(position); 2149 while (--i > -1) { 2150 if (a[i]._startTime === time) { 2151 a[i]._enabled(false, false); 2152 } 2153 } 2154 } 2155 } 2156 return this; 2157 }; 2158 2159 p.removePause = function(position) { 2160 return this.removeCallback(TimelineLite._internals.pauseCallback, position); 2161 }; 2162 2163 p.tweenTo = function(position, vars) { 2164 vars = vars || {}; 2165 var copy = {ease:_easeNone, useFrames:this.usesFrames(), immediateRender:false, lazy:false}, 2166 Engine = (vars.repeat && _globals.TweenMax) || TweenLite, 2167 duration, p, t; 2168 for (p in vars) { 2169 copy[p] = vars[p]; 2170 } 2171 copy.time = this._parseTimeOrLabel(position); 2172 duration = (Math.abs(Number(copy.time) - this._time) / this._timeScale) || 0.001; 2173 t = new Engine(this, duration, copy); 2174 copy.onStart = function() { 2175 t.target.paused(true); 2176 if (t.vars.time !== t.target.time() && duration === t.duration() && !t.isFromTo) { //don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all. 2177 t.duration( Math.abs( t.vars.time - t.target.time()) / t.target._timeScale ).render(t.time(), true, true); //render() right away to ensure that things look right, especially in the case of .tweenTo(0). 2178 } 2179 if (vars.onStart) { //in case the user had an onStart in the vars - we don't want to overwrite it. 2180 vars.onStart.apply(vars.onStartScope || vars.callbackScope || t, vars.onStartParams || []); //don't use t._callback("onStart") or it'll point to the copy.onStart and we'll get a recursion error. 2181 } 2182 }; 2183 return t; 2184 }; 2185 2186 p.tweenFromTo = function(fromPosition, toPosition, vars) { 2187 vars = vars || {}; 2188 fromPosition = this._parseTimeOrLabel(fromPosition); 2189 vars.startAt = {onComplete:this.seek, onCompleteParams:[fromPosition], callbackScope:this}; 2190 vars.immediateRender = (vars.immediateRender !== false); 2191 var t = this.tweenTo(toPosition, vars); 2192 t.isFromTo = 1; //to ensure we don't mess with the duration in the onStart (we've got the start and end values here, so lock it in) 2193 return t.duration((Math.abs( t.vars.time - fromPosition) / this._timeScale) || 0.001); 2194 }; 2195 2196 p.render = function(time, suppressEvents, force) { 2197 if (this._gc) { 2198 this._enabled(true, false); 2199 } 2200 var prevTime = this._time, 2201 totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), 2202 dur = this._duration, 2203 prevTotalTime = this._totalTime, 2204 prevStart = this._startTime, 2205 prevTimeScale = this._timeScale, 2206 prevRawPrevTime = this._rawPrevTime, 2207 prevPaused = this._paused, 2208 prevCycle = this._cycle, 2209 tween, isComplete, next, callback, internalForce, cycleDuration, pauseTween, curTime; 2210 if (prevTime !== this._time) { //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). 2211 time += this._time - prevTime; 2212 } 2213 if (time >= totalDur - 0.0000001 && time >= 0) { //to work around occasional floating point math artifacts. 2214 if (!this._locked) { 2215 this._totalTime = totalDur; 2216 this._cycle = this._repeat; 2217 } 2218 if (!this._reversed) if (!this._hasPausedChild()) { 2219 isComplete = true; 2220 callback = "onComplete"; 2221 internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 2222 if (this._duration === 0) if ((time <= 0 && time >= -0.0000001) || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && this._first) { 2223 internalForce = true; 2224 if (prevRawPrevTime > _tinyNum) { 2225 callback = "onReverseComplete"; 2226 } 2227 } 2228 } 2229 this._rawPrevTime = (this._duration || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 2230 if (this._yoyo && (this._cycle & 1) !== 0) { 2231 this._time = time = 0; 2232 } else { 2233 this._time = dur; 2234 time = dur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. We cannot do less then 0.0001 because the same issue can occur when the duration is extremely large like 999999999999 in
2234which case adding 0.00000001, for example, causes it to act like nothing was added. 2235 } 2236 2237 } else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0. 2238 if (!this._locked) { 2239 this._totalTime = this._cycle = 0; 2240 } 2241 this._time = 0; 2242 if (prevTime !== 0 || (dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || (time < 0 && prevRawPrevTime >= 0)) && !this._locked)) { //edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare) 2243 callback = "onReverseComplete"; 2244 isComplete = this._reversed; 2245 } 2246 if (time < 0) { 2247 this._active = false; 2248 if (this._timeline.autoRemoveChildren && this._reversed) { 2249 internalForce = isComplete = true; 2250 callback = "onReverseComplete"; 2251 } else if (prevRawPrevTime >= 0 && this._first) { //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state. 2252 internalForce = true; 2253 } 2254 this._rawPrevTime = time; 2255 } else { 2256 this._rawPrevTime = (dur || !suppressEvents || time || this._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 2257 if (time === 0 && isComplete) { //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good). 2258 tween = this._first; 2259 while (tween && tween._startTime === 0) { 2260 if (!tween._duration) { 2261 isComplete = false; 2262 } 2263 tween = tween._next; 2264 } 2265 } 2266 time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline) 2267 if (!this._initted) { 2268 internalForce = true; 2269 } 2270 } 2271 2272 } else { 2273 if (dur === 0 && prevRawPrevTime < 0) { //without this, zero-duration repeating timelines (like with a simple callback nested at the very beginning and a repeatDelay) wouldn't render the first time through. 2274 internalForce = true; 2275 } 2276 this._time = this._rawPrevTime = time; 2277 if (!this._locked) { 2278 this._totalTime = time; 2279 if (this._repeat !== 0) { 2280 cycleDuration = dur + this._repeatDelay; 2281 this._cycle = (this._totalTime / cycleDuration) >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but it gets reported as 0.79999999!) 2282 if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) { 2283 this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning) 2284 } 2285 this._time = this._totalTime - (this._cycle * cycleDuration); 2286 if (this._yoyo) if ((this._cycle & 1) !== 0) { 2287 this._time = dur - this._time; 2288 } 2289 if (this._time > dur) { 2290 this._time = dur; 2291 time = dur + 0.0001; //to avoid occasional floating point rounding error 2292 } else if (this._time < 0) { 2293 this._time = time = 0; 2294 } else { 2295 time = this._time; 2296 } 2297 } 2298 } 2299 2300 if (this._hasPause && !this._forcingPlayhead && !suppressEvents) { 2301 time = this._time; 2302 if (time >= prevTime || (this._repeat && prevCycle !== this._cycle)) { 2303 tween = this._first; 2304 while (tween && tween._startTime <= time && !pauseTween) { 2305 if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) { 2306 pauseTween = tween; 2307 } 2308 tween = tween._next; 2309 } 2310 } else { 2311 tween = this._last; 2312 while (tween && tween._startTime >= time && !pauseTween) { 2313 if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) { 2314 pauseTween = tween; 2315 } 2316 tween = tween._prev; 2317 } 2318 } 2319 if (pauseTween && pauseTween._startTime < dur) { 2320 this._time = time = pauseTween._startTime; 2321 this._totalTime = time + (this._cycle * (this._totalDuration + this._repeatDelay)); 2322 } 2323 } 2324 2325 } 2326 2327 if (this._cycle !== prevCycle) if (!this._locked) { 2328 /* 2329 make sure children at the end/beginning of the timeline are rendered properly. If, for example, 2330 a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
2331 would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there 2332 could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So 2333 we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must 2334 ensure that zero-duration tweens at the very beginning or end of the TimelineMax work. 2335 */ 2336 var backwards = (this._yoyo && (prevCycle & 1) !== 0), 2337 wrap = (backwards === (this._yoyo && (this._cycle & 1) !== 0)), 2338 recTotalTime = this._totalTime, 2339 recCycle = this._cycle, 2340 recRawPrevTime = this._rawPrevTime, 2341 recTime = this._time; 2342 2343 this._totalTime = prevCycle * dur; 2344 if (this._cycle < prevCycle) { 2345 backwards = !backwards; 2346 } else { 2347 this._totalTime += dur; 2348 } 2349 this._time = prevTime; //temporarily revert _time so that render() renders the children in the correct order. Without this, tweens won't rewind correctly. We could arhictect things in a "cleaner" way by splitting out the rendering queue into a separate method but for performance reasons, we kept it all inside this method. 2350 2351 this._rawPrevTime = (dur === 0) ? prevRawPrevTime - 0.0001 : prevRawPrevTime; 2352 this._cycle = prevCycle; 2353 this._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render() 2354 prevTime = (backwards) ? 0 : dur; 2355 this.render(prevTime, suppressEvents, (dur === 0)); 2356 if (!suppressEvents) if (!this._gc) { 2357 if (this.vars.onRepeat) { 2358 this._cycle = recCycle; //in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle. 2359 this._locked = false; 2360 this._callback("onRepeat"); 2361 } 2362 } 2363 if (prevTime !== this._time) { //in case there's a callback like onComplete in a nested tween/timeline that changes the playhead position, like via seek(), we should just abort. 2364 return; 2365 } 2366 if (wrap) { 2367 this._cycle = prevCycle; //if there's an onRepeat, we reverted this above, so make sure it's set properly again. We also unlocked in that scenario, so reset that too. 2368 this._locked = true; 2369 prevTime = (backwards) ? dur + 0.0001 : -0.0001; 2370 this.render(prevTime, true, false); 2371 } 2372 this._locked = false; 2373 if (this._paused && !prevPaused) { //if the render() triggered callback that paused this timeline, we should abort (very rare, but possible) 2374 return; 2375 } 2376 this._time = recTime; 2377 this._totalTime = recTotalTime; 2378 this._cycle = recCycle; 2379 this._rawPrevTime = recRawPrevTime; 2380 } 2381 2382 if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) { 2383 if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) { //so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate. 2384 this._callback("onUpdate"); 2385 } 2386 return; 2387 } else if (!this._initted) { 2388 this._initted = true; 2389 } 2390 2391 if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) { 2392 this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. 2393 } 2394 2395 if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0 || !this._totalDuration) if (!suppressEvents) { 2396 this._callback("onStart"); 2397 } 2398 2399 curTime = this._time; 2400 if (curTime >= prevTime) { 2401 tween = this._first; 2402 while (tween) { 2403 next = tween._next; //record it here because the value could change after rendering... 2404 if (curTime !== this._time || (this._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 2405 break; 2406 } else if (tween._active || (tween._startTime <= this._time && !tween._paused && !tween._gc)) { 2407 if (pauseTween === tween) { 2408 this.pause(); 2409 } 2410 if (!tween._reversed) { 2411 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 2412 } else { 2413 tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force); 2414 } 2415 } 2416 tween = next; 2417 } 2418 } else { 2419 tween = this._last; 2420 while (tween) { 2421 next = tween._prev; //record it here because the value could change after rendering... 2422 if (curTime !== this._time || (this._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 2423 break; 2424 } else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) { 2425 if (pauseTween === tween) { 2426 pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse. 2427 while (pauseTween && pauseTween.endTime() > this._time) { 2428 pauseTween.render( (pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force); 2429 pauseTween = pauseTween._prev; 2430 } 2431 pauseTween = null; 2432 this.pause(); 2433 } 2434 if (!tween._reversed) { 2435 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 2436 } else { 2437 tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force); 2438 } 2439 } 2440 tween = next; 2441 } 2442 } 2443 2444 if (this._onUpdate) if (!suppressEvents) { 2445 if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 2446 _lazyRender(); 2447 }
2448 this._callback("onUpdate"); 2449 } 2450 if (callback) if (!this._locked) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate 2451 if (isComplete) { 2452 if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values. 2453 _lazyRender(); 2454 } 2455 if (this._timeline.autoRemoveChildren) { 2456 this._enabled(false, false); 2457 } 2458 this._active = false; 2459 } 2460 if (!suppressEvents && this.vars[callback]) { 2461 this._callback(callback); 2462 } 2463 } 2464 }; 2465 2466 p.getActive = function(nested, tweens, timelines) { 2467 if (nested == null) { 2468 nested = true; 2469 } 2470 if (tweens == null) { 2471 tweens = true; 2472 } 2473 if (timelines == null) { 2474 timelines = false; 2475 } 2476 var a = [], 2477 all = this.getChildren(nested, tweens, timelines), 2478 cnt = 0, 2479 l = all.length, 2480 i, tween; 2481 for (i = 0; i < l; i++) { 2482 tween = all[i]; 2483 if (tween.isActive()) { 2484 a[cnt++] = tween; 2485 } 2486 } 2487 return a; 2488 }; 2489 2490 2491 p.getLabelAfter = function(time) { 2492 if (!time) if (time !== 0) { //faster than isNan() 2493 time = this._time; 2494 } 2495 var labels = this.getLabelsArray(), 2496 l = labels.length, 2497 i; 2498 for (i = 0; i < l; i++) { 2499 if (labels[i].time > time) { 2500 return labels[i].name; 2501 } 2502 } 2503 return null; 2504 }; 2505 2506 p.getLabelBefore = function(time) { 2507 if (time == null) { 2508 time = this._time; 2509 } 2510 var labels = this.getLabelsArray(), 2511 i = labels.length; 2512 while (--i > -1) { 2513 if (labels[i].time < time) { 2514 return labels[i].name; 2515 } 2516 } 2517 return null; 2518 }; 2519 2520 p.getLabelsArray = function() { 2521 var a = [], 2522 cnt = 0, 2523 p; 2524 for (p in this._labels) { 2525 a[cnt++] = {time:this._labels[p], name:p}; 2526 } 2527 a.sort(function(a,b) { 2528 return a.time - b.time; 2529 }); 2530 return a; 2531 }; 2532 2533 p.invalidate = function() { 2534 this._locked = false; //unlock and set cycle in case invalidate() is called from inside an onRepeat 2535 return TimelineLite.prototype.invalidate.call(this); 2536 }; 2537 2538 2539//---- GETTERS / SETTERS ------------------------------------------------------------------------------------------------------- 2540 2541 p.progress = function(value, suppressEvents) { 2542 return (!arguments.length) ? (this._time / this.duration()) || 0 : this.totalTime( this.duration() * ((this._yoyo && (this._cycle & 1) !== 0) ? 1 - value : value) + (this._cycle * (this._duration + this._repeatDelay)), suppressEvents); 2543 }; 2544 2545 p.totalProgress = function(value, suppressEvents) { 2546 return (!arguments.length) ? (this._totalTime / this.totalDuration()) || 0 : this.totalTime( this.totalDuration() * value, suppressEvents); 2547 }; 2548 2549 p.totalDuration = function(value) { 2550 if (!arguments.length) { 2551 if (this._dirty) { 2552 TimelineLite.prototype.totalDuration.call(this); //just forces refresh 2553 //Instead of Infinity, we use 999999999999 so that we can accommodate reverses. 2554 this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat); 2555 } 2556 return this._totalDuration; 2557 } 2558 return (this._repeat === -1 || !value) ? this : this.timeScale( this.totalDuration() / value ); 2559 }; 2560 2561 p.time = function(value, suppressEvents) { 2562 if (!arguments.length) { 2563 return this._time; 2564 } 2565 if (this._dirty) { 2566 this.totalDuration(); 2567 } 2568 if (value > this._duration) { 2569 value = this._duration; 2570 } 2571 if (this._yoyo && (this._cycle & 1) !== 0) { 2572 value = (this._duration - value) + (this._cycle * (this._duration + this._repeatDelay)); 2573 } else if (this._repeat !== 0) { 2574 value += this._cycle * (this._duration + this._repeatDelay); 2575 } 2576 return this.totalTime(value, suppressEvents); 2577 }; 2578 2579 p.repeat = function(value) { 2580 if (!arguments.length) { 2581 return this._repeat; 2582 } 2583 this._repeat = value; 2584 return this._uncache(true); 2585 }; 2586 2587 p.repeatDelay = function(value) { 2588 if (!arguments.length) { 2589 return this._repeatDelay; 2590 } 2591 this._repeatDelay = value; 2592 return this._uncache(true); 2593 }; 2594 2595 p.yoyo = function(value) { 2596 if (!arguments.length) { 2597 return this._yoyo; 2598 } 2599 this._yoyo = value; 2600 return this; 2601 }; 2602 2603 p.currentLabel = function(value) { 2604 if (!arguments.length) { 2605 return this.getLabelBefore(this._time + 0.00000001); 2606 } 2607 return this.seek(value, true); 2608 }; 2609 2610 return TimelineMax; 2611 2612 }, true); 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625/* 2626 * ---------------------------------------------------------------- 2627 * BezierPlugin 2628 * ---------------------------------------------------------------- 2629 */ 2630 (function() { 2631 2632 var _RAD2DEG = 180 / Math.PI, 2633 _r1 = [], 2634 _r2 = [], 2635 _r3 = [], 2636 _corProps = {}, 2637 _globals = _gsScope._gsDefine.globals, 2638 Segment = function(a, b, c, d) { 2639 if (c === d) { //if c and d match, the final autoRotate value could lock at -90 degrees, so differentiate them slightly. 2640 c = d - (d - b) / 1000000; 2641 } 2642 if (a === b) { //if a and b match, the starting autoRotate value could lock at -90 degrees, so differentiate them slightly. 2643 b = a + (c - a) / 1000000; 2644 } 2645 this.a = a; 2646 this.b = b; 2647 this.c = c; 2648 this.d = d; 2649 this.da = d - a; 2650 this.ca = c - a; 2651 this.ba = b - a; 2652 }, 2653 _correlate = ",x,y,z,left,top,right,bottom,marginTop,marginLeft,marginRight,marginBottom,paddingLeft,paddingTop,paddingRight,paddingBottom,backgroundPosition,backgroundPosition_y,", 2654 cubicToQuadratic = function(a, b, c, d) { 2655 var q1 = {a:a}, 2656 q2 = {}, 2657 q3 = {}, 2658 q4 = {c:d}, 2659 mab = (a + b) / 2, 2660 mbc = (b + c) / 2, 2661 mcd = (c + d) / 2, 2662 mabc = (mab + mbc) / 2, 2663 mbcd = (mbc + mcd) / 2, 2664 m8 = (mbcd - mabc) / 8; 2665 q1.b = mab + (a - mab) / 4; 2666 q2.b = mabc + m8; 2667 q1.c = q2.a = (q1.b + q2.b) / 2; 2668 q2.c = q3.a = (mabc + mbcd) / 2; 2669 q3.b = mbcd - m8; 2670 q4.b = mcd + (d - mcd) / 4; 2671 q3.c = q4.a = (q3.b + q4.b) / 2; 2672 return [q1, q2, q3, q4]; 2673 }, 2674 _calculateControlPoints = function(a, curviness, quad, basic, correlate) { 2675 var l = a.length - 1, 2676 ii = 0, 2677 cp1 = a[0].a, 2678 i, p1, p2, p3, seg, m1, m2, mm, cp2, qb, r1, r2, tl; 2679 for (i = 0; i < l; i++) { 2680 seg = a[ii]; 2681 p1 = seg.a; 2682 p2 = seg.d; 2683 p3 = a[ii+1].d; 2684 2685 if (correlate) { 2686 r1 = _r1[i]; 2687 r2 = _r2[i]; 2688 tl = ((r2 + r1) * curviness * 0.25) / (basic ? 0.5 : _r3[i] || 0.5); 2689 m1 = p2 - (p2 - p1) * (basic ? curviness * 0.5 : (r1 !== 0 ? tl / r1 : 0)); 2690 m2 = p2 + (p3 - p2) * (basic ? curviness * 0.5 : (r2 !== 0 ? tl / r2 : 0)); 2691 mm = p2 - (m1 + (((m2 - m1) * ((r1 * 3 / (r1 + r2)) + 0.5) / 4) || 0)); 2692 } else { 2693 m1 = p2 - (p2 - p1) * curviness * 0.5; 2694 m2 = p2 + (p3 - p2) * curviness * 0.5; 2695 mm = p2 - (m1 + m2) / 2; 2696 } 2697 m1 += mm; 2698 m2 += mm; 2699 2700 seg.c = cp2 = m1; 2701 if (i !== 0) { 2702 seg.b = cp1; 2703 } else { 2704 seg.b = cp1 = seg.a + (seg.c - seg.a) * 0.6; //instead of placing b on a exactly, we move it inline with c so that if the user specifies an ease like Back.easeIn or Elastic.easeIn which goes BEYOND the beginning, it will do so smoothly. 2705 } 2706 2707 seg.da = p2 - p1; 2708 seg.ca = cp2 - p1; 2709 seg.ba = cp1 - p1; 2710 2711 if (quad) { 2712 qb = cubicToQuadratic(p1, cp1, cp2, p2); 2713 a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]); 2714 ii += 4; 2715 } else { 2716 ii++; 2717 } 2718 2719 cp1 = m2; 2720 } 2721 seg = a[ii]; 2722 seg.b = cp1; 2723 seg.c = cp1 + (seg.d - cp1) * 0.4; //instead of placing c on d exactly, we move it inline with b so that if the user specifies an ease like Back.easeOut or Elastic.easeOut which goes BEYOND the end, it will do so smoothly. 2724 seg.da = seg.d - seg.a; 2725 seg.ca = seg.c - seg.a; 2726 seg.ba = cp1 - seg.a; 2727 if (quad) { 2728 qb = cubicToQuadratic(seg.a, cp1, seg.c, seg.d); 2729 a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]); 2730 } 2731 }, 2732 _parseAnchors = function(values, p, correlate, prepend) { 2733 var a = [], 2734 l, i, p1, p2, p3, tmp; 2735 if (prepend) {
2736 values = [prepend].concat(values); 2737 i = values.length; 2738 while (--i > -1) { 2739 if (typeof( (tmp = values[i][p]) ) === "string") if (tmp.charAt(1) === "=") { 2740 values[i][p] = prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)); //accommodate relative values. Do it inline instead of breaking it out into a function for speed reasons 2741 } 2742 } 2743 } 2744 l = values.length - 2; 2745 if (l < 0) { 2746 a[0] = new Segment(values[0][p], 0, 0, values[0][p]); 2747 return a; 2748 } 2749 for (i = 0; i < l; i++) { 2750 p1 = values[i][p]; 2751 p2 = values[i+1][p]; 2752 a[i] = new Segment(p1, 0, 0, p2); 2753 if (correlate) { 2754 p3 = values[i+2][p]; 2755 _r1[i] = (_r1[i] || 0) + (p2 - p1) * (p2 - p1); 2756 _r2[i] = (_r2[i] || 0) + (p3 - p2) * (p3 - p2); 2757 } 2758 } 2759 a[i] = new Segment(values[i][p], 0, 0, values[i+1][p]); 2760 return a; 2761 }, 2762 bezierThrough = function(values, curviness, quadratic, basic, correlate, prepend) { 2763 var obj = {}, 2764 props = [], 2765 first = prepend || values[0], 2766 i, p, a, j, r, l, seamless, last; 2767 correlate = (typeof(correlate) === "string") ? ","+correlate+"," : _correlate; 2768 if (curviness == null) { 2769 curviness = 1; 2770 } 2771 for (p in values[0]) { 2772 props.push(p); 2773 } 2774 //check to see if the last and first values are identical (well, within 0.05). If so, make seamless by appending the second element to the very end of the values array and the 2nd-to-last element to the very beginning (we'll remove those segments later) 2775 if (values.length > 1) { 2776 last = values[values.length - 1]; 2777 seamless = true; 2778 i = props.length; 2779 while (--i > -1) { 2780 p = props[i]; 2781 if (Math.abs(first[p] - last[p]) > 0.05) { //build in a tolerance of +/-0.05 to accommodate rounding errors. 2782 seamless = false; 2783 break; 2784 } 2785 } 2786 if (seamless) { 2787 values = values.concat(); //duplicate the array to avoid contaminating the original which the user may be reusing for other tweens 2788 if (prepend) { 2789 values.unshift(prepend); 2790 } 2791 values.push(values[1]); 2792 prepend = values[values.length - 3]; 2793 } 2794 } 2795 _r1.length = _r2.length = _r3.length = 0; 2796 i = props.length; 2797 while (--i > -1) { 2798 p = props[i]; 2799 _corProps[p] = (correlate.indexOf(","+p+",") !== -1); 2800 obj[p] = _parseAnchors(values, p, _corProps[p], prepend); 2801 } 2802 i = _r1.length; 2803 while (--i > -1) { 2804 _r1[i] = Math.sqrt(_r1[i]); 2805 _r2[i] = Math.sqrt(_r2[i]); 2806 } 2807 if (!basic) { 2808 i = props.length; 2809 while (--i > -1) { 2810 if (_corProps[p]) { 2811 a = obj[props[i]]; 2812 l = a.length - 1; 2813 for (j = 0; j < l; j++) { 2814 r = (a[j+1].da / _r2[j] + a[j].da / _r1[j]) || 0; 2815 _r3[j] = (_r3[j] || 0) + r * r; 2816 } 2817 } 2818 } 2819 i = _r3.length; 2820 while (--i > -1) { 2821 _r3[i] = Math.sqrt(_r3[i]); 2822 } 2823 } 2824 i = props.length; 2825 j = quadratic ? 4 : 1; 2826 while (--i > -1) { 2827 p = props[i]; 2828 a = obj[p]; 2829 _calculateControlPoints(a, curviness, quadratic, basic, _corProps[p]); //this method requires that _parseAnchors() and _setSegmentRatios() ran first so that _r1, _r2, and _r3 values are populated for all properties 2830 if (seamless) { 2831 a.splice(0, j); 2832 a.splice(a.length - j, j); 2833 } 2834 } 2835 return obj; 2836 }, 2837 _parseBezierData = function(values, type, prepend) { 2838 type = type || "soft"; 2839 var obj = {}, 2840 inc = (type === "cubic") ? 3 : 2, 2841 soft = (type === "soft"), 2842 props = [], 2843 a, b, c, d, cur, i, j, l, p, cnt, tmp; 2844 if (soft && prepend) { 2845 values = [prepend].concat(values); 2846 } 2847 if (values == null || values.length < inc + 1) { throw "invalid Bezier data"; } 2848 for (p in values[0]) { 2849 props.push(p); 2850 } 2851 i = props.length; 2852 while (--i > -1) { 2853 p = props[i]; 2854 obj[p] = cur = []; 2855 cnt = 0; 2856 l = values.length; 2857 for (j = 0; j < l; j++) { 2858 a = (prepend == null) ? values[j][p] : (typeof( (tmp = values[j][p]) ) === "string" && tmp.charAt(1) === "=") ? prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)) : Number(tmp); 2859 if (soft) if (j > 1) if (j < l - 1) { 2860 cur[cnt++] = (a + cur[cnt-2]) / 2; 2861 } 2862 cur[cnt++] = a; 2863 } 2864 l = cnt - inc + 1; 2865 cnt = 0; 2866 for (j = 0; j < l; j += inc) { 2867 a = cur[j]; 2868 b = cur[j+1]; 2869 c = cur[j+2]; 2870 d = (inc === 2) ? 0 : cur[j+3]; 2871 cur[cnt++] = tmp = (inc === 3) ? new Segment(a, b, c, d) : new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c); 2872 } 2873 cur.length = cnt; 2874 } 2875 return obj; 2876 }, 2877 _addCubicLengths = function(a, steps, resolution) { 2878 var inc = 1 / resolution, 2879 j = a.length, 2880 d, d1, s, da, ca, ba, p, i, inv, bez, index; 2881 while (--j > -1) { 2882 bez = a[j]; 2883 s = bez.a; 2884 da = bez.d - s; 2885 ca = bez.c - s; 2886 ba = bez.b - s; 2887 d = d1 = 0; 2888 for (i = 1; i <= resolution; i++) { 2889 p = inc * i; 2890 inv = 1 - p; 2891 d = d1 - (d1 = (p * p * da + 3 * inv * (p * ca + inv * ba)) * p); 2892 index = j * resolution + i - 1; 2893 steps[index] = (steps[index] || 0) + d * d; 2894 } 2895 } 2896 }, 2897 _parseLengthData = function(obj, resolution) { 2898 resolution = resolution >> 0 || 6; 2899 var a = [], 2900 lengths = [], 2901 d = 0, 2902 total = 0, 2903 threshold = resolution - 1, 2904 segments = [], 2905 curLS = [], //current length segments array 2906 p, i, l, index; 2907 for (p in obj) { 2908 _addCubicLengths(obj[p], a, resolution); 2909 } 2910 l = a.length; 2911 for (i = 0; i < l; i++) { 2912 d += Math.sqrt(a[i]); 2913 index = i % resolution; 2914 curLS[index] = d; 2915 if (index === threshold) { 2916 total += d; 2917 index = (i / resolution) >> 0; 2918 segments[index] = curLS; 2919 lengths[index] = total; 2920 d = 0; 2921 curLS = []; 2922 } 2923 } 2924 return {length:total, lengths:lengths, segments:segments}; 2925 }, 2926 2927 2928 2929 BezierPlugin = _gsScope._gsDefine.plugin({ 2930 propName: "bezier", 2931 priority: -1, 2932 version: "1.3.8", 2933 API: 2, 2934 global:true, 2935 2936 //gets called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. 2937 init: function(target, vars, tween) { 2938 this._target = target; 2939 if (vars instanceof Array) { 2940 vars = {values:vars}; 2941 } 2942 this._func = {}; 2943 this._mod = {}; 2944 this._props = []; 2945 this._timeRes = (vars.timeResolution == null) ? 6 : parseInt(vars.timeResolution, 10); 2946 var values = vars.values || [], 2947 first = {}, 2948 second = values[0], 2949 autoRotate = vars.autoRotate || tween.vars.orientToBezier, 2950 p, isFunc, i, j, prepend; 2951 2952 this._autoRotate = autoRotate ? (autoRotate instanceof Array) ? autoRotate : [["x","y","rotation",((autoRotate === true) ? 0 : Number(autoRotate) || 0)]] : null; 2953 for (p in second) { 2954 this._props.push(p); 2955 } 2956 2957 i = this._props.length; 2958 while (--i > -1) { 2959 p = this._props[i]; 2960 2961 this._overwriteProps.push(p); 2962 isFunc = this._func[p] = (typeof(target[p]) === "function"); 2963 first[p] = (!isFunc) ? parseFloat(target[p]) : target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ](); 2964 if (!prepend) if (first[p] !== values[0][p]) { 2965 prepend = first; 2966 } 2967 } 2968 this._beziers = (vars.type !== "cubic" && vars.type !== "quadratic" && vars.type !== "soft") ? bezierThrough(values, isNaN(vars.curviness) ? 1 : vars.curviness, false, (vars.type === "thruBasic"), vars.correlate, prepend) : _parseBezierData(values, vars.type, first); 2969 this._segCount = this._beziers[p].length; 2970 2971 if (this._timeRes) { 2972 var ld = _parseLengthData(this._beziers, this._timeRes); 2973 this._length = ld.length; 2974 this._lengths = ld.lengths; 2975 this._segments = ld.segments; 2976 this._l1 = this._li = this._s1 = this._si = 0; 2977 this._l2 = this._lengths[0]; 2978 this._curSeg = this._segments[0]; 2979 this._s2 = this._curSeg[0]; 2980 this._prec = 1 / this._curSeg.length; 2981 } 2982 2983 if ((autoRotate = this._autoRotate)) { 2984 this._initialRotations = []; 2985 if (!(autoRotate[0] instanceof Array)) { 2986 this._autoRotate = autoRotate = [autoRotate]; 2987 } 2988 i = autoRotate.length; 2989 while (--i > -1) { 2990 for (j = 0; j < 3; j++) { 2991 p = autoRotate[i][j]; 2992 this._func[p] = (typeof(target[p]) === "function") ? target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ] : false;
2993 } 2994 p = autoRotate[i][2]; 2995 this._initialRotations[i] = (this._func[p] ? this._func[p].call(this._target) : this._target[p]) || 0; 2996 this._overwriteProps.push(p); 2997 } 2998 } 2999 this._startRatio = tween.vars.runBackwards ? 1 : 0; //we determine the starting ratio when the tween inits which is always 0 unless the tween has runBackwards:true (indicating it's a from() tween) in which case it's 1. 3000 return true; 3001 }, 3002 3003 //called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.) 3004 set: function(v) { 3005 var segments = this._segCount, 3006 func = this._func, 3007 target = this._target, 3008 notStart = (v !== this._startRatio), 3009 curIndex, inv, i, p, b, t, val, l, lengths, curSeg; 3010 if (!this._timeRes) { 3011 curIndex = (v < 0) ? 0 : (v >= 1) ? segments - 1 : (segments * v) >> 0; 3012 t = (v - (curIndex * (1 / segments))) * segments; 3013 } else { 3014 lengths = this._lengths; 3015 curSeg = this._curSeg; 3016 v *= this._length; 3017 i = this._li; 3018 //find the appropriate segment (if the currently cached one isn't correct) 3019 if (v > this._l2 && i < segments - 1) { 3020 l = segments - 1; 3021 while (i < l && (this._l2 = lengths[++i]) <= v) { } 3022 this._l1 = lengths[i-1]; 3023 this._li = i; 3024 this._curSeg = curSeg = this._segments[i]; 3025 this._s2 = curSeg[(this._s1 = this._si = 0)]; 3026 } else if (v < this._l1 && i > 0) { 3027 while (i > 0 && (this._l1 = lengths[--i]) >= v) { } 3028 if (i === 0 && v < this._l1) { 3029 this._l1 = 0; 3030 } else { 3031 i++; 3032 } 3033 this._l2 = lengths[i]; 3034 this._li = i; 3035 this._curSeg = curSeg = this._segments[i]; 3036 this._s1 = curSeg[(this._si = curSeg.length - 1) - 1] || 0; 3037 this._s2 = curSeg[this._si]; 3038 } 3039 curIndex = i; 3040 //now find the appropriate sub-segment (we split it into the number of pieces that was defined by "precision" and measured each one) 3041 v -= this._l1; 3042 i = this._si; 3043 if (v > this._s2 && i < curSeg.length - 1) { 3044 l = curSeg.length - 1; 3045 while (i < l && (this._s2 = curSeg[++i]) <= v) { } 3046 this._s1 = curSeg[i-1]; 3047 this._si = i; 3048 } else if (v < this._s1 && i > 0) { 3049 while (i > 0 && (this._s1 = curSeg[--i]) >= v) { } 3050 if (i === 0 && v < this._s1) { 3051 this._s1 = 0; 3052 } else { 3053 i++; 3054 } 3055 this._s2 = curSeg[i]; 3056 this._si = i; 3057 } 3058 t = ((i + (v - this._s1) / (this._s2 - this._s1)) * this._prec) || 0; 3059 } 3060 inv = 1 - t; 3061 3062 i = this._props.length; 3063 while (--i > -1) { 3064 p = this._props[i]; 3065 b = this._beziers[p][curIndex]; 3066 val = (t * t * b.da + 3 * inv * (t * b.ca + inv * b.ba)) * t + b.a; 3067 if (this._mod[p]) { 3068 val = this._mod[p](val, target); 3069 } 3070 if (func[p]) { 3071 target[p](val); 3072 } else { 3073 target[p] = val; 3074 } 3075 } 3076 3077 if (this._autoRotate) { 3078 var ar = this._autoRotate, 3079 b2, x1, y1, x2, y2, add, conv; 3080 i = ar.length; 3081 while (--i > -1) { 3082 p = ar[i][2]; 3083 add = ar[i][3] || 0; 3084 conv = (ar[i][4] === true) ? 1 : _RAD2DEG; 3085 b = this._beziers[ar[i][0]]; 3086 b2 = this._beziers[ar[i][1]]; 3087 3088 if (b && b2) { //in case one of the properties got overwritten. 3089 b = b[curIndex]; 3090 b2 = b2[curIndex]; 3091 3092 x1 = b.a + (b.b - b.a) * t; 3093 x2 = b.b + (b.c - b.b) * t; 3094 x1 += (x2 - x1) * t; 3095 x2 += ((b.c + (b.d - b.c) * t) - x2) * t; 3096 3097 y1 = b2.a + (b2.b - b2.a) * t; 3098 y2 = b2.b + (b2.c - b2.b) * t; 3099 y1 += (y2 - y1) * t; 3100 y2 += ((b2.c + (b2.d - b2.c) * t) - y2) * t; 3101 3102 val = notStart ? Math.atan2(y2 - y1, x2 - x1) * conv + add : this._initialRotations[i]; 3103 3104 if (this._mod[p]) { 3105 val = this._mod[p](val, target); //for modProps 3106 } 3107 3108 if (func[p]) { 3109 target[p](val); 3110 } else { 3111 target[p] = val; 3112 } 3113 } 3114 } 3115 } 3116 } 3117 }), 3118 p = BezierPlugin.prototype; 3119 3120 3121 BezierPlugin.bezierThrough = bezierThrough; 3122 BezierPlugin.cubicToQuadratic = cubicToQuadratic; 3123 BezierPlugin._autoCSS = true; //indicates that this plugin can be inserted into the "css" object using the autoCSS feature of TweenLite 3124 BezierPlugin.quadraticToCubic = function(a, b, c) { 3125 return new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c); 3126 }; 3127 3128 BezierPlugin._cssRegister = function() { 3129 var CSSPlugin = _globals.CSSPlugin; 3130 if (!CSSPlugin) { 3131 return; 3132 } 3133 var _internals = CSSPlugin._internals, 3134 _parseToProxy = _internals._parseToProxy, 3135 _setPluginRatio = _internals._setPluginRatio, 3136 CSSPropTween = _internals.CSSPropTween; 3137 _internals._registerComplexSpecialProp("bezier", {parser:function(t, e, prop, cssp, pt, plugin) { 3138 if (e instanceof Array) { 3139 e = {values:e}; 3140 } 3141 plugin = new BezierPlugin(); 3142 var values = e.values, 3143 l = values.length - 1, 3144 pluginValues = [], 3145 v = {}, 3146 i, p, data; 3147 if (l < 0) { 3148 return pt; 3149 } 3150 for (i = 0; i <= l; i++) { 3151 data = _parseToProxy(t, values[i], cssp, pt, plugin, (l !== i)); 3152 pluginValues[i] = data.end; 3153 } 3154 for (p in e) { 3155 v[p] = e[p]; //duplicate the vars object because we need to alter some things which w
3155ould cause problems if the user plans to reuse the same vars object for another tween. 3156 } 3157 v.values = pluginValues; 3158 pt = new CSSPropTween(t, "bezier", 0, 0, data.pt, 2); 3159 pt.data = data; 3160 pt.plugin = plugin; 3161 pt.setRatio = _setPluginRatio; 3162 if (v.autoRotate === 0) { 3163 v.autoRotate = true; 3164 } 3165 if (v.autoRotate && !(v.autoRotate instanceof Array)) { 3166 i = (v.autoRotate === true) ? 0 : Number(v.autoRotate); 3167 v.autoRotate = (data.end.left != null) ? [["left","top","rotation",i,false]] : (data.end.x != null) ? [["x","y","rotation",i,false]] : false; 3168 } 3169 if (v.autoRotate) { 3170 if (!cssp._transform) { 3171 cssp._enableTransforms(false); 3172 } 3173 data.autoRotate = cssp._target._gsTransform; 3174 data.proxy.rotation = data.autoRotate.rotation || 0; 3175 cssp._overwriteProps.push("rotation"); 3176 } 3177 plugin._onInitTween(data.proxy, v, cssp._tween); 3178 return pt; 3179 }}); 3180 }; 3181 3182 p._mod = function(lookup) { 3183 var op = this._overwriteProps, 3184 i = op.length, 3185 val; 3186 while (--i > -1) { 3187 val = lookup[op[i]]; 3188 if (val && typeof(val) === "function") { 3189 this._mod[op[i]] = val; 3190 } 3191 } 3192 }; 3193 3194 p._kill = function(lookup) { 3195 var a = this._props, 3196 p, i; 3197 for (p in this._beziers) { 3198 if (p in lookup) { 3199 delete this._beziers[p]; 3200 delete this._func[p]; 3201 i = a.length; 3202 while (--i > -1) { 3203 if (a[i] === p) { 3204 a.splice(i, 1); 3205 } 3206 } 3207 } 3208 } 3209 a = this._autoRotate; 3210 if (a) { 3211 i = a.length; 3212 while (--i > -1) { 3213 if (lookup[a[i][2]]) { 3214 a.splice(i, 1); 3215 } 3216 } 3217 } 3218 return this._super._kill.call(this, lookup); 3219 }; 3220 3221 }()); 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236/* 3237 * ---------------------------------------------------------------- 3238 * CSSPlugin 3239 * ---------------------------------------------------------------- 3240 */ 3241 _gsScope._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin","TweenLite"], function(TweenPlugin, TweenLite) { 3242 3243 /** @constructor **/ 3244 var CSSPlugin = function() { 3245 TweenPlugin.call(this, "css"); 3246 this._overwriteProps.length = 0; 3247 this.setRatio = CSSPlugin.prototype.setRatio; //speed optimization (avoid prototype lookup on this "hot" method) 3248 }, 3249 _globals = _gsScope._gsDefine.globals, 3250 _hasPriority, //turns true whenever a CSSPropTween instance is created that has a priority other than 0. This helps us discern whether or not we should spend the time organizing the linked list or not after a CSSPlugin's _onInitTween() method is called. 3251 _suffixMap, //we set this in _onInitTween() each time as a way to have a persistent variable we can use in other methods like _parse() without having to pass it around as a parameter and we keep _parse() decoupled from a particular CSSPlugin instance 3252 _cs, //computed style (we store this in a shared variable to conserve memory and make minification tighter 3253 _overwriteProps, //alias to the currently instantiating CSSPlugin's _overwriteProps array. We use this closure in order to avoid having to pass a reference around from method to method and aid in minification. 3254 _specialProps = {}, 3255 p = CSSPlugin.prototype = new TweenPlugin("css"); 3256 3257 p.constructor = CSSPlugin; 3258 CSSPlugin.version = "1.20.5"; 3259 CSSPlugin.API = 2; 3260 CSSPlugin.defaultTransformPerspective = 0; 3261 CSSPlugin.defaultSkewType = "compensated"; 3262 CSSPlugin.defaultSmoothOrigin = true; 3263 p = "px"; //we'll reuse the "p" variable to keep file size down 3264 CSSPlugin.suffixMap = {top:p, right:p, bottom:p, left:p, width:p, height:p, fontSize:p, padding:p, margin:p, perspective:p, lineHeight:""}; 3265 3266 3267 var _numExp = /(?:\-|\.|\b)(\d|\.|e\-)+/g, 3268 _relNumExp = /(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g, 3269 _valuesExp = /(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b)/gi, //finds all the values that begin with numbers or += or -= and then a number. Includes suffixes. We use this to split complex values apart like "1px 5px 20px rgb(255,102,51)" 3270 _NaNExp = /(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g, //also allows scientific notation and doesn't kill the leading -/+ in -= and += 3271 _suffixExp = /(?:\d|\-|\+|=|#|\.)*/g, 3272 _opacityExp = /opacity *= *([^)]*)/i, 3273 _opacityValExp = /opacity:([^;]*)/i,
3274 _alphaFilterExp = /alpha\(opacity *=.+?\)/i, 3275 _rgbhslExp = /^(rgb|hsl)/, 3276 _capsExp = /([A-Z])/g, 3277 _camelExp = /-([a-z])/gi, 3278 _urlExp = /(^(?:url\(\"|url\())|(?:(\"\))$|\)$)/gi, //for pulling out urls from url(...) or url("...") strings (some browsers wrap urls in quotes, some don't when reporting things like backgroundImage) 3279 _camelFunc = function(s, g) { return g.toUpperCase(); }, 3280 _horizExp = /(?:Left|Right|Width)/i, 3281 _ieGetMatrixExp = /(M11|M12|M21|M22)=[\d\-\.e]+/gi, 3282 _ieSetMatrixExp = /progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i, 3283 _commasOutsideParenExp = /,(?=[^\)]*(?:\(|$))/gi, //finds any commas that are not within parenthesis 3284 _complexExp = /[\s,\(]/i, //for testing a string to find if it has a space, comma, or open parenthesis (clues that it's a complex value) 3285 _DEG2RAD = Math.PI / 180, 3286 _RAD2DEG = 180 / Math.PI, 3287 _forcePT = {}, 3288 _dummyElement = {style:{}}, 3289 _doc = _gsScope.document || {createElement: function() {return _dummyElement;}}, 3290 _createElement = function(type, ns) { 3291 return _doc.createElementNS ? _doc.createElementNS(ns || "http://www.w3.org/1999/xhtml", type) : _doc.createElement(type); 3292 }, 3293 _tempDiv = _createElement("div"), 3294 _tempImg = _createElement("img"), 3295 _internals = CSSPlugin._internals = {_specialProps:_specialProps}, //provides a hook to a few internal methods that we need to access from inside other plugins 3296 _agent = (_gsScope.navigator || {}).userAgent || "", 3297 _autoRound, 3298 _reqSafariFix, //we won't apply the Safari transform fix until we actually come across a tween that affects a transform property (to maintain best performance). 3299 3300 _isSafari, 3301 _isFirefox, //Firefox has a bug that causes 3D transformed elements to randomly disappear unless a repaint is forced after each update on each element. 3302 _isSafariLT6, //Safari (and Android 4 which uses a flavor of Safari) has a bug that prevents changes to "top" and "left" properties from rendering properly if changed on the same frame as a transform UNLESS we set the element's WebkitBackfaceVisibility to hidden (weird, I know). Doing this for Android 3 and earlier seems to actually cause other problems, though (fun!) 3303 _ieVers, 3304 _supportsOpacity = (function() { //we set _isSafari, _ieVers, _isFirefox, and _supportsOpacity all in one function here to reduce file size slightly, especially in the minified version. 3305 var i = _agent.indexOf("Android"), 3306 a = _createElement("a"); 3307 _isSafari = (_agent.indexOf("Safari") !== -1 && _agent.indexOf("Chrome") === -1 && (i === -1 || parseFloat(_agent.substr(i+8, 2)) > 3)); 3308 _isSafariLT6 = (_isSafari && (parseFloat(_agent.substr(_agent.indexOf("Version/")+8, 2)) < 6)); 3309 _isFirefox = (_agent.indexOf("Firefox") !== -1); 3310 if ((/MSIE ([0-9]{1,}[\.0-9]{0,})/).exec(_agent) || (/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/).exec(_agent)) { 3311 _ieVers = parseFloat( RegExp.$1 ); 3312 } 3313 if (!a) { 3314 return false; 3315 } 3316 a.style.cssText = "top:1px;opacity:.55;"; 3317 return /^0.55/.test(a.style.opacity); 3318 }()), 3319 _getIEOpacity = function(v) { 3320 return (_opacityExp.test( ((typeof(v) === "string") ? v : (v.currentStyle ? v.currentStyle.filter : v.style.filter) || "") ) ? ( parseFloat( RegExp.$1 ) / 100 ) : 1); 3321 }, 3322 _log = function(s) {//for logging messages, but in a way that won't throw errors in old versions of IE. 3323 if (_gsScope.console) { 3324 console.log(s); 3325 } 3326 }, 3327 _target, //when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params 3328 _index, //when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params 3329 3330 _prefixCSS = "", //the non-camelCase vendor prefix like "-o-", "-moz-", "-ms-", or "-webkit-" 3331 _prefix = "", //camelCase vendor prefix like "O", "ms", "Webkit", or "Moz". 3332 3333 // @private feed in a camelCase property name like "transform" and it will check to see if it is valid as-is or if it needs a vendor prefix. It returns the corrected camelCase property name (i.e. "WebkitTransform" or "MozTransform" or "transform" or null if no such property is found, like if the browser is IE8 or before, "transform" won't be found at all) 3334 _checkPropPrefix = function(p, e) { 3335 e = e || _tempDiv; 3336 var s = e.style, 3337 a, i; 3338 if (s[p] !== undefined) { 3339 return p; 3340 } 3341 p = p.charAt(0).toUpperCase() + p.substr(1); 3342 a = ["O","Moz","ms","Ms","Webkit"]; 3343 i = 5; 3344 while (--i > -1 && s[a[i]+p] === undefined) { } 3345 if (i >= 0) { 3346 _prefix = (i === 3) ? "ms" : a[i]; 3347 _prefixCSS = "-" + _prefix.toLowerCase() + "-"; 3348 return _prefix + p; 3349 } 3350 return null; 3351 }, 3352 3353 _getComputedStyle = (typeof(window) !== "undefined" ? window : _doc.defaultView || {getComputedStyle:function() {}}).getComputedStyle, 3354 3355 /** 3356 * @private Returns the css style for a particular property of an element. For example, to get whatever the current "left" css value for an element with an ID of "myElement", you could do: 3357 * var currentLeft = CSSPlugin.getStyle( document.getElementById("myElement"), "left"); 3358 * 3359 * @param {!Object} t Target element whose style property you want to query 3360 * @param {!string} p Property name (like "left" or "top" or "marginTop", etc.) 3361 * @param {Object=} cs Computed style object. This just provides a way to speed processing if you're going to get several properties on the same element in quick succession - you can reuse the result of the getComputedStyle() call. 3362 * @param {boolean=} calc If true, the value will not be read directly from the element's "style" property (if it exists there), but instead the getComputedStyle() result will be used. This can be useful when you want to ensure that the browser itself is interpreting the value. 3363 * @param {string=} dflt Default value that should be returned in the place of null, "none", "auto" or "auto auto". 3364 * @return {?string} The current property value 3365 */ 3366 _getStyle = CSSPlugin.getStyle = function(t, p, cs, calc, dflt) { 3367 var rv; 3368 if (!_supportsOpacity) if (p === "opacity") { //several versions of IE don't use the standard "opacity" property - they use things like filter:alpha(opacity=50), so we parse that here. 3369 return _getIEOpacity(t); 3370 } 3371 if (!calc && t.style[p]) { 3372 rv = t.style[p]; 3373 } else if ((cs = cs || _getComputedStyle(t))) { 3374 rv = cs[p] || cs.getPropertyValue(p) || cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase()); 3375 } else if (t.currentStyle) { 3376 rv = t.currentStyle[p]; 3377 } 3378 return (dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto")) ? dflt : rv; 3379 }, 3380 3381 /** 3382 * @private Pass the target element, the property name, the numeric value, and the suffix (like "%", "em", "px", etc.) and it will spit back the equivalent pixel number. 3383 * @param {!Object} t Target element 3384 * @param {!string} p Property name (like "left", "top", "marginLeft", etc.) 3385 * @param {!number} v Value 3386 * @param {string=} sfx Suffix (like "px" or "%" or "em") 3387 * @param {boolean=} recurse If true, the call is a recursive one. In some browsers (like IE7/8), occasionally the value isn't accurately reported initially, but if we run the function again it will take effect. 3388 * @return {number} value in pixels 3389 */ 3390 _convertToPixels = _internals.convertToPixels = function(t, p, v, sfx, recurse) { 3391 if (sfx === "px" || (!sfx && p !== "lineHeight")) { return v; } 3392 if (sfx === "auto" || !v) { return 0; } 3393 var horiz = _horizExp.test(p), 3394 node = t, 3395 style = _tempDiv.style, 3396 neg = (v < 0), 3397 precise = (v === 1), 3398 pix, cache, time; 3399 if (neg) { 3400 v = -v; 3401 } 3402 if (precise) { 3403 v *= 100; 3404 } 3405 if (p === "lineHeight" && !sfx) { //special case of when a simple lineHeight (without a unit) is used. Set it to the value, read back the computed value, and then revert. 3406 cache = _getComputedStyle(t).lineHeight; 3407 t.style.lineHeight = v; 3408 pix = parseFloat(_getComputedStyle(t).lineHeight); 3409 t.style.lineHeight = cache; 3410 } else if (sfx === "%" && p.indexOf("border") !== -1) { 3411 pix = (v / 100) * (horiz ? t.clientWidth : t.clientHeight); 3412 } else { 3413 style.cssText = "border:0 solid red;position:" + _getStyle(t, "position") + ";line-height:0;"; 3414 if (sfx === "%" || !node.appendChild || sfx.charAt(0) === "v" || sfx === "rem") { 3415 node = t.parentNode || _doc.body; 3416 if (_getStyle(node, "display").indexOf("flex") !== -1) { //Edge and IE11 have a bug that causes offsetWidth to report as 0 if the container has display:flex and the child is position:relative. Switching to position: absolute solves it. 3417 style.position = "absolute"; 3418 } 3419 cache = node._gsCache; 3420 time = TweenLite.ticker.frame; 3421 if (cache && horiz && cache.time === time) { //performance optimization: we record the width of elements along with the ticker frame so that we can quickly get it again on the same tick (seems relatively safe to assume it wouldn't change on the same tick) 3422 return cache.width * v / 100; 3423 } 3424 style[(horiz ? "width" : "height")] = v + sfx; 3425 } else { 3426 style[(horiz ? "borderLeftWidth" : "borderTopWidth")] = v + sfx; 3427 } 3428 node.appendChild(_tempDiv); 3429 pix = parseFloat(_tempDiv[(horiz ? "offsetWidth" : "offsetHeight")]); 3430 node.removeChild(_tempDiv); 3431 if (horiz && sfx === "%" && CSSPlugin.cacheWidths !== false) { 3432 cache = node._gsCache = node._gsCache || {}; 3433 cache.time = time; 3434 cache.width = pix / v * 100; 3435 } 3436 if (pix === 0 && !recurse) { 3437 pix = _convertToPixels(t, p, v, sfx, true); 3438 } 3439 } 3440 if (precise) { 3441 pix /= 100; 3442 } 3443 return neg ? -pix : pix; 3444 }, 3445 _calculateOffset = _internals.calculateOffset = function(t, p, cs) { //for figuring out "top" or "left" in px when it's "auto". We need to factor in margin with the offsetLeft/offsetTop 3446 if (_getStyle(t, "position", cs) !== "absolute") { return 0; } 3447 var dim = ((p === "left") ? "Left" : "Top"),
3448 v = _getStyle(t, "margin" + dim, cs); 3449 return t["offset" + dim] - (_convertToPixels(t, p, parseFloat(v), v.replace(_suffixExp, "")) || 0); 3450 }, 3451 3452 // @private returns at object containing ALL of the style properties in camelCase and their associated values. 3453 _getAllStyles = function(t, cs) { 3454 var s = {}, 3455 i, tr, p; 3456 if ((cs = cs || _getComputedStyle(t, null))) { 3457 if ((i = cs.length)) { 3458 while (--i > -1) { 3459 p = cs[i]; 3460 if (p.indexOf("-transform") === -1 || _transformPropCSS === p) { //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here. 3461 s[p.replace(_camelExp, _camelFunc)] = cs.getPropertyValue(p); 3462 } 3463 } 3464 } else { //some browsers behave differently - cs.length is always 0, so we must do a for...in loop. 3465 for (i in cs) { 3466 if (i.indexOf("Transform") === -1 || _transformProp === i) { //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here. 3467 s[i] = cs[i]; 3468 } 3469 } 3470 } 3471 } else if ((cs = t.currentStyle || t.style)) { 3472 for (i in cs) { 3473 if (typeof(i) === "string" && s[i] === undefined) { 3474 s[i.replace(_camelExp, _camelFunc)] = cs[i]; 3475 } 3476 } 3477 } 3478 if (!_supportsOpacity) { 3479 s.opacity = _getIEOpacity(t); 3480 } 3481 tr = _getTransform(t, cs, false); 3482 s.rotation = tr.rotation; 3483 s.skewX = tr.skewX; 3484 s.scaleX = tr.scaleX; 3485 s.scaleY = tr.scaleY; 3486 s.x = tr.x; 3487 s.y = tr.y; 3488 if (_supports3D) { 3489 s.z = tr.z; 3490 s.rotationX = tr.rotationX; 3491 s.rotationY = tr.rotationY; 3492 s.scaleZ = tr.scaleZ; 3493 } 3494 if (s.filters) { 3495 delete s.filters; 3496 } 3497 return s; 3498 }, 3499 3500 // @private analyzes two style objects (as returned by _getAllStyles()) and only looks for differences between them that contain tweenable values (like a number or color). It returns an object with a "difs" property which refers to an object c
3500ontaining only those isolated properties and values for tweening, and a "firstMPT" property which refers to the first MiniPropTween instance in a linked list that recorded all the starting values of the different properties so that we can revert to them at the end or beginning of the tween - we don't want the cascading to get messed up. The forceLookup parameter is an optional generic object with properties that should be forced into the results - this is necessary for className tweens that are overwriting others because imagine a scenario where a rollover/rollout adds/removes a class and the user swipes the mouse over the target SUPER fast, thus nothing actually changed yet and the subsequent comparison of the properties would indicate they match (especially when px rounding is taken into consideration), thus no tweening is necessary even though it SHOULD tween and remove those properties after the tween (otherwise the inline styles will contaminate things). See the className SpecialProp code for details. 3501 _cssDif = function(t, s1, s2, vars, forceLookup) { 3502 var difs = {}, 3503 style = t.style, 3504 val, p, mpt; 3505 for (p in s2) { 3506 if (p !== "cssText") if (p !== "length") if (isNaN(p)) if (s1[p] !== (val = s2[p]) || (forceLookup && forceLookup[p])) if (p.indexOf("Origin") === -1) if (typeof(val) === "number" || typeof(val) === "string") { 3507 difs[p] = (val === "auto" && (p === "left" || p === "top")) ? _calculateOffset(t, p) : ((val === "" || val === "auto" || val === "none") && typeof(s1[p]) === "string" && s1[p].replace(_NaNExp, "") !== "") ? 0 : val; //if the ending value is defaulting ("" or "auto"), we check the starting value and if it can be parsed into a number (a string which could have a suffix too, like 700px), then we swap in 0 for "" or "auto" so that things actually tween. 3508 if (style[p] !== undefined) { //for className tweens, we must remember which properties already existed inline - the ones that didn't should be removed when the tween isn't in progress because they were only introduced to facilitate the transition between classes. 3509 mpt = new MiniPropTween(style, p, style[p], mpt); 3510 } 3511 } 3512 } 3513 if (vars) { 3514 for (p in vars) { //copy properties (except className) 3515 if (p !== "className") { 3516 difs[p] = vars[p]; 3517 } 3518 } 3519 } 3520 return {difs:difs, firstMPT:mpt}; 3521 }, 3522 _dimensions = {width:["Left","Right"], height:["Top","Bottom"]}, 3523 _margins = ["marginLeft","marginRight","marginTop","marginBottom"], 3524 3525 /** 3526 * @private Gets the width or height of an element 3527 * @param {!Object} t Target element 3528 * @param {!string} p Property name ("width" or "height") 3529 * @param {Object=} cs Computed style object (if one exists). Just a speed optimization. 3530 * @return {number} Dimension (in pixels) 3531 */ 3532 _getDimension = function(t, p, cs) { 3533 if ((t.nodeName + "").toLowerCase() === "svg") { //Chrome no longer supports offsetWidth/offsetHeight on SVG elements. 3534 return (cs || _getComputedStyle(t))[p] || 0; 3535 } else if (t.getCTM && _isSVG(t)) { 3536 return t.getBBox()[p] || 0; 3537 } 3538 var v = parseFloat((p === "width") ? t.offsetWidth : t.offsetHeight), 3539 a = _dimensions[p], 3540 i = a.length; 3541 cs = cs || _getComputedStyle(t, null); 3542 while (--i > -1) { 3543 v -= parseFloat( _getStyle(t, "padding" + a[i], cs, true) ) || 0; 3544 v -= parseFloat( _getStyle(t, "border" + a[i] + "Width", cs, true) ) || 0; 3545 } 3546 return v; 3547 }, 3548 3549 // @private Parses position-related complex strings like "top left" or "50px 10px" or "70% 20%", etc. which are used for things like transformOrigin or backgroundPosition. Optionally decorates a supplied object (recObj) with the following properties: "ox" (offsetX), "oy" (offsetY), "oxp" (if true, "ox" is a percentage not a pixel value), and "oxy" (if true, "oy" is a percentage not a pixel value) 3550 _parsePosition = function(v, recObj) { 3551 if (v === "contain" || v === "auto" || v === "auto auto") { //note: Firefox uses "auto auto" as default whereas Chrome uses "auto". 3552 return v + " "; 3553 } 3554 if (v == null || v === "") { 3555 v = "0 0"; 3556 } 3557 var a = v.split(" "), 3558 x = (v.indexOf("left") !== -1) ? "0%" : (v.indexOf("right") !== -1) ? "100%" : a[0], 3559 y = (v.indexOf("top") !== -1) ? "0%" : (v.indexOf("bottom") !== -1) ? "100%" : a[1], 3560 i; 3561 if (a.length > 3 && !recObj) { //multiple positions 3562 a = v.split(", ").join(",").split(","); 3563 v = []; 3564 for (i = 0; i < a.length; i++) { 3565 v.push(_parsePosition(a[i])); 3566 } 3567 return v.join(","); 3568 } 3569 if (y == null) { 3570 y = (x === "center") ? "50%" : "0"; 3571 } else if (y === "center") { 3572 y = "50%"; 3573 } 3574 if (x === "center" || (isNaN(parseFloat(x)) && (x + "").indexOf("=") === -1)) { //remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it c
3574ould be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative. 3575 x = "50%"; 3576 } 3577 v = x + " " + y + ((a.length > 2) ? " " + a[2] : ""); 3578 if (recObj) { 3579 recObj.oxp = (x.indexOf("%") !== -1); 3580 recObj.oyp = (y.indexOf("%") !== -1); 3581 recObj.oxr = (x.charAt(1) === "="); 3582 recObj.oyr = (y.charAt(1) === "="); 3583 recObj.ox = parseFloat(x.replace(_NaNExp, "")); 3584 recObj.oy = parseFloat(y.replace(_NaNExp, "")); 3585 recObj.v = v; 3586 } 3587 return recObj || v; 3588 }, 3589 3590 /** 3591 * @private Takes an ending value (typically a string, but can be a number) and a starting value and returns the change between the two, looking for relative value indicators like += and -= and it also ignores suffixes (but make sure the ending value starts with a number or +=/-= and that the starting value is a NUMBER!) 3592 * @param {(number|string)} e End value which is typically a string, but could be a number 3593 * @param {(number|string)} b Beginning value which is typically a string but could be a number 3594 * @return {number} Amount of change between the beginning and ending values (relative values that have a "+=" or "-=" are recognized) 3595 */ 3596 _parseChange = function(e, b) { 3597 if (typeof(e) === "function") { 3598 e = e(_index, _target); 3599 } 3600 return (typeof(e) === "string" && e.charAt(1) === "=") ? parseInt(e.charAt(0) + "1", 10) * parseFloat(e.substr(2)) : (parseFloat(e) - parseFloat(b)) || 0; 3601 }, 3602 3603 /** 3604 * @private Takes a value and a default number, checks if the value is relative, null, or numeric and spits back a normalized number accordingly. Primarily used in the _parseTransform() function. 3605 * @param {Object} v Value to be parsed 3606 * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter) 3607 * @return {number} Parsed value 3608 */ 3609 _parseVal = function(v, d) { 3610 if (typeof(v) === "function") { 3611 v = v(_index, _target); 3612 } 3613 return (v == null) ? d : (typeof(v) === "string" && v.charAt(1) === "=") ? parseInt(v.charAt(0) + "1", 10) * parseFloat(v.substr(2)) + d : parseFloat(v) || 0; 3614 }, 3615 3616 /** 3617 * @private Translates strings like "40deg" or "40" or 40rad" or "+=40deg" or "270_short" or "-90_cw" or "+=45_ccw" to a numeric radian angle. Of course a starting/default value must be fed in too so that relative values can be calculated properly. 3618 * @param {Object} v Value to be parsed 3619 * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter) 3620 * @param {string=} p property name for directionalEnd (optional - only used when the parsed value is directional ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation). Property name would be "rotation", "rotationX", or "rotationY" 3621 * @param {Object=} directionalEnd An object that will store the raw end values for directional angles ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation. 3622 * @return {number} parsed angle in radians 3623 */ 3624 _parseAngle = function(v, d, p, directionalEnd) { 3625 var min = 0.000001, 3626 cap, split, dif, result, isRelative; 3627 if (typeof(v) === "function") { 3628 v = v(_index, _target); 3629 } 3630 if (v == null) { 3631 result = d; 3632 } else if (typeof(v) === "number") { 3633 result = v; 3634 } else { 3635 cap = 360; 3636 split = v.split("_"); 3637 isRelative = (v.charAt(1) === "="); 3638 dif = (isRelative ? parseInt(v.charAt(0) + "1", 10) * parseFloat(split[0].substr(2)) : parseFloat(split[0])) * ((v.indexOf("rad") === -1) ? 1 : _RAD2DEG) - (isRelative ? 0 : d); 3639 if (split.length) { 3640 if (directionalEnd) { 3641 directionalEnd[p] = d + dif; 3642 } 3643 if (v.indexOf("short") !== -1) { 3644 dif = dif % cap; 3645 if (dif !== dif % (cap / 2)) { 3646 dif = (dif < 0) ? dif + cap : dif - cap; 3647 } 3648 } 3649 if (v.indexOf("_cw") !== -1 && dif < 0) { 3650 dif = ((dif + cap * 9999999999) % cap) - ((dif / cap) | 0) * cap; 3651 } else if (v.indexOf("ccw") !== -1 && dif > 0) { 3652 dif = ((dif - cap * 9999999999) % cap) - ((dif / cap) | 0) * cap; 3653 } 3654 } 3655 result = d + dif; 3656 } 3657 if (result < min && result > -min) { 3658 result = 0; 3659 } 3660 return result; 3661 }, 3662 3663 _colorLookup = {aqua:[0,255,255], 3664 lime:[0,255,0], 3665 silver:[192,192,192], 3666 black:[0,0,0], 3667 maroon:[128,0,0], 3668 teal:[0,128,128], 3669 blue:[0,0,255], 3670 navy:[0,0,128], 3671 white:[255,255,255], 3672 fuchsia:[255,0,255], 3673 olive:[128,128,0], 3674 yellow:[255,255,0], 3675 orange:[255,165,0], 3676 gray:[128,128,128], 3677 purple:[128,0,128], 3678 green:[0,128,0], 3679 red:[255,0,0], 3680 pink:[255,192,203], 3681 cyan:[0,255,255], 3682 transparent:[255,255,255,0]}, 3683 3684 _hue = function(h, m1, m2) { 3685 h = (h < 0) ? h + 1 : (h > 1) ? h - 1 : h; 3686 return ((((h * 6 < 1) ? m1 + (m2 - m1) * h * 6 : (h < 0.5) ? m2 : (h * 3 < 2) ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * 255) + 0.5) | 0; 3687 }, 3688 3689 /** 3690 * @private Parses a color (like #9F0, #FF9900, rgb(255,51,153) or hsl(108, 50%, 10%)) into an array with 3 elements for red, green, and blue or if toHSL parameter is true, it will populate the array with hue, saturation, and lightness values. If a relative value is found in an hsl() or hsla() string, it will preserve those relative prefixes and all the values in the array will be strings instead of numbers (in all other cases it will be populated with numbers). 3691 * @param {(string|number)} v The value the should be parsed which could be a string like #9F0 or rgb(255,102,51) or rgba(255,0,0,0.5) or it could be a number like 0xFF00CC or even a named color like red, blue, purple, etc. 3692 * @param {(boolean)} toHSL If true, an hsl() or hsla() value will be returned instead of rgb() or rgba() 3693 * @return {Array.<number>} An array containing red, green, and blue (and optionally alpha) in that order, or if the toHSL parameter was true, the array will contain hue, saturation and lightness (and optionally alpha) in that order. Always numbers unless there's a relative prefix found in an hsl() or hsla() string and toHSL is true. 3694 */ 3695 _parseColor = CSSPlugin.parseColor = function(v, toHSL) { 3696 var a, r, g, b, h, s, l, max, min, d, wasHSL; 3697 if (!v) { 3698 a = _colorLookup.black; 3699 } else if (typeof(v) === "number") { 3700 a = [v >> 16, (v >> 8) & 255, v & 255]; 3701 } else { 3702 if (v.charAt(v.length - 1) === ",") { //sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)" - in this example "blue," has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value. 3703 v = v.substr(0, v.length - 1); 3704 } 3705 if (_colorLookup[v]) { 3706 a = _colorLookup[v]; 3707 } else if (v.charAt(0) === "#") { 3708 if (v.length === 4) { //for shorthand like #9F0 3709 r = v.charAt(1); 3710 g = v.charAt(2); 3711 b = v.charAt(3); 3712 v = "#" + r + r + g + g + b + b; 3713 } 3714 v = parseInt(v.substr(1), 16); 3715 a = [v >> 16, (v >> 8) & 255, v & 255]; 3716 } else if (v.substr(0, 3) === "hsl") { 3717 a = wasHSL = v.match(_numExp); 3718 if (!toHSL) { 3719 h = (Number(a[0]) % 360) / 360;
3720 s = Number(a[1]) / 100; 3721 l = Number(a[2]) / 100; 3722 g = (l <= 0.5) ? l * (s + 1) : l + s - l * s; 3723 r = l * 2 - g; 3724 if (a.length > 3) { 3725 a[3] = Number(a[3]); 3726 } 3727 a[0] = _hue(h + 1 / 3, r, g); 3728 a[1] = _hue(h, r, g); 3729 a[2] = _hue(h - 1 / 3, r, g); 3730 } else if (v.indexOf("=") !== -1) { //if relative values are found, just return the raw strings with the relative prefixes in place. 3731 return v.match(_relNumExp); 3732 } 3733 } else { 3734 a = v.match(_numExp) || _colorLookup.transparent; 3735 } 3736 a[0] = Number(a[0]); 3737 a[1] = Number(a[1]); 3738 a[2] = Number(a[2]); 3739 if (a.length > 3) { 3740 a[3] = Number(a[3]); 3741 } 3742 } 3743 if (toHSL && !wasHSL) { 3744 r = a[0] / 255; 3745 g = a[1] / 255; 3746 b = a[2] / 255; 3747 max = Math.max(r, g, b); 3748 min = Math.min(r, g, b); 3749 l = (max + min) / 2; 3750 if (max === min) { 3751 h = s = 0; 3752 } else { 3753 d = max - min; 3754 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 3755 h = (max === r) ? (g - b) / d + (g < b ? 6 : 0) : (max === g) ? (b - r) / d + 2 : (r - g) / d + 4; 3756 h *= 60; 3757 } 3758 a[0] = (h + 0.5) | 0; 3759 a[1] = (s * 100 + 0.5) | 0; 3760 a[2] = (l * 100 + 0.5) | 0; 3761 } 3762 return a; 3763 }, 3764 _formatColors = function(s, toHSL) { 3765 var colors = s.match(_colorExp) || [], 3766 charIndex = 0, 3767 parsed = "", 3768 i, color, temp; 3769 if (!colors.length) { 3770 return s; 3771 } 3772 for (i = 0; i < colors.length; i++) { 3773 color = colors[i]; 3774 temp = s.substr(charIndex, s.indexOf(color, charIndex)-charIndex); 3775 charIndex += temp.length + color.length; 3776 color = _parseColor(color, toHSL); 3777 if (color.length === 3) { 3778 color.push(1); 3779 } 3780 parsed += temp + (toHSL ? "hsla(" + color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : "rgba(" + color.join(",")) + ")"; 3781 } 3782 return parsed + s.substr(charIndex); 3783 }, 3784 _colorExp = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3}){1,2}\\b"; //we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc. 3785 3786 for (p in _colorLookup) { 3787 _colorExp += "|" + p + "\\b"; 3788 } 3789 _colorExp = new RegExp(_colorExp+")", "gi"); 3790 3791 CSSPlugin.colorStringFilter = function(a) { 3792 var combined = a[0] + " " + a[1], 3793 toHSL; 3794 if (_colorExp.test(combined)) { 3795 toHSL = (combined.indexOf("hsl(") !== -1 || combined.indexOf("hsla(") !== -1); 3796 a[0] = _formatColors(a[0], toHSL); 3797 a[1] = _formatColors(a[1], toHSL); 3798 } 3799 _colorExp.lastIndex = 0; 3800 }; 3801 3802 if (!TweenLite.defaultStringFilter) { 3803 TweenLite.defaultStringFilter = CSSPlugin.colorStringFilter; 3804 } 3805 3806 /** 3807 * @private Returns a formatter function that handles taking a string (or number in some cases) and returning a consistently formatted one in terms of delimiters, quantity of values, etc. For example, we may get boxShadow values defined as "0px red" or "0px 0px 10px rgb(255,0,0)" or "0px 0px 20px 20px #F00" and we need to ensure that what we get back is described with 4 numbers and a color. This allows us to feed it into the _parseComplex() method and split the values up appropriately. The neat thing about this _getFormatter() function is that the dflt defines a pattern as well as a default, so for example, _getFormatter("0px 0px 0px 0px #777", true) not only sets the default as 0px for all distances and #777 for the color, but also sets the pattern such that 4 numbers and a color will always get returned. 3808 * @param {!string} dflt The default value and pattern to follow. So "0px 0px 0px 0px #777" will ensure that 4 numbers and a color will always get returned. 3809 * @param {boolean=} clr If true, the values should be searched for color-related data. For example, boxShadow values typically contain a color whereas borderRadius don't. 3810 * @param {boolean=} collapsible If true, the value is a top/left/right/bottom style one that acts like margin or padding, where if only one value is received, it's used for all 4; if 2 are received, the first is duplicated for 3rd (bottom) and the 2nd is duplicated for the 4th spot (left), etc. 3811 * @return {Function} formatter function 3812 */ 3813 var _getFormatter = function(dflt, clr, collapsible, multi) { 3814 if (dflt == null) { 3815 return function(v) {return v;}; 3816 } 3817 var dColor = clr ? (dflt.match(_colorExp) || [""])[0] : "", 3818 dVals = dflt.split(dColor).join("").match(_valuesExp) || [], 3819 pfx = dflt.substr(0, dflt.indexOf(dVals[0])), 3820 sfx = (dflt.charAt(dflt.length - 1) === ")") ? ")" : "", 3821 delim = (dflt.indexOf(" ") !== -1) ? " " : ",", 3822 numVals = dVals.length, 3823 dSfx = (numVals > 0) ? dVals[0].replace(_numExp, "") : "", 3824 formatter; 3825 if (!numVals) { 3826 return function(v) {return v;}; 3827 } 3828 if (clr) { 3829 formatter = function(v) { 3830 var color, vals, i, a; 3831 if (typeof(v) === "number") { 3832 v += dSfx; 3833 } else if (multi && _commasOutsideParenExp.test(v)) { 3834 a = v.replace(_commasOutsideParenExp, "|").split("|"); 3835 for (i = 0; i < a.length; i++) { 3836 a[i] = formatter(a[i]); 3837 } 3838 return a.join(","); 3839 } 3840 color = (v.match(_colorExp) || [dColor])[0]; 3841 vals = v.split(color).join("").match(_valuesExp) || []; 3842 i = vals.length; 3843 if (numVals > i--) { 3844 while (++i < numVals) { 3845 vals[i] = collapsible ? vals[(((i - 1) / 2) | 0)] : dVals[i]; 3846 } 3847 } 3848 return pfx + vals.join(delim) + delim + color + sfx + (v.indexOf("inset") !== -1 ? " inset" : ""); 3849 }; 3850 return formatter; 3851 3852 } 3853 formatter = function(v) { 3854 var vals, a, i; 3855 if (typeof(v) === "number") { 3856 v += dSfx; 3857 } else if (multi && _commasOutsideParenExp.test(v)) { 3858 a = v.replace(_commasOutsideParenExp, "|").split("|"); 3859 for (i = 0; i < a.length; i++) { 3860 a[i] = formatter(a[i]); 3861 } 3862 return a.join(","); 3863 } 3864 vals = v.match(_valuesExp) || []; 3865 i = vals.length; 3866 if (numVals > i--) { 3867 while (++i < numVals) { 3868 vals[i] = collapsible ? vals[(((i - 1) / 2) | 0)] : dVals[i]; 3869 } 3870 } 3871 return pfx + vals.join(delim) + sfx; 3872 }; 3873 return formatter; 3874 }, 3875 3876 /** 3877 * @private returns a formatter function that's used for edge-related values like marginTop, marginLeft, paddingBottom, paddingRight, etc. Just pass a comma-delimited list of property names related to the edges. 3878 * @param {!string} props a comma-delimited list of property names in order from top to left, like "marginTop,marginRight,marginBottom,marginLeft" 3879 * @return {Function} a formatter function 3880 */ 3881 _getEdgeParser = function(props) { 3882 props = props.split(","); 3883 return function(t, e, p, cssp, pt, plugin, vars) { 3884 var a = (e + "").split(" "), 3885 i; 3886 vars = {}; 3887 for (i = 0; i < 4; i++) { 3888 vars[props[i]] = a[i] = a[i] || a[(((i - 1) / 2) >> 0)]; 3889 } 3890 return cssp.parse(t, vars, pt, plugin); 3891 }; 3892 }, 3893 3894 // @private used when other plugins must tween values first, like BezierPlugin or ThrowPropsPlugin, etc. That plugin's setRatio() gets called first so that the values are updated, and then we loop through the MiniPropTweens which handle copying the values into their appropriate slots so that they can then be applied correctly in the main CSSPlugin setRatio() method. Remember, we typically create a proxy object that has a bunch of uniquely-named properties that we feed to the sub-plugin and it does its magic normally, and then we must interpret those values and apply them to the css because often numbers must get combined/concatenated, suffixes added, etc. to work with css, like boxShadow could have 4 values plus a color. 3895 _setPluginRatio = _internals._setPluginRatio = function(v) { 3896 this.plugin.setRatio(v); 3897 var d = this.data, 3898 proxy = d.proxy, 3899 mpt = d.firstMPT, 3900 min = 0.000001, 3901 val, pt, i, str, p; 3902 while (mpt) { 3903 val = proxy[mpt.v]; 3904 if (mpt.r) { 3905 val = mpt.r(val); 3906 } else if (val < min && val > -min) { 3907 val = 0; 3908 } 3909 mpt.t[mpt.p] = val; 3910 mpt = mpt._next; 3911 } 3912 if (d.autoRotate) { 3913 d.autoRotate.rotation = d.mod ? d.mod.call(this._tween, proxy.rotation, this.t, this._tween) : proxy.rotation; //special case for ModifyPlugin to hook into an auto-rotating bezier 3914 } 3915 //at the end, we must set the CSSPropTween's "e" (end) value dynamically here because that's what is used in the final setRatio() method. Same for "b" at the beginning. 3916 if (v === 1 || v === 0) { 3917 mpt = d.firstMPT; 3918 p = (v === 1) ? "e" : "b"; 3919 while (mpt) { 3920 pt = mpt.t; 3921 if (!pt.type) { 3922 pt[p] = pt.s + pt.xs0; 3923 } else if (pt.type === 1) { 3924 str = pt.xs0 + pt.s + pt.xs1; 3925 for (i = 1; i < pt.l; i++) {
3926 str += pt["xn"+i] + pt["xs"+(i+1)]; 3927 } 3928 pt[p] = str; 3929 } 3930 mpt = mpt._next; 3931 } 3932 } 3933 }, 3934 3935 /** 3936 * @private @constructor Used by a few SpecialProps to hold important values for proxies. For example, _parseToProxy() creates a MiniPropTween instance for each property that must get tweened on the proxy, and we record the original property name as well as the unique one we create for the proxy, plus whether or not the value needs to be rounded plus the original value. 3937 * @param {!Object} t target object whose property we're tweening (often a CSSPropTween) 3938 * @param {!string} p property name 3939 * @param {(number|string|object)} v value 3940 * @param {MiniPropTween=} next next MiniPropTween in the linked list 3941 * @param {boolean=} r if true, the tweened value should be rounded to the nearest integer 3942 */ 3943 MiniPropTween = function(t, p, v, next, r) { 3944 this.t = t; 3945 this.p = p; 3946 this.v = v; 3947 this.r = r; 3948 if (next) { 3949 next._prev = this; 3950 this._next = next; 3951 } 3952 }, 3953 3954 /** 3955 * @private Most other plugins (like BezierPlugin and ThrowPropsPlugin and others) can only tween numeric values, but CSSPlugin must accommodate special values that have a bunch of extra data (like a suffix or strings between numeric values, etc.). For example, boxShadow has values like "10px 10px 20px 30px rgb(255,0,0)" which would utterly confuse other plugins. This method allows us to split that data apart and grab only the numeric data and attach it to uniquely-named properties of a generic proxy object ({}) so that we can feed that to virtually any plugin to have the numbers tweened. However, we must also keep track of which properties from the proxy go with which CSSPropTween values and instances. So we create a linked list of MiniPropTweens. Each one records a target (the original CSSPropTween), property (like "s" or "xn1" or "xn2") that we're tweening and the unique property name that was used for the proxy (like "boxShadow_xn1" and "boxShadow_xn2") and whether or not they need to be rounded. That way, in the _setPluginRatio() method we can simply copy the values over from the proxy to the CSSPropTween instance(s). Then, when the main CSSPlugin setRatio() method runs and applies the CSSPropTween values accordingly, they're updated nicely. So the external plugin tweens the numbers, _setPluginRatio() copies them over, and setRatio() acts normally, applying css-specific values to the element. 3956 * This method returns an object that has the following properties:
3957 * - proxy: a generic object containing the starting values for all the properties that will be tweened by the external plugin. This is what we feed to the external _onInitTween() as the target 3958 * - end: a generic object containing the ending values for all the properties that will be tweened by the external plugin. This is what we feed to the external plugin's _onInitTween() as the destination values 3959 * - firstMPT: the first MiniPropTween in the linked list 3960 * - pt: the first CSSPropTween in the linked list that was created when parsing. If shallow is true, this linked list will NOT attach to the one passed into the _parseToProxy() as the "pt" (4th) parameter. 3961 * @param {!Object} t target object to be tweened 3962 * @param {!(Object|string)} vars the object containing the information about the tweening values (typically the end/destination values) that should be parsed 3963 * @param {!CSSPlugin} cssp The CSSPlugin instance 3964 * @param {CSSPropTween=} pt the next CSSPropTween in the linked list 3965 * @param {TweenPlugin=} plugin the external TweenPlugin instance that will be handling tweening the numeric values 3966 * @param {boolean=} shallow if true, the resulting linked list from the parse will NOT be attached to the CSSPropTween that was passed in as the "pt" (4th) parameter. 3967 * @return An object containing the following properties: proxy, end, firstMPT, and pt (see above for descriptions) 3968 */ 3969 _parseToProxy = _internals._parseToProxy = function(t, vars, cssp, pt, plugin, shallow) { 3970 var bpt = pt, 3971 start = {}, 3972 end = {}, 3973 transform = cssp._transform, 3974 oldForce = _forcePT, 3975 i, p, xp, mpt, firstPT; 3976 cssp._transform = null; 3977 _forcePT = vars; 3978 pt = firstPT = cssp.parse(t, vars, pt, plugin); 3979 _forcePT = oldForce; 3980 //break off from the linked list so the new ones are isolated. 3981 if (shallow) { 3982 cssp._transform = transform; 3983 if (bpt) { 3984 bpt._prev = null; 3985 if (bpt._prev) { 3986 bpt._prev._next = null; 3987 } 3988 } 3989 } 3990 while (pt && pt !== bpt) { 3991 if (pt.type <= 1) { 3992 p = pt.p; 3993 end[p] = pt.s + pt.c; 3994 start[p] = pt.s; 3995 if (!shallow) { 3996 mpt = new MiniPropTween(pt, "s", p, mpt, pt.r); 3997 pt.c = 0; 3998 } 3999 if (pt.type === 1) { 4000 i = pt.l; 4001 while (--i > 0) { 4002 xp = "xn" + i; 4003 p = pt.p + "_" + xp; 4004 end[p] = pt.data[xp]; 4005 start[p] = pt[xp]; 4006 if (!shallow) { 4007 mpt = new MiniPropTween(pt, xp, p, mpt, pt.rxp[xp]); 4008 } 4009 } 4010 } 4011 } 4012 pt = pt._next; 4013 } 4014 return {proxy:start, end:end, firstMPT:mpt, pt:firstPT}; 4015 }, 4016 4017 4018 4019 /** 4020 * @constructor Each property that is tweened has at least one CSSPropTween associated with it. These instances store important information like the target, property, starting value, amount of change, etc. They can also optionally have a number of "extra" strings and numeric values named xs1, xn1, xs2, xn2, xs3, xn3, etc. where "s" indicates string and "n" indicates number. These can be pieced together in a complex-value tween (type:1) that has alternating types of data like a string, number, string, number, etc. For example, boxShadow could be "5px 5px 8px rgb(102, 102, 51)". In that value, there are 6 numbers that may need to tween and then pieced back together into a string again with spaces, suffixes, etc. xs0 is special in that it stores the suffix for standard (type:0) tweens, -OR- the first string (prefix) in a complex-value (type:1) CSSPropTween -OR- it can be the non-tweening value in a type:-1 CSSPropTween. We do this to conserve memory. 4021 * CSSPropTweens have the following optional properties as well (not defined through the constructor): 4022 * - l: Length in terms of the number of extra properties that the CSSPropTween has (default: 0). For example, for a boxShadow we may need to tween 5 numbers in which case l would be 5; Keep in mind that the start/end values for the first number that's tweened are always stored in the s and c properties to conserve memory. All additional values thereafter are stored in xn1, xn2, etc. 4023 * - xfirst: The first instance of any sub-CSSPropTweens that are tweening properties of this instance. For example, we may split up a boxShadow tween so that there's a main CSSPropTween of type:1 that has various xs* and xn* values associated with the h-shadow, v-shadow, blur, color, etc. Then we spawn a CSSPropTween for each of those that has a higher priority and runs BEFORE the main CSSPropTween so that the values are all set by the time it needs to re-assemble them. The xfirst gives us an easy way to identify the first one in that chain which typically ends at the main one (because they're all prepende to the linked list) 4024 * - plugin: The TweenPlugin instance that will handle the tweening of any complex values. For example, sometimes we don't want to use normal subt
4024weens (like xfirst refers to) to tween the values - we might want ThrowPropsPlugin or BezierPlugin some other plugin to do the actual tweening, so we create a plugin instance and store a reference here. We need this reference so that if we get a request to round values or disable a tween, we can pass along that request. 4025 * - data: Arbitrary data that needs to be stored with the CSSPropTween. Typically if we're going to have a plugin handle the tweening of a complex-value tween, we create a generic object that stores the END values that we're tweening to and the CSSPropTween's xs1, xs2, etc. have the starting values. We store that object as data. That way, we can simply pass that object to the plugin and use the CSSPropTween as the target. 4026 * - setRatio: Only used for type:2 tweens that require custom functionality. In this case, we call the CSSPropTween's setRatio() method and pass the ratio each time the tween updates. This isn't quite as efficient as doing things directly in the CSSPlugin's setRatio() method, but it's very convenient and flexible. 4027 * @param {!Object} t Target object whose property will be tweened. Often a DOM element, but not always. It could be anything. 4028 * @param {string} p Property to tween (name). For example, to tween element.width, p would be "width". 4029 * @param {number} s Starting numeric value 4030 * @param {number} c Change in numeric value over the course of the entire tween. For example, if element.width starts at 5 and should end at 100, c would be 95. 4031 * @param {CSSPropTween=} next The next CSSPropTween in the linked list. If one is defined, we will define its _prev as the new instance, and the new instance's _next will be pointed at it. 4032 * @param {number=} type The type of CSSPropTween where -1 = a non-tweening value, 0 = a standard simple tween, 1 = a complex value (like one that has multiple numbers in a comma- or space-delimited string like border:"1px solid red"), and 2 = one that uses a custom setRatio function that does all of the work of applying the values on each update. 4033 * @param {string=} n Name of the property that should be used for overwriting purposes which is typically the same as p but not always. For example, we may need to create a subtween for the 2nd part of a "clip:rect(...)" tween in which case "p" might be xs1 but "n" is still "clip" 4034 * @param {boolean=} r If true, the value(s) should be rounded 4035 * @param {number=} pr Priority in the linked list order. Higher priority CSSPropTweens will be updated before lower priority ones. The default priority is 0. 4036 * @param {string=} b Beginning value. We store this to ensure that it is EXACTLY what it was when the tween began without any risk of interpretation issues. 4037 * @param {string=} e Ending value. We store this to ensure that it is EXACTLY what the user defined at the end of the tween without any risk of interpretation issues. 4038 */ 4039 CSSPropTween = _internals.CSSPropTween = function(t, p, s, c, next, type, n, r, pr, b, e) { 4040 this.t = t; //target 4041 this.p = p; //property 4042 this.s = s; //starting value 4043 this.c = c; //change value 4044 this.n = n || p; //name that this CSSPropTween should be associated to (usually the same as p, but not always - n is what overwriting looks at) 4045 if (!(t instanceof CSSPropTween)) { 4046 _overwriteProps.push(this.n); 4047 } 4048 this.r = !r ? r : (typeof(r) === "function") ? r : Math.round; //round (boolean) 4049 this.type = type || 0; //0 = normal tween, -1 = non-tweening (in which case xs0 will be applied to the target's property, like tp.t[tp.p] = tp.xs0), 1 = complex-value SpecialProp, 2 = custom setRatio() that does all the work 4050 if (pr) { 4051 this.pr = pr; 4052 _hasPriority = true; 4053 } 4054 this.b = (b === undefined) ? s : b; 4055 this.e = (e === undefined) ? s + c : e; 4056 if (next) { 4057 this._next = next; 4058 next._prev = this; 4059 } 4060 }, 4061 4062 _addNonTweeningNumericPT = function(target, prop, start, end, next, overwriteProp) { //cleans up some code redundancies and helps minification. Just a fast way to add a NUMERIC non-tweening CSSPropTween
4063 var pt = new CSSPropTween(target, prop, start, end - start, next, -1, overwriteProp); 4064 pt.b = start; 4065 pt.e = pt.xs0 = end; 4066 return pt; 4067 }, 4068 4069 /** 4070 * Takes a target, the beginning value and ending value (as strings) and parses them into a CSSPropTween (possibly with child CSSPropTweens) that accommodates multiple numbers, colors, comma-delimited values, etc. For example: 4071 * sp.parseComplex(element, "boxShadow", "5px 10px 20px rgb(255,102,51)", "0px 0px 0px red", true, "0px 0px 0px rgb(0,0,0,0)", pt); 4072 * It will walk through the beginning and ending values (which should be in the same format with the same number and type of values) and figure out which parts are numbers, what strings separate the numeric/tweenable values, and then create the CSSPropTweens accordingly. If a plugin is defined, no child CSSPropTweens will be created. Instead, the ending values will be stored in the "data" property of the returned CSSPropTween like: {s:-5, xn1:-10, xn2:-20, xn3:255, xn4:0, xn5:0} so that it can be fed to any other plugin and it'll be plain numeric tweens but the recomposition of the complex value will be handled inside CSSPlugin's setRatio(). 4073 * If a setRatio is defined, the type of the CSSPropTween will be set to 2 and recomposition of the values will be the responsibility of that method. 4074 * 4075 * @param {!Object} t Target whose property will be tweened 4076 * @param {!string} p Property that will be tweened (its name, like "left" or "backgroundColor" or "boxShadow") 4077 * @param {string} b Beginning value 4078 * @param {string} e Ending value 4079 * @param {boolean} clrs If true, the value could contain a color value like "rgb(255,0,0)" or "#F00" or "red". The default is false, so no colors will be recognized (a performance optimization) 4080 * @param {(string|number|Object)} dflt The default beginning value that should be used if no valid beginning value is defined or if the number of values inside the complex beginning and ending values don't match 4081 * @param {?CSSPropTween} pt CSSPropTween instance that is the current head of the linked list (we'll prepend to this). 4082 * @param {number=} pr Priority in the linked list order. Higher priority properties will be updated before lower priority ones. The default priority is 0. 4083 * @param {TweenPlugin=} plugin If a plugin should handle the tweening of extra properties, pass the plugin instance here. If one is defined, then NO subtweens will be created for any extra properties (the properties will be created - just not additional CSSPropTween instances to tween them) because the plugin is expected to do so. However, the end values WILL be populated in the "data" property, like {s:100, xn1:50, xn2:300} 4084 * @param {function(number)=} setRatio If values should be set in a custom function instead of being pieced together in a type:1 (complex-value) CSSPropTween, define that custom function here. 4085 * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parseComplex() call. 4086 */ 4087 _parseComplex = CSSPlugin.parseComplex = function(t, p, b, e, clrs, dflt, pt, pr, plugin, setRatio) { 4088 //DEBUG: _log("parseComplex: "+p+", b: "+b+", e: "+e); 4089 b = b || dflt || ""; 4090 if (typeof(e) === "function") { 4091 e = e(_index, _target); 4092 } 4093 pt = new CSSPropTween(t, p, 0, 0, pt, (setRatio ? 2 : 1), null, false, pr, b, e); 4094 e += ""; //ensures it's a string 4095 if (clrs && _colorExp.test(e + b)) { //if colors are found, normalize the formatting to rgba() or hsla(). 4096 e = [b, e]; 4097 CSSPlugin.colorStringFilter(e); 4098 b = e[0]; 4099 e = e[1]; 4100 } 4101 var ba = b.split(", ").join(",").split(" "), //beginning array 4102 ea = e.split(", ").join(",").split(" "), //ending array 4103 l = ba.length, 4104 autoRound = (_autoRound !== false), 4105 i, xi, ni, bv, ev, bnums, enums, bn, hasAlpha, temp, cv, str, useHSL; 4106 if (e.indexOf(",") !== -1 || b.indexOf(",") !== -1) { 4107 if ((e + b).indexOf("rgb") !== -1 || (e + b).indexOf("hsl") !== -1) { //keep rgb(), rgba(), hsl(), and hsla() values together! (remember, we're splitting on spaces) 4108 ba = ba.join(" ").replace(_commasOutsideParenExp, ", ").split(" "); 4109 ea = ea.join(" ").replace(_commasOutsideParenExp, ", ").split(" "); 4110 } else { 4111 ba = ba.join(" ").split(",").join(", ").split(" "); 4112 ea = ea.join(" ").split(",").join(", ").split(" "); 4113 } 4114 l = ba.length; 4115 } 4116 if (l !== ea.length) { 4117 //DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")"); 4118 ba = (dflt || "").split(" "); 4119 l = ba.length; 4120 } 4121 pt.plugin = plugin; 4122 pt.setRatio = setRatio; 4123 _colorExp.lastIndex = 0; 4124 for (i = 0; i < l; i++) { 4125 bv = ba[i]; 4126 ev = ea[i] + ""; 4127 bn = parseFloat(bv); 4128 //if the value begins with a number (most common). It's fine if it has a suffix like px 4129 if (bn || bn === 0) { 4130 pt.appendXtra("", bn, _parseChange(ev, bn), ev.replace(_relNumExp, ""), (autoRound && ev.indexOf("px") !== -1) ? Math.round : false, true); 4131 4132 //if the value is a color 4133 } else if (clrs && _colorExp.test(bv)) { 4134 str = ev.indexOf(")") + 1; 4135 str = ")" + (str ? ev.substr(str) : ""); //if there's a comma or ) at the end, retain it. 4136 useHSL = (ev.indexOf("hsl") !== -1 && _supportsOpacity); 4137 temp = ev; //original string value so we can look for any prefix later. 4138 bv = _parseColor(bv, useHSL); 4139 ev = _parseColor(ev, useHSL); 4140 hasAlpha = (bv.length + ev.length > 6); 4141 if (hasAlpha && !_supportsOpacity && ev[3] === 0) { //older versions of IE don't support rgba(), so if the destination alpha is 0, just use "transparent" for the end color 4142 pt["xs" + pt.l] += pt.l ? " transparent" : "transparent";
4143 pt.e = pt.e.split(ea[i]).join("transparent"); 4144 } else { 4145 if (!_supportsOpacity) { //old versions of IE don't support rgba(). 4146 hasAlpha = false; 4147 } 4148 if (useHSL) { 4149 pt.appendXtra(temp.substr(0, temp.indexOf("hsl")) + (hasAlpha ? "hsla(" : "hsl("), bv[0], _parseChange(ev[0], bv[0]), ",", false, true) 4150 .appendXtra("", bv[1], _parseChange(ev[1], bv[1]), "%,", false) 4151 .appendXtra("", bv[2], _parseChange(ev[2], bv[2]), (hasAlpha ? "%," : "%" + str), false); 4152 } else { 4153 pt.appendXtra(temp.substr(0, temp.indexOf("rgb")) + (hasAlpha ? "rgba(" : "rgb("), bv[0], ev[0] - bv[0], ",", Math.round, true) 4154 .appendXtra("", bv[1], ev[1] - bv[1], ",", Math.round) 4155 .appendXtra("", bv[2], ev[2] - bv[2], (hasAlpha ? "," : str), Math.round); 4156 } 4157 4158 if (hasAlpha) { 4159 bv = (bv.length < 4) ? 1 : bv[3]; 4160 pt.appendXtra("", bv, ((ev.length < 4) ? 1 : ev[3]) - bv, str, false); 4161 } 4162 } 4163 _colorExp.lastIndex = 0; //otherwise the test() on the RegExp could move the lastIndex and taint future results. 4164 4165 } else { 4166 bnums = bv.match(_numExp); //gets each group of numbers in the beginning value string and drops them into an array 4167 4168 //if no number is found, treat it as a non-tweening value and just append the string to the current xs. 4169 if (!bnums) { 4170 pt["xs" + pt.l] += (pt.l || pt["xs" + pt.l]) ? " " + ev : ev; 4171 4172 //loop through all the numbers that are found and construct the extra values on the pt. 4173 } else { 4174 enums = ev.match(_relNumExp); //get each group of numbers in the end value string and drop them into an array. We allow relative values too, like +=50 or -=.5 4175 if (!enums || enums.length !== bnums.length) { 4176 //DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")"); 4177 return pt; 4178 } 4179 ni = 0; 4180 for (xi = 0; xi < bnums.length; xi++) { 4181 cv = bnums[xi]; 4182 temp = bv.indexOf(cv, ni); 4183 pt.appendXtra(bv.substr(ni, temp - ni), Number(cv), _parseChange(enums[xi], cv), "", (autoRound && bv.substr(temp + cv.length, 2) === "px") ? Math.round : false, (xi === 0)); 4184 ni = temp + cv.length; 4185 } 4186 pt["xs" + pt.l] += bv.substr(ni); 4187 } 4188 } 4189 } 4190 //if there are relative values ("+=" or "-=" prefix), we need to adjust the ending value to eliminate the prefixes and combine the values properly. 4191 if (e.indexOf("=") !== -1) if (pt.data) { 4192 str = pt.xs0 + pt.data.s; 4193 for (i = 1; i < pt.l; i++) { 4194 str += pt["xs" + i] + pt.data["xn" + i]; 4195 } 4196 pt.e = str + pt["xs" + i]; 4197 } 4198 if (!pt.l) { 4199 pt.type = -1; 4200 pt.xs0 = pt.e; 4201 } 4202 return pt.xfirst || pt; 4203 }, 4204 i = 9; 4205 4206 4207 p = CSSPropTween.prototype; 4208 p.l = p.pr = 0; //length (number of extra properties like xn1, xn2, xn3, etc. 4209 while (--i > 0) { 4210 p["xn" + i] = 0; 4211 p["xs" + i] = ""; 4212 } 4213 p.xs0 = ""; 4214 p._next = p._prev = p.xfirst = p.data = p.plugin = p.setRatio = p.rxp = null; 4215 4216 4217 /** 4218 * Appends and extra tweening value to a CSSPropTween and automatically manages any prefix and suffix strings. The first extra value is stored in the s and c of the main CSSPropTween instance, but thereafter any extras are stored in the xn1, xn2, xn3, etc. The prefixes and suffixes are stored in the xs0, xs1, xs2, etc. properties. For example, if I walk through a clip value like "rect(10px, 5px, 0px, 20px)", the values would be stored like this: 4219 * xs0:"rect(", s:10, xs1:"px, ", xn1:5, xs2:"px, ", xn2:0, xs3:"px, ", xn3:20, xn4:"px)" 4220 * And they'd all get joined together when the CSSPlugin renders (in the setRatio() method). 4221 * @param {string=} pfx Prefix (if any) 4222 * @param {!number} s Starting value 4223 * @param {!number} c Change in numeric value over the course of the entire tween. For example, if the start is 5 and the end is 100, the change would be 95. 4224 * @param {string=} sfx Suffix (if any) 4225 * @param {boolean=} r Round (if true). 4226 * @param {boolean=} pad If true, this extra value should be separated by the previous one by a space. If there is no previous extra and pad is true, it will automatically drop the space. 4227 * @return {CSSPropTween} returns itself so that multiple methods can be chained together. 4228 */ 4229 p.appendXtra = function(pfx, s, c, sfx, r, pad) { 4230 var pt = this, 4231 l = pt.l; 4232 pt["xs" + l] += (pad && (l || pt["xs" + l])) ? " " + pfx : pfx || ""; 4233 if (!c) if (l !== 0 && !pt.plugin) { //typically we'll combine non-changing values right into the xs to optimize performance, but we don't combine them when there's a plugin that will be tweening the values because it may depend on the values being split apart, like for a bezier, if a value doesn't change between the first and second iteration but then it does on the 3rd, we'll run into trouble because there's no xn slot for that value! 4234 pt["xs" + l] += s + (sfx || ""); 4235 return pt; 4236 } 4237 pt.l++; 4238 pt.type = pt.setRatio ? 2 : 1; 4239 pt["xs" + pt.l] = sfx || ""; 4240 if (l > 0) { 4241 pt.data["xn" + l] = s + c; 4242 pt.rxp["xn" + l] = r; //round extra property (we need to tap into this in the _parseToProxy() method) 4243 pt["xn" + l] = s; 4244 if (!pt.plugin) { 4245 pt.xfirst = new CSSPropTween(pt, "xn" + l, s, c, pt.xfirst || pt, 0, pt.n, r, pt.pr); 4246 pt.xfirst.xs0 = 0; //just to ensure that the property stays numeric which helps modern browsers speed up processing. Remember, in the setRatio() method, we do pt.t[pt.p] = val + pt.xs0 so if pt.xs0 is "" (the default), it'll cast the end value as a string. When a property is a number sometimes and a string sometimes, it prevents the compiler from locking in the data type, slowing things down slightly. 4247 } 4248 return pt; 4249 } 4250 pt.data = {s:s + c}; 4251 pt.rxp = {}; 4252 pt.s = s; 4253 pt.c = c; 4254 pt.r = r; 4255 return pt; 4256 }; 4257 4258 /** 4259 * @constructor A SpecialProp is basically a css property that needs to be treated in a non-standard way, like if it may contain a complex value like boxShadow:"5px 10px 15px rgb(255, 102, 51)" or if it is associated with another plugin like ThrowPropsPlugin or BezierPlugin. Every SpecialProp is associated with a particular property name like "boxShadow" or "throwProps" or "bezier" and it will intercept those values in the vars object that's passed to the CSSPlugin and handle them accordingly. 4260 * @param {!string} p Property name (like "boxShadow" or "throwProps") 4261 * @param {Object=}
4261 options An object containing any of the following configuration options: 4262 * - defaultValue: the default value 4263 * - parser: A function that should be called when the associated property name is found in the vars. This function should return a CSSPropTween instance and it should ensure that it is properly inserted into the linked list. It will receive 4 paramters: 1) The target, 2) The value defined in the vars, 3) The CSSPlugin instance (whose _firstPT should be used for the linked list), and 4) A computed style object if one was calculated (this is a speed optimization that allows retrieval of starting values quicker) 4264 * - formatter: a function that formats any value received for this special property (for example, boxShadow could take "5px 5px red" and format it to "5px 5px 0px 0px red" so that both the beginning and ending values have a common order and quantity of values.) 4265 * - prefix: if true, we'll determine whether or not this property requires a vendor prefix (like Webkit or Moz or ms or O) 4266 * - color: set this to true if the value for this SpecialProp may contain color-related values like rgb(), rgba(), etc. 4267 * - priority: priority in the linked list order. Higher priority SpecialProps will be updated before lower priority ones. The default priority is 0. 4268 * - multi: if true, the formatter should accommodate a comma-delimited list of values, like boxShadow could have multiple boxShadows listed out. 4269 * - collapsible: if true, the formatter should treat the value like it's a top/right/bottom/left value that could be collapsed, like "5px" would apply to all, "5px, 10px" would use 5px for top/bottom and 10px for right/left, etc. 4270 * - keyword: a special keyword that can [optionally] be found inside the value (like "inset" for boxShadow). This allows us to validate beginning/ending values to make sure they match (if the keyword is found in one, it'll be added to the other for consistency by default). 4271 */ 4272 var SpecialProp = function(p, options) { 4273 options = options || {}; 4274 this.p = options.prefix ? _checkPropPrefix(p) || p : p; 4275 _specialProps[p] = _specialProps[this.p] = this; 4276 this.format = options.formatter || _getFormatter(options.defaultValue, options.color, options.collapsible, options.multi); 4277 if (options.parser) { 4278 this.parse = options.parser; 4279 } 4280 this.clrs = options.color; 4281 this.multi = options.multi; 4282 this.keyword = options.keyword; 4283 this.dflt = options.defaultValue; 4284 this.pr = options.priority || 0; 4285 }, 4286 4287 //shortcut for creating a new SpecialProp that can accept multiple properties as a comma-delimited list (helps minification). dflt can be an array for multiple values (we don't do a comma-delimited list because the default value may contain commas, like rect(0px,0px,0px,0px)). We attach this method to the SpecialProp class/object instead of using a private _createSpecialProp() method so that we can tap into it externally if necessary, like from another plugin. 4288 _registerComplexSpecialProp = _internals._registerComplexSpecialProp = function(p, options, defaults) { 4289 if (typeof(options) !== "object") { 4290 options = {parser:defaults}; //to make backwards compatible with older versions of BezierPlugin and ThrowPropsPlugin 4291 } 4292 var a = p.split(","), 4293 d = options.defaultValue, 4294 i, temp; 4295 defaults = defaults || [d]; 4296 for (i = 0; i < a.length; i++) { 4297 options.prefix = (i === 0 && options.prefix); 4298 options.defaultValue = defaults[i] || d; 4299 temp = new SpecialProp(a[i], options); 4300 } 4301 }, 4302 4303 //creates a placeholder special prop for a plugin so that the property gets caught the first time a tween of it is attempted, and at that time it makes the plugin register itself, thus taking over for all future tweens of that property. This allows us to not mandate that things load in a particular order and it also allows us to log() an error that informs the user when they attempt to tween an external plugin-related property without loading its .js file. 4304 _registerPluginProp = _internals._registerPluginProp = function(p) { 4305 if (!_specialProps[p]) { 4306 var pluginName = p.charAt(0).toUpperCase() + p.substr(1) + "Plugin"; 4307 _registerComplexSpecialProp(p, {parser:function(t, e, p, cssp, pt, plugin, vars) { 4308 var pluginClass = _globals.com.greensock.plugins[pluginName]; 4309 if (!pluginClass) { 4310 _log("Error: " + pluginName + " js file not loaded."); 4311 return pt; 4312 } 4313 pluginClass._cssRegister(); 4314 return _specialProps[p].parse(t, e, p, cssp, pt, plugin, vars); 4315 }}); 4316 } 4317 }; 4318 4319 4320 p = SpecialProp.prototype; 4321 4322 /** 4323 * Alias for _parseComplex() that automatically plugs in certain values for this SpecialProp, like its property name, whether or not colors should be sensed, the default value, and priority. It also looks for any keyword that the SpecialProp defines (like "inset" for boxSh
4323adow) and ensures that the beginning and ending values have the same number of values for SpecialProps where multi is true (like boxShadow and textShadow can have a comma-delimited list) 4324 * @param {!Object} t target element 4325 * @param {(string|number|object)} b beginning value 4326 * @param {(string|number|object)} e ending (destination) value 4327 * @param {CSSPropTween=} pt next CSSPropTween in the linked list 4328 * @param {TweenPlugin=} plugin If another plugin will be tweening the complex value, that TweenPlugin instance goes here. 4329 * @param {function=} setRatio If a custom setRatio() method should be used to handle this complex value, that goes here. 4330 * @return {CSSPropTween=} First CSSPropTween in the linked list 4331 */ 4332 p.parseComplex = function(t, b, e, pt, plugin, setRatio) { 4333 var kwd = this.keyword, 4334 i, ba, ea, l, bi, ei; 4335 //if this SpecialProp's value can contain a comma-delimited list of values (like boxShadow or textShadow), we must parse them in a special way, and look for a keyword (like "inset" for boxShadow) and ensure that the beginning and ending BOTH have it if the end defines it as such. We also must ensure that there are an equal number of values specified (we can't tween 1 boxShadow to 3 for example) 4336 if (this.multi) if (_commasOutsideParenExp.test(e) || _commasOutsideParenExp.test(b)) { 4337 ba = b.replace(_commasOutsideParenExp, "|").split("|"); 4338 ea = e.replace(_commasOutsideParenExp, "|").split("|"); 4339 } else if (kwd) { 4340 ba = [b]; 4341 ea = [e]; 4342 } 4343 if (ea) { 4344 l = (ea.length > ba.length) ? ea.length : ba.length; 4345 for (i = 0; i < l; i++) { 4346 b = ba[i] = ba[i] || this.dflt; 4347 e = ea[i] = ea[i] || this.dflt; 4348 if (kwd) { 4349 bi = b.indexOf(kwd); 4350 ei = e.indexOf(kwd); 4351 if (bi !== ei) { 4352 if (ei === -1) { //if the keyword isn't in the end value, remove it from the beginning one. 4353 ba[i] = ba[i].split(kwd).join(""); 4354 } else if (bi === -1) { //if the keyword isn't in the beginning, add it. 4355 ba[i] += " " + kwd; 4356 } 4357 } 4358 } 4359 } 4360 b = ba.join(", "); 4361 e = ea.join(", "); 4362 } 4363 return _parseComplex(t, this.p, b, e, this.clrs, this.dflt, pt, this.pr, plugin, setRatio); 4364 }; 4365 4366 /** 4367 * Accepts a target and end value and spits back a CSSPropTween that has been inserted into the CSSPlugin's linked list and conforms with all the conventions we use internally, like type:-1, 0, 1, or 2, setting up any extra property tweens, priority, etc. For example, if we have a boxShadow SpecialProp and call: 4368 * this._firstPT = sp.parse(element, "5px 10px 20px rgb(2550,102,51)", "boxShadow", this); 4369 * It should figure out the starting value of the element's boxShadow, compare it to the provided end value and create all the necessary CSSPropTweens of the appropriate types to tween the boxShadow. The CSSPropTween that gets spit back should already be inserted into the linked list (the 4th parameter is the current head, so prepend to that). 4370 * @param {!Object} t Target object whose property is being tweened 4371 * @param {Object} e End value as provided in the vars object (typically a string, but not always - like a throwProps would be an object). 4372 * @param {!string} p Property name 4373 * @param {!CSSPlugin} cssp The CSSPlugin instance that should be associated with this tween. 4374 * @param {?CSSPropTween} pt The CSSPropTween that is the current head of the linked list (we'll prepend to it) 4375 * @param {TweenPlugin=} plugin If a plugin will be used to tween the parsed value, this is the plugin instance. 4376 * @param {Object=} vars Original vars object that contains the data for parsing. 4377 * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parse() call. 4378 */ 4379 p.parse = function(t, e, p, cssp, pt, plugin, vars) { 4380 return this.parseComplex(t.style, this.format(_getStyle(t, this.p, _cs, false, this.dflt)), this.format(e), pt, plugin); 4381 }; 4382 4383 /** 4384 * Registers a special property that should be intercepted from any "css" objects defined in tweens. This allows you to handle them however you want without CSSPlugin doing it for you. The 2nd parameter should be a function that accepts 3 parameters: 4385 * 1) Target object whose property should be tweened (typically a DOM element) 4386 * 2) The end/destination value (could be a string, number, object, or whatever you want) 4387 * 3) The tween instance (you probably don't need to worry about this, but it can be useful for looking up information like the duration) 4388 * 4389 * Then, your function should return a function which will be called each time the tween gets rendered, passing a numeric "ratio" parameter to your function that indicates the change factor (usually between 0 and 1). For example: 4390 * 4391 * CSSPlugin.registerSpecialProp("myCustomProp", function(target, value, tween) { 4392 * var start = target.style.width;
4393 * return function(ratio) { 4394 * target.style.width = (start + value * ratio) + "px"; 4395 * console.log("set width to " + target.style.width); 4396 * } 4397 * }, 0); 4398 * 4399 * Then, when I do this tween, it will trigger my special property: 4400 * 4401 * TweenLite.to(element, 1, {css:{myCustomProp:100}}); 4402 * 4403 * In the example, of course, we're just changing the width, but you can do anything you want. 4404 * 4405 * @param {!string} name Property name (or comma-delimited list of property names) that should be intercepted and handled by your function. For example, if I define "myCustomProp", then it would handle that portion of the following tween: TweenLite.to(element, 1, {css:{myCustomProp:100}}) 4406 * @param {!function(Object, Object, Object, string):function(number)} onInitTween The function that will be called when a tween of this special property is performed. The function will receive 4 parameters: 1) Target object that should be tweened, 2) Value that was passed to the tween, 3) The tween instance itself (rarely used), and 4) The property name that's being tweened. Your function should return a function that should be called on every update of the tween. That function will receive a single parameter that is a "change factor" value (typically between 0 and 1) indicating the amount of change as a ratio. You can use this to determine how to set the values appropriately in your function. 4407 * @param {number=} priority Priority that helps the engine determine the order in which to set the properties (default: 0). Higher priority properties will be updated before lower priority ones. 4408 */ 4409 CSSPlugin.registerSpecialProp = function(name, onInitTween, priority) { 4410 _registerComplexSpecialProp(name, {parser:function(t, e, p, cssp, pt, plugin, vars) { 4411 var rv = new CSSPropTween(t, p, 0, 0, pt, 2, p, false, priority); 4412 rv.plugin = plugin; 4413 rv.setRatio = onInitTween(t, e, cssp._tween, p); 4414 return rv; 4415 }, priority:priority}); 4416 }; 4417 4418 4419 4420 4421 4422 4423 //transform-related methods and properties 4424 CSSPlugin.useSVGTransformAttr = true; //Safari and Firefox both have some rendering bugs when applying CSS transforms to SVG elements, so default to using the "transform" attribute instead (users can override this). 4425 var _transformProps = ("scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent").split(","), 4426 _transformProp = _checkPropPrefix("transform"), //the Javascript (camelCase) transform property, like msTransform, WebkitTransform, MozTransform, or OTransform. 4427 _transformPropCSS = _prefixCSS + "transform", 4428 _transformOriginProp = _checkPropPrefix("transformOrigin"), 4429 _supports3D = (_checkPropPrefix("perspective") !== null), 4430 Transform = _internals.Transform = function() { 4431 this.perspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0; 4432 this.force3D = (CSSPlugin.defaultForce3D === false || !_supports3D) ? false : CSSPlugin.defaultForce3D || "auto"; 4433 }, 4434 _SVGElement = _gsScope.SVGElement, 4435 _useSVGTransformAttr, 4436 //Some browsers (like Firefox and IE) don't honor transform-origin properly in SVG elements, so we need to manually adjust the matrix accordingly. We feature detect here rather than always doing the conversion for certain browsers because they may fix the problem at some point in the future. 4437 4438 _createSVG = function(type, container, attributes) { 4439 var element = _doc.createElementNS("http://www.w3.org/2000/svg", type), 4440 reg = /([a-z])([A-Z])/g, 4441 p; 4442 for (p in attributes) { 4443 element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]); 4444 } 4445 container.appendChild(element); 4446 return element; 4447 }, 4448 _docElement = _doc.documentElement || {}, 4449 _forceSVGTransformAttr = (function() { 4450 //IE and Android stock don't support CSS transforms on SVG elements, so we must write them to the "transform" attribute. We populate this variable in the _parseTransform() method, and only if/when we come across an SVG element 4451 var force = _ieVers || (/Android/i.test(_agent) && !_gsScope.chrome), 4452 svg, rect, width; 4453 if (_doc.createElementNS && !force) { //IE8 and earlier doesn't support SVG anyway 4454 svg = _createSVG("svg", _docElement); 4455 rect = _createSVG("rect", svg, {width:100, height:50, x:100}); 4456 width = rect.getBoundingClientRect().width; 4457 rect.style[_transformOriginProp] = "50% 50%"; 4458 rect.style[_transformProp] = "scaleX(0.5)"; 4459 force = (width === rect.getBoundingClientRect().width && !(_is
4459Firefox && _supports3D)); //note: Firefox fails the test even though it does support CSS transforms in 3D. Since we can't push 3D stuff into the transform attribute, we force Firefox to pass the test here (as long as it does truly support 3D). 4460 _docElement.removeChild(svg); 4461 } 4462 return force; 4463 })(), 4464 _parseSVGOrigin = function(e, local, decoratee, absolute, smoothOrigin, skipRecord) { 4465 var tm = e._gsTransform, 4466 m = _getMatrix(e, true), 4467 v, x, y, xOrigin, yOrigin, a, b, c, d, tx, ty, determinant, xOriginOld, yOriginOld; 4468 if (tm) { 4469 xOriginOld = tm.xOrigin; //record the original values before we alter them. 4470 yOriginOld = tm.yOrigin; 4471 } 4472 if (!absolute || (v = absolute.split(" ")).length < 2) { 4473 b = e.getBBox(); 4474 if (b.x === 0 && b.y === 0 && b.width + b.height === 0) { //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case. 4475 b = {x: parseFloat(e.hasAttribute("x") ? e.getAttribute("x") : e.hasAttribute("cx") ? e.getAttribute("cx") : 0) || 0, y: parseFloat(e.hasAttribute("y") ? e.getAttribute("y") : e.hasAttribute("cy") ? e.getAttribute("cy") : 0) || 0, width:0, height:0}; 4476 } 4477 local = _parsePosition(local).split(" "); 4478 v = [(local[0].indexOf("%") !== -1 ? parseFloat(local[0]) / 100 * b.width : parseFloat(local[0])) + b.x, 4479 (local[1].indexOf("%") !== -1 ? parseFloat(local[1]) / 100 * b.height : parseFloat(local[1])) + b.y]; 4480 } 4481 decoratee.xOrigin = xOrigin = parseFloat(v[0]); 4482 decoratee.yOrigin = yOrigin = parseFloat(v[1]); 4483 if (absolute && m !== _identity2DMatrix) { //if svgOrigin is being set, we must invert the matrix and determine where the absolute point is, factoring in the current transforms. Otherwise, the svgOrigin would be based on the element's non-transformed position on the canvas. 4484 a = m[0]; 4485 b = m[1]; 4486 c = m[2]; 4487 d = m[3]; 4488 tx = m[4]; 4489 ty = m[5]; 4490 determinant = (a * d - b * c); 4491 if (determinant) { //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero. 4492 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + ((c * ty - d * tx) / determinant); 4493 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - ((a * ty - b * tx) / determinant); 4494 xOrigin = decoratee.xOrigin = v[0] = x; 4495 yOrigin = decoratee.yOrigin = v[1] = y; 4496 } 4497 } 4498 if (tm) { //avoid jump when transformOrigin is changed - adjust the x/y values accordingly 4499 if (skipRecord) { 4500 decoratee.xOffset = tm.xOffset; 4501 decoratee.yOffset = tm.yOffset; 4502 tm = decoratee; 4503 } 4504 if (smoothOrigin || (smoothOrigin !== false && CSSPlugin.defaultSmoothOrigin !== false)) { 4505 x = xOrigin - xOriginOld; 4506 y = yOrigin - yOriginOld; 4507 //originally, we simply adjusted the x and y values, but that would cause problems if, for example, you created a rotational tween part-way through an x/y tween. Managing the offset in a separate variable gives us ultimate flexibility. 4508 //tm.x -= x - (x * m[0] + y * m[2]); 4509 //tm.y -= y - (x * m[1] + y * m[3]); 4510 tm.xOffset += (x * m[0] + y * m[2]) - x; 4511 tm.yOffset += (x * m[1] + y * m[3]) - y; 4512 } else { 4513 tm.xOffset = tm.yOffset = 0; 4514 } 4515 } 4516 if (!skipRecord) { 4517 e.setAttribute("data-svg-origin", v.join(" ")); 4518 } 4519 }, 4520 _getBBoxHack = function(swapIfPossible) { //works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a <defs> element and/or <mask>. We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it). 4521 var svg = _createElement("svg", (this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns")) || "http://www.w3.org/2000/svg"), 4522 oldParent = this.parentNode, 4523 oldSibling = this.nextSibling, 4524 oldCSS = this.style.cssText, 4525 bbox; 4526 _docElement.appendChild(svg); 4527 svg.appendChild(this); 4528 this.style.display = "block"; 4529 if (swapIfPossible) { 4530 try { 4531 bbox = this.getBBox(); 4532 this._originalGetBBox = this.getBBox; 4533 this.getBBox = _getBBoxHack; 4534 } catch (e) { } 4535 } else if (this._originalGetBBox) { 4536 bbox = this._originalGetBBox(); 4537 } 4538 if (oldSibling) { 4539 oldParent.insertBefore(this, oldSibling); 4540 } else { 4541 oldParent.appendChild(this); 4542 } 4543 _docElement.removeChild(svg); 4544 this.style.cssText = oldCSS; 4545 return bbox; 4546 }, 4547 _getBBox = function(e) { 4548 try { 4549 return e.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a <symbol> or <defs>). https://bugzilla.mozilla.org/show_bug.cgi?id=612118 4550 } catch (error) { 4551 return _getBBoxHack.call(e, true); 4552 } 4553 }, 4554 _isSVG = function(e) { //reports if the element is an SVG on which getBBox() actually works 4555 return !!(_SVGElement && e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 4556 }, 4557 _identity2DMatrix = [1,0,0,1,0,0], 4558 _getMatrix = function(e, force2D) { 4559 var tm = e._gsTransform || new Transform(), 4560 rnd = 100000, 4561 style = e.style, 4562 isDefault, s, m, n, dec, none; 4563 if (_transformProp) { 4564 s = _getStyle(e, _transformPropCSS, null, true); 4565 } else if (e.currentStyle) { 4566 //for older versions of IE, we need to interpret the filter portion that is in the format: progid:DXImageTransform.Microsoft.Matrix(M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17, sizingMethod='auto expand') Notice that we need to swap b and c compared to a normal matrix. 4567 s = e.currentStyle.filter.match(_ieGetMatrixExp); 4568 s = (s && s.length === 4) ? [s[0].substr(4), Number(s[2].substr(4)), Number(s[1].substr(4)), s[3].substr(4), (tm.x || 0), (tm.y || 0)].join(",") : ""; 4569 }
4570 isDefault = (!s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)"); 4571 if (_transformProp && ((none = (!_getComputedStyle(e) || _getComputedStyle(e).display === "none")) || !e.parentNode)) { //note: Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397 4572 if (none) { //browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not "none". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px). 4573 n = style.display; 4574 style.display = "block"; 4575 } 4576 if (!e.parentNode) { 4577 dec = 1; //flag 4578 _docElement.appendChild(e); 4579 } 4580 s = _getStyle(e, _transformPropCSS, null, true); 4581 isDefault = (!s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)"); 4582 if (n) { 4583 style.display = n; 4584 } else if (none) { 4585 _removeProp(style, "display"); 4586 } 4587 if (dec) { 4588 _docElement.removeChild(e); 4589 } 4590 } 4591 if (tm.svg || (e.getCTM && _isSVG(e))) { 4592 if (isDefault && (style[_transformProp] + "").indexOf("matrix") !== -1) { //some browsers (like Chrome 40) don't correctly report transforms that are applied inline on an SVG element (they don't get included in the computed style), so we double-check here and accept matrix values 4593 s = style[_transformProp]; 4594 isDefault = 0; 4595 } 4596 m = e.getAttribute("transform"); 4597 if (isDefault && m) { 4598 m = e.transform.baseVal.consolidate().matrix; //ensures that even complex values like "translate(50,60) rotate(135,0,0)" are parsed because it mashes it into a matrix. 4599 s = "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + m.e + "," + m.f + ")"; 4600 isDefault = 0; 4601 } 4602 } 4603 if (isDefault) { 4604 return _identity2DMatrix; 4605 } 4606 //split the matrix values out into an array (m for matrix) 4607 m = (s || "").match(_numExp) || []; 4608 i = m.length; 4609 while (--i > -1) { 4610 n = Number(m[i]); 4611 m[i] = (dec = n - (n |= 0)) ? ((dec * rnd + (dec < 0 ? -0.5 : 0.5)) | 0) / rnd + n : n; //convert strings to Numbers and round to 5 decimal places to avoid issues with tiny numbers. Roughly 20x faster than Number.toFixed(). We also must make sure to round before dividing so that values like 0.9999999999 become 1 to avoid glitches in browser rendering and interpretation of flipped/rotated 3D matrices. And don't just multiply the number by rnd, floor it, and then divide by rnd because the bitwise operations max out at a 32-bit signed integer, thus it could get clipped at a relatively low value (like 22,000.00000 for example). 4612 } 4613 return (force2D && m.length > 6) ? [m[0], m[1], m[4], m[5], m[12], m[13]] : m; 4614 }, 4615 4616 /** 4617 * Parses the transform values for an element, returning an object with x, y, z, scaleX, scaleY, scaleZ, rotation, rotationX, rotationY, skewX, and skewY properties. Note: by default (for performance reasons), all skewing is combined into skewX and rotation but skewY still has a place in the transform object so that we can record how much of the skew is attributed to skewX vs skewY. Remember, a skewY of 10 looks the same as a rotation of 10 and skewX of -10. 4618 * @param {!Object} t target element 4619 * @param {Object=} cs computed style object (optional) 4620 * @param {boolean=} rec if true, the transform values will be recorded to the target element's _gsTransform object, like target._gsTransform = {x:0, y:0, z:0, scaleX:1...} 4621 * @param {boolean=} parse if true, we'll ignore any _gsTransform values that already exist on the element, and force a reparsing of the css (calculated style) 4622 * @return {object}
4622 object containing all of the transform properties/values like {x:0, y:0, z:0, scaleX:1...} 4623 */ 4624 _getTransform = _internals.getTransform = function(t, cs, rec, parse) { 4625 if (t._gsTransform && rec && !parse) { 4626 return t._gsTransform; //if the element already has a _gsTransform, use that. Note: some browsers don't accurately return the calculated style for the transform (particularly for SVG), so it's almost always safest to just use the values we've already applied rather than re-parsing things. 4627 } 4628 var tm = rec ? t._gsTransform || new Transform() : new Transform(), 4629 invX = (tm.scaleX < 0), //in order to interpret things properly, we need to know if the user applied a negative scaleX previously so that we can adjust the rotation and skewX accordingly. Otherwise, if we always interpret a flipped matrix as affecting scaleY and the user only wants to tween the scaleX on multiple sequential tweens, it would keep the negative scaleY without that being the user's intent. 4630 min = 0.00002, 4631 rnd = 100000, 4632 zOrigin = _supports3D ? parseFloat(_getStyle(t, _transformOriginProp, cs, false, "0 0 0").split(" ")[2]) || tm.zOrigin || 0 : 0, 4633 defaultTransformPerspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0, 4634 m, i, scaleX, scaleY, rotation, skewX; 4635 4636 tm.svg = !!(t.getCTM && _isSVG(t)); 4637 if (tm.svg) { 4638 _parseSVGOrigin(t, _getStyle(t, _transformOriginProp, cs, false, "50% 50%") + "", tm, t.getAttribute("data-svg-origin")); 4639 _useSVGTransformAttr = CSSPlugin.useSVGTransformAttr || _forceSVGTransformAttr; 4640 } 4641 m = _getMatrix(t); 4642 if (m !== _identity2DMatrix) { 4643 4644 if (m.length === 16) { 4645 //we'll only look at these position-related 6 variables first because if x/y/z all match, it's relatively safe to assume we don't need to re-parse everything which risks losing important rotational information (like rotationX:180 plus rotationY:180 would look the same as rotation:180 - there's no way to know for sure which direction was taken based solely on the matrix3d() values) 4646 var a11 = m[0], a21 = m[1], a31 = m[2], a41 = m[3], 4647 a12 = m[4], a22 = m[5], a32 = m[6], a42 = m[7], 4648 a13 = m[8], a23 = m[9], a33 = m[10], 4649 a14 = m[12], a24 = m[13], a34 = m[14], 4650 a43 = m[11], 4651 angle = Math.atan2(a32, a33), 4652 t1, t2, t3, t4, cos, sin; 4653 //we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari 4654 if (tm.zOrigin) { 4655 a34 = -tm.zOrigin; 4656 a14 = a13*a34-m[12]; 4657 a24 = a23*a34-m[13]; 4658 a34 = a33*a34+tm.zOrigin-m[14]; 4659 } 4660 //note for possible future consolidation: rotationX: Math.atan2(a32, a33), rotationY: Math.atan2(-a31, Math.sqrt(a33 * a33 + a32 * a32)), rotation: Math.atan2(a21, a11), skew: Math.atan2(a12, a22). However, it doesn't seem to be quite as reliable as the full-on backwards rotation procedure. 4661 tm.rotationX = angle * _RAD2DEG; 4662 //rotationX 4663 if (angle) { 4664 cos = Math.cos(-angle); 4665 sin = Math.sin(-angle); 4666 t1 = a12*cos+a13*sin; 4667 t2 = a22*cos+a23*sin; 4668 t3 = a32*cos+a33*sin; 4669 a13 = a12*-sin+a13*cos; 4670 a23 = a22*-sin+a23*cos; 4671 a33 = a32*-sin+a33*cos; 4672 a43 = a42*-sin+a43*cos; 4673 a12 = t1; 4674 a22 = t2; 4675 a32 = t3; 4676 } 4677 //rotationY 4678 angle = Math.atan2(-a31, a33); 4679 tm.rotationY = angle * _RAD2DEG; 4680 if (angle) { 4681 cos = Math.cos(-angle); 4682 sin = Math.sin(-angle); 4683 t1 = a11*cos-a13*sin; 4684 t2 = a21*cos-a23*sin; 4685 t3 = a31*cos-a33*sin; 4686 a23 = a21*sin+a23*cos; 4687 a33 = a31*sin+a33*cos; 4688 a43 = a41*sin+a43*cos; 4689 a11 = t1; 4690 a21 = t2; 4691 a31 = t3; 4692 } 4693 //rotationZ 4694 angle = Math.atan2(a21, a11); 4695 tm.rotation = angle * _RAD2DEG; 4696 if (angle) { 4697 cos = Math.cos(angle); 4698 sin = Math.sin(angle); 4699 t1 = a11*cos+a21*sin; 4700 t2 = a12*cos+a22*sin; 4701 t3 = a13*cos+a23*sin; 4702 a21 = a21*cos-a11*sin; 4703 a22 = a22*cos-a12*sin; 4704 a23 = a23*cos-a13*sin; 4705 a11 = t1; 4706 a12 = t2; 4707 a13 = t3; 4708 } 4709 4710 if (tm.rotationX && Math.abs(tm.rotationX) + Math.abs(tm.rotation) > 359.9) { //when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here. 4711 tm.rotationX = tm.rotation = 0; 4712 tm.rotationY = 180 - tm.rotationY; 4713 } 4714 4715 //skewX 4716 angle = Math.atan2(a12, a22); 4717 4718 //scales 4719 tm.scaleX = ((Math.sqrt(a11 * a11 + a21 * a21 + a31 * a31) * rnd + 0.5) | 0) / rnd; 4720 tm.scaleY = ((Math.sqrt(a22 * a22 + a32 * a32) * rnd + 0.5) | 0) / rnd; 4721 tm.scaleZ = ((Math.sqrt(a13 * a13 + a23 * a23 + a33 * a33) * rnd + 0.5) | 0) / rnd; 4722 a11 /= tm.scaleX; 4723 a12 /= tm.scaleY; 4724 a21 /= tm.scaleX; 4725 a22 /= tm.scaleY; 4726 if (Math.abs(angle) > min) { 4727 tm.skewX = angle * _RAD2DEG; 4728 a12 = 0;
4728 //unskews 4729 if (tm.skewType !== "simple") { 4730 tm.scaleY *= 1 / Math.cos(angle); //by default, we compensate the scale based on the skew so that the element maintains a similar proportion when skewed, so we have to alter the scaleY here accordingly to match the default (non-adjusted) skewing that CSS does (stretching more and more as it skews). 4731 } 4732 4733 } else { 4734 tm.skewX = 0; 4735 } 4736 4737 /* //for testing purposes 4738 var transform = "matrix3d(", 4739 comma = ",", 4740 zero = "0"; 4741 a13 /= tm.scaleZ; 4742 a23 /= tm.scaleZ; 4743 a31 /= tm.scaleX; 4744 a32 /= tm.scaleY; 4745 a33 /= tm.scaleZ; 4746 transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31); 4747 transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22); 4748 transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13); 4749 transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma; 4750 transform += a14 + comma + a24 + comma + a34 + comma + (tm.perspective ? (1 + (-a34 / tm.perspective)) : 1) + ")"; 4751 console.log(transform); 4752 document.querySelector(".test").style[_transformProp] = transform; 4753 */ 4754 4755 tm.perspective = a43 ? 1 / ((a43 < 0) ? -a43 : a43) : 0; 4756 tm.x = a14; 4757 tm.y = a24; 4758 tm.z = a34; 4759 if (tm.svg) { 4760 tm.x -= tm.xOrigin - (tm.xOrigin * a11 - tm.yOrigin * a12); 4761 tm.y -= tm.yOrigin - (tm.yOrigin * a21 - tm.xOrigin * a22); 4762 } 4763 4764 } else if ((!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || (!tm.rotationX && !tm.rotationY))) { //sometimes a 6-element matrix is returned even when we performed 3D transforms, like if rotationX and rotationY are 180. In cases like this, we still need to honor the 3D transforms. If we just rely on the 2D info, it could affect how the data is interpreted, like scaleY might get set to -1 or rotation could get offset by 180 degrees. For example, do a TweenLite.to(element, 1, {css:{rotationX:180, rotationY:180}}) and then later, TweenLite.to(element, 1, {css:{rotationX:0}}) and without this conditional logic in place, it'd jump to a state of being unrotated when the 2nd tween starts. Then again, we need to honor the fact that the user COULD alter the transforms outside of CSSPlugin, like by manually applying new css, so we try to sense that by looking at x and y because if those changed, we know the changes were made outside CSSPlugin and we force a reinterpretation of the matrix values. Also, in Webkit browsers, if the element's "display" is "none", its calculated style value will always return empty, so if we've already recorded the values in the _gsTransform object, we'll just rely on those. 4765 var k = (m.length >= 6), 4766 a = k ? m[0] : 1, 4767 b = m[1] || 0, 4768 c = m[2] || 0, 4769 d = k ? m[3] : 1; 4770 tm.x = m[4] || 0; 4771 tm.y = m[5] || 0; 4772 scaleX = Math.sqrt(a * a + b * b); 4773 scaleY = Math.sqrt(d * d + c * c); 4774 rotation = (a || b) ? Math.atan2(b, a) * _RAD2DEG : tm.rotation || 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist). 4775 skewX = (c || d) ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0; 4776 tm.scaleX = scaleX; 4777 tm.scaleY = scaleY; 4778 tm.rotation = rotation; 4779 tm.skewX = skewX; 4780 if (_supports3D) { 4781 tm.rotationX = tm.rotationY = tm.z = 0; 4782 tm.perspective = defaultTransformPerspective; 4783 tm.scaleZ = 1; 4784 } 4785 if (tm.svg) { 4786 tm.x -= tm.xOrigin - (tm.xOrigin * a + tm.yOrigin * c); 4787 tm.y -= tm.yOrigin - (tm.xOrigin * b + tm.yOrigin * d); 4788 } 4789 } 4790 if (Math.abs(tm.skewX) > 90 && Math.abs(tm.skewX) < 270) { 4791 if (invX) { 4792 tm.scaleX *= -1; 4793 tm.skewX += (tm.rotation <= 0) ? 180 : -180; 4794 tm.rotation += (tm.rotation <= 0) ? 180 : -180; 4795 } else { 4796 tm.scaleY *= -1; 4797 tm.skewX += (tm.skewX <= 0) ? 180 : -180; 4798 } 4799 } 4800 tm.zOrigin = zOrigin;
4801 //some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 0 in these cases. The conditional logic here is faster than calling Math.abs(). Also, browsers tend to render a SLIGHTLY rotated object in a fuzzy way, so we need to snap to exactly 0 when appropriate. 4802 for (i in tm) { 4803 if (tm[i] < min) if (tm[i] > -min) { 4804 tm[i] = 0; 4805 } 4806 } 4807 } 4808 //DEBUG: _log("parsed rotation of " + t.getAttribute("id")+": "+(tm.rotationX)+", "+(tm.rotationY)+", "+(tm.rotation)+", scale: "+tm.scaleX+", "+tm.scaleY+", "+tm.scaleZ+", position: "+tm.x+", "+tm.y+", "+tm.z+", perspective: "+tm.perspective+ ", origin: "+ tm.xOrigin+ ","+ tm.yOrigin); 4809 if (rec) { 4810 t._gsTransform = tm; //record to the object's _gsTransform which we use so that tweens can control individual properties independently (we need all the properties to accurately recompose the matrix in the setRatio() method) 4811 if (tm.svg) { //if we're supposed to apply transforms to the SVG element's "transform" attribute, make sure there aren't any CSS transforms applied or they'll override the attribute ones. Also clear the transform attribute if we're using CSS, just to be clean. 4812 if (_useSVGTransformAttr && t.style[_transformProp]) { 4813 TweenLite.delayedCall(0.001, function(){ //if we apply this right away (before anything has rendered), we risk there being no transforms for a brief moment and it also interferes with adjusting the transformOrigin in a tween with immediateRender:true (it'd try reading the matrix and it wouldn't have the appropriate data in place because we just removed it). 4814 _removeProp(t.style, _transformProp); 4815 }); 4816 } else if (!_useSVGTransformAttr && t.getAttribute("transform")) { 4817 TweenLite.delayedCall(0.001, function(){ 4818 t.removeAttribute("transform"); 4819 }); 4820 } 4821 } 4822 } 4823 return tm; 4824 }, 4825 4826 //for setting 2D transforms in IE6, IE7, and IE8 (must use a "filter" to emulate the behavior of modern day browser transforms) 4827 _setIETransformRatio = function(v) { 4828 var t = this.data, //refers to the element's _gsTransform object 4829 ang = -t.rotation * _DEG2RAD, 4830 skew = ang + t.skewX * _DEG2RAD, 4831 rnd = 100000, 4832 a = ((Math.cos(ang) * t.scaleX * rnd) | 0) / rnd, 4833 b = ((Math.sin(ang) * t.scaleX * rnd) | 0) / rnd, 4834 c = ((Math.sin(skew) * -t.scaleY * rnd) | 0) / rnd, 4835 d = ((Math.cos(skew) * t.scaleY * rnd) | 0) / rnd, 4836 style = this.t.style, 4837 cs = this.t.currentStyle, 4838 filters, val; 4839 if (!cs) { 4840 return; 4841 } 4842 val = b; //just for swapping the variables an inverting them (reused "val" to avoid creating another variable in memory). IE's filter matrix uses a non-standard matrix configuration (angle goes the opposite way, and b and c are reversed and inverted) 4843 b = -c; 4844 c = -val; 4845 filters = cs.filter; 4846 style.filter = ""; //remove filters so that we can accurately measure offsetWidth/offsetHeight 4847 var w = this.t.offsetWidth, 4848 h = this.t.offsetHeight, 4849 clip = (cs.position !== "absolute"), 4850 m = "progid:DXImageTransform.Microsoft.Matrix(M11=" + a + ", M12=" + b + ", M21=" + c + ", M22=" + d, 4851 ox = t.x + (w * t.xPercent / 100), 4852 oy = t.y + (h * t.yPercent / 100), 4853 dx, dy; 4854 4855 //if transformOrigin is being used, adjust the offset x and y 4856 if (t.ox != null) { 4857 dx = ((t.oxp) ? w * t.ox * 0.01 : t.ox) - w / 2; 4858 dy = ((t.oyp) ? h * t.oy * 0.01 : t.oy) - h / 2; 4859 ox += dx - (dx * a + dy * b); 4860 oy += dy - (dx * c + dy * d); 4861 } 4862 4863 if (!clip) { 4864 m += ", sizingMethod='auto expand')"; 4865 } else { 4866 dx = (w / 2); 4867 dy = (h / 2); 4868 //translate to ensure that transformations occur around the correct origin (default is center). 4869 m += ", Dx=" + (dx - (dx * a + dy * b) + ox) + ", Dy=" + (dy - (dx * c + dy * d) + oy) + ")"; 4870 } 4871 if (filters.indexOf("DXImageTransform.Microsoft.Matrix(") !== -1) { 4872 style.filter = filters.replace(_ieSetMatrixExp, m); 4873 } else { 4874 style.filter = m + " " + filters;
4874 //we must always put the transform/matrix FIRST (before alpha(opacity=xx)) to avoid an IE bug that slices part of the object when rotation is applied with alpha. 4875 } 4876 4877 //at the end or beginning of the tween, if the matrix is normal (1, 0, 0, 1) and opacity is 100 (or doesn't exist), remove the filter to improve browser performance. 4878 if (v === 0 || v === 1) if (a === 1) if (b === 0) if (c === 0) if (d === 1) if (!clip || m.indexOf("Dx=0, Dy=0") !== -1) if (!_opacityExp.test(filters) || parseFloat(RegExp.$1) === 100) if (filters.indexOf("gradient(" && filters.indexOf("Alpha")) === -1) { 4879 style.removeAttribute("filter"); 4880 } 4881 4882 //we must set the margins AFTER applying the filter in order to avoid some bugs in IE8 that could (in rare scenarios) cause them to be ignored intermittently (vibration). 4883 if (!clip) { 4884 var mult = (_ieVers < 8) ? 1 : -1, //in Internet Explorer 7 and before, the box model is broken, causing the browser to treat the width/height of the actual rotated filtered image as the width/height of the box itself, but Microsoft corrected that in IE8. We must use a negative offset in IE8 on the right/bottom 4885 marg, prop, dif; 4886 dx = t.ieOffsetX || 0; 4887 dy = t.ieOffsetY || 0; 4888 t.ieOffsetX = Math.round((w - ((a < 0 ? -a : a) * w + (b < 0 ? -b : b) * h)) / 2 + ox); 4889 t.ieOffsetY = Math.round((h - ((d < 0 ? -d : d) * h + (c < 0 ? -c : c) * w)) / 2 + oy); 4890 for (i = 0; i < 4; i++) { 4891 prop = _margins[i]; 4892 marg = cs[prop]; 4893 //we need to get the current margin in case it is being tweened separately (we want to respect that tween's changes) 4894 val = (marg.indexOf("px") !== -1) ? parseFloat(marg) : _convertToPixels(this.t, prop, parseFloat(marg), marg.replace(_suffixExp, "")) || 0; 4895 if (val !== t[prop]) { 4896 dif = (i < 2) ? -t.ieOffsetX : -t.ieOffsetY; //if another tween is controlling a margin, we cannot only apply the difference in the ieOffsets, so we essentially zero-out the dx and dy here in that case. We record the margin(s) later so that we can keep comparing them, making this code very flexible. 4897 } else { 4898 dif = (i < 2) ? dx - t.ieOffsetX : dy - t.ieOffsetY; 4899 } 4900 style[prop] = (t[prop] = Math.round( val - dif * ((i === 0 || i === 2) ? 1 : mult) )) + "px"; 4901 } 4902 } 4903 }, 4904 4905 /* translates a super small decimal to a string WITHOUT scientific notation 4906 _safeDecimal = function(n) { 4907 var s = (n < 0 ? -n : n) + "", 4908 a = s.split("e-"); 4909 return (n < 0 ? "-0." : "0.") + new Array(parseInt(a[1], 10) || 0).join("0") + a[0].split(".").join(""); 4910 }, 4911 */ 4912 4913 _setTransformRatio = _internals.set3DTransformRatio = _internals.setTransformRatio = function(v) { 4914 var t = this.data, //refers to the element's _gsTransform object 4915 style = this.t.style, 4916 angle = t.rotation, 4917 rotationX = t.rotationX, 4918 rotationY = t.rotationY, 4919 sx = t.scaleX, 4920 sy = t.scaleY, 4921 sz = t.scaleZ, 4922 x = t.x, 4923 y = t.y, 4924 z = t.z, 4925 isSVG = t.svg, 4926 perspective = t.perspective, 4927 force3D = t.force3D, 4928 skewY = t.skewY, 4929 skewX = t.skewX, 4930 t1, a11, a12, a13, a21, a22, a23, a31, a32, a33, a41, a42, a43, 4931 zOrigin, min, cos, sin, t2, transform, comma, zero, skew, rnd; 4932 if (skewY) { //for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees. 4933 skewX += skewY; 4934 angle += skewY; 4935 } 4936 4937 //check to see if we should render as 2D (and SVGs must use 2D when _useSVGTransformAttr is true) 4938 if (((((v === 1 || v === 0) && force3D === "auto" && (this.tween._totalTime === this.tween._totalDuration || !this.tween._totalTime)) || !force3D) && !z && !perspective && !rotationY && !rotationX && sz === 1) || (_useSVGTransformAttr && isSVG) || !_supports3D) { //on the final render (which could be 0 for a from tween), if there are no 3D aspects, render in 2D to free up memory and improve performance especially on mobile devices. Check the tween's totalTime/totalDuration too in order to make sure it doesn't happen between repeats if it's a repeating tween. 4939 4940 //2D 4941 if (angle || skewX || isSVG) { 4942 angle *= _DEG2RAD; 4943 skew = skewX * _DEG2RAD; 4944 rnd = 100000; 4945 a11 = Math.cos(angle) * sx; 4946 a21 = Math.sin(angle) * sx; 4947 a12 = Math.sin(angle - skew) * -sy;
4948 a22 = Math.cos(angle - skew) * sy; 4949 if (skew && t.skewType === "simple") { //by default, we compensate skewing on the other axis to make it look more natural, but you can set the skewType to "simple" to use the uncompensated skewing that CSS does 4950 t1 = Math.tan(skew - skewY * _DEG2RAD); 4951 t1 = Math.sqrt(1 + t1 * t1); 4952 a12 *= t1; 4953 a22 *= t1; 4954 if (skewY) { 4955 t1 = Math.tan(skewY * _DEG2RAD); 4956 t1 = Math.sqrt(1 + t1 * t1); 4957 a11 *= t1; 4958 a21 *= t1; 4959 } 4960 } 4961 if (isSVG) { 4962 x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset; 4963 y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset; 4964 if (_useSVGTransformAttr && (t.xPercent || t.yPercent)) { //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the matrix to simulate it. 4965 min = this.t.getBBox(); 4966 x += t.xPercent * 0.01 * min.width; 4967 y += t.yPercent * 0.01 * min.height; 4968 } 4969 min = 0.000001; 4970 if (x < min) if (x > -min) { 4971 x = 0; 4972 } 4973 if (y < min) if (y > -min) { 4974 y = 0; 4975 } 4976 } 4977 transform = (((a11 * rnd) | 0) / rnd) + "," + (((a21 * rnd) | 0) / rnd) + "," + (((a12 * rnd) | 0) / rnd) + "," + (((a22 * rnd) | 0) / rnd) + "," + x + "," + y + ")"; 4978 if (isSVG && _useSVGTransformAttr) {
4979 this.t.setAttribute("transform", "matrix(" + transform); 4980 } else { 4981 //some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 5 decimal places. 4982 style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + transform; 4983 } 4984 } else { 4985 style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + sx + ",0,0," + sy + "," + x + "," + y + ")"; 4986 } 4987 return; 4988 4989 } 4990 if (_isFirefox) { //Firefox has a bug (at least in v25) that causes it to render the transparent part of 32-bit PNG images as black when displayed inside an iframe and the 3D scale is very small and doesn't change sufficiently enough between renders (like if you use a Power4.easeInOut to scale from 0 to 1 where the beginning values only change a tiny amount to begin the tween before accelerating). In this case, we force the scale to be 0.00002 instead which is visually the same but works around the Firefox issue. 4991 min = 0.0001; 4992 if (sx < min && sx > -min) { 4993 sx = sz = 0.00002; 4994 } 4995 if (sy < min && sy > -min) { 4996 sy = sz = 0.00002; 4997 } 4998 if (perspective && !t.z && !t.rotationX && !t.rotationY) { //Firefox has a bug that causes elements to have an odd super-thin, broken/dotted black border on elements that have a perspective set but aren't utilizing 3D space (no rotationX, rotationY, or z). 4999 perspective = 0; 5000 } 5001 } 5002 if (angle || skewX) { 5003 angle *= _DEG2RAD; 5004 cos = a11 = Math.cos(angle); 5005 sin = a21 = Math.sin(angle); 5006 if (skewX) { 5007 angle -= skewX * _DEG2RAD; 5008 cos = Math.cos(angle); 5009 sin = Math.sin(angle); 5010 if (t.skewType === "simple") { //by default, we compensate skewing on the other axis to make it look more natural, but you can set the skewType to "simple" to use the uncompensated skewing that CSS does 5011 t1 = Math.tan((skewX - skewY) * _DEG2RAD); 5012 t1 = Math.sqrt(1 + t1 * t1); 5013 cos *= t1; 5014 sin *= t1; 5015 if (t.skewY) { 5016 t1 = Math.tan(skewY * _DEG2RAD); 5017 t1 = Math.sqrt(1 + t1 * t1); 5018 a11 *= t1; 5019 a21 *= t1; 5020 } 5021 } 5022 } 5023 a12 = -sin; 5024 a22 = cos; 5025 5026 } else if (!rotationY && !rotationX && sz === 1 && !perspective && !isSVG) { //if we're only translating and/or 2D scaling, this is faster... 5027 style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) translate3d(" : "translate3d(") + x + "px," + y + "px," + z +"px)" + ((sx !== 1 || sy !== 1) ? " scale(" + sx + "," + sy + ")" : ""); 5028 return; 5029 } else { 5030 a11 = a22 = 1; 5031 a12 = a21 = 0; 5032 } 5033 // KEY INDEX AFFECTS a[row][column] 5034 // a11 0 rotation, rotationY, scaleX 5035 // a21 1 rotation, rotationY, scaleX 5036 // a31 2 rotationY, scaleX 5037 // a41 3 rotationY, scaleX 5038 // a12 4 rotation, skewX, rotationX, scaleY 5039 // a22 5 rotation, skewX, rotationX, scaleY 5040 // a32 6 rotationX, scaleY 5041 // a42 7 rotationX, scaleY 5042 // a13 8 rotationY, rotationX, scaleZ 5043 // a23 9 rotationY, rotationX, scaleZ 5044 // a33 10 rotationY, rotationX, scaleZ 5045 // a43 11 rotationY, rotationX, perspective, scaleZ 5046 // a14 12 x, zOrigin, svgOrigin 5047 // a24 13 y, zOrigin, svgOrigin 5048 // a34 14 z, zOrigin 5049 // a44 15 5050 // rotation: Math.atan2(a21, a11) 5051 // rotationY: Math.atan2(a13, a33) (or Math.atan2(a13, a11)) 5052 // rotationX: Math.atan2(a32, a33) 5053 a33 = 1; 5054 a13 = a23 = a31 = a32 = a41 = a42 = 0; 5055 a43 = (perspective) ? -1 / perspective : 0; 5056 zOrigin = t.zOrigin; 5057 min = 0.000001; //threshold below which browsers use scientific notation which won't work. 5058 comma = ","; 5059 zero = "0"; 5060 angle = rotationY * _DEG2RAD; 5061 if (angle) { 5062 cos = Math.cos(angle); 5063 sin = Math.sin(angle);
5064 a31 = -sin; 5065 a41 = a43*-sin; 5066 a13 = a11*sin; 5067 a23 = a21*sin; 5068 a33 = cos; 5069 a43 *= cos; 5070 a11 *= cos; 5071 a21 *= cos; 5072 } 5073 angle = rotationX * _DEG2RAD; 5074 if (angle) { 5075 cos = Math.cos(angle); 5076 sin = Math.sin(angle); 5077 t1 = a12*cos+a13*sin; 5078 t2 = a22*cos+a23*sin; 5079 a32 = a33*sin; 5080 a42 = a43*sin; 5081 a13 = a12*-sin+a13*cos; 5082 a23 = a22*-sin+a23*cos; 5083 a33 = a33*cos; 5084 a43 = a43*cos; 5085 a12 = t1; 5086 a22 = t2; 5087 } 5088 if (sz !== 1) { 5089 a13*=sz; 5090 a23*=sz; 5091 a33*=sz; 5092 a43*=sz; 5093 } 5094 if (sy !== 1) { 5095 a12*=sy; 5096 a22*=sy; 5097 a32*=sy; 5098 a42*=sy; 5099 } 5100 if (sx !== 1) { 5101 a11*=sx; 5102 a21*=sx; 5103 a31*=sx; 5104 a41*=sx; 5105 } 5106 5107 if (zOrigin || isSVG) { 5108 if (zOrigin) { 5109 x += a13*-zOrigin; 5110 y += a23*-zOrigin; 5111 z += a33*-zOrigin+zOrigin; 5112 } 5113 if (isSVG) { //due to bugs in some browsers, we need to manage the transform-origin of SVG manually 5114 x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset; 5115 y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset; 5116 } 5117 if (x < min && x > -min) { 5118 x = zero; 5119 } 5120 if (y < min && y > -min) { 5121 y = zero; 5122 } 5123 if (z < min && z > -min) { 5124 z = 0; //don't use string because we calculate perspective later and need the number. 5125 } 5126 } 5127 5128 //optimized way of concatenating all the values into a string. If we do it all in one shot, it's slower because of the way browsers have to create temp strings and the way it affects memory. If we do it piece-by-piece with +=, it's a bit slower too. We found that doing it in these sized chunks works best overall: 5129 transform = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix3d(" : "matrix3d("); 5130 transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31); 5131 transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22); 5132 if (rotationX || rotationY || sz !== 1) { //performance optimization (often there's no rotationX or rotationY, so we can skip these calculations) 5133 transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13); 5134 transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma; 5135 } else { 5136 transform += ",0,0,0,0,1,0,"; 5137 } 5138 transform += x + comma + y + comma + z + comma + (perspective ? (1 + (-z / perspective)) : 1) + ")"; 5139 5140 style[_transformProp] = transform; 5141 }; 5142 5143 p = Transform.prototype; 5144 p.x = p.y = p.z = p.skewX = p.skewY = p.rotation = p.rotationX = p.rotationY = p.zOrigin = p.xPercent = p.yPercent = p.xOffset = p.yOffset = 0; 5145 p.scaleX = p.scaleY = p.scaleZ = 1; 5146 5147 _registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,svgOrigin,transformPerspective,directionalRotation,parseTransform,force3D,skewType,xPercent,yPercent,smoothOrigin", {parser:function(t, e, parsingProp, cssp, pt, plugin, vars) { 5148 if (cssp._lastParsedTransform === vars) { return pt; } //only need to parse the transform once, and only if the browser supports it. 5149 cssp._lastParsedTransform = vars; 5150 var scaleFunc = (vars.scale && typeof(vars.scale) === "function") ? vars.scale : 0, //if there's a function-based "scale" value, swap in the resulting numeric value temporarily. Otherwise, if it's called for both scaleX and scaleY independently, they may not match (like if the function uses Math.random()). 5151 swapFunc; 5152 if (typeof(vars[parsingProp]) === "function") { //whatever property triggers the initial parsing might be a function-based value in which case it already got called in parse(), thus we don't want to call it again in here. The most efficient way to avoid this is to temporarily swap the value directly into the vars object, and then after we do all our parsing in this function, we'll swap it back again. 5153 swapFunc = vars[parsingProp]; 5154 vars[parsingProp] = e; 5155 } 5156 if (scaleFunc) { 5157 vars.scale = scaleFunc(_index, t); 5158 } 5159 var originalGSTransform = t._gsTransform, 5160 style = t.style, 5161 min = 0.000001, 5162 i = _transformProps.length, 5163 v = vars, 5164 endRotations = {}, 5165 transformOriginString = "transformOrigin", 5166 m1 = _getTransform(t, _cs, true, v.parseTransform), 5167 orig = v.transform && ((typeof(v.transform) === "function") ? v.transform(_index, _target) : v.transform), 5168 m2, copy, has3D, hasChange, dr, x, y, matrix, p; 5169 m1.skewType = v.skewType || m1.skewType || CSSPlugin.defaultSkewType; 5170 cssp._transform = m1; 5171 if (orig && typeof(orig) === "string" && _transformProp) { //for values like transform:"rotate(60deg) scale(0.5, 0.8)" 5172 copy = _tempDiv.style; //don't use the original target because it might be SVG in which case some browsers don't report computed style correctly. 5173 copy[_transformProp] = orig; 5174 copy.display = "block"; //if display is "none", the browser often refuses to report the transform properties correctly. 5175 copy.position = "absolute"; 5176 if (orig.indexOf("%") !== -1) { //%-based translations will fail unless we set the width/height to match the original target... 5177 copy.width = _getStyle(t, "width");
5178 copy.height = _getStyle(t, "height"); 5179 } 5180 _doc.body.appendChild(_tempDiv); 5181 m2 = _getTransform(_tempDiv, null, false); 5182 if (m1.skewType === "simple") { //the default _getTransform() reports the skewX/scaleY as if skewType is "compensated", thus we need to adjust that here if skewType is "simple". 5183 m2.scaleY *= Math.cos(m2.skewX * _DEG2RAD); 5184 } 5185 if (m1.svg) { //if it's an SVG element, x/y part of the matrix will be affected by whatever we use as the origin and the offsets, so compensate here... 5186 x = m1.xOrigin; 5187 y = m1.yOrigin; 5188 m2.x -= m1.xOffset; 5189 m2.y -= m1.yOffset; 5190 if (v.transformOrigin || v.svgOrigin) { //if this tween is altering the origin, we must factor that in here. The actual work of recording the transformOrigin values and setting up the PropTween is done later (still inside this function) so we cannot leave the changes intact here - we only want to update the x/y accordingly. 5191 orig = {}; 5192 _parseSVGOrigin(t, _parsePosition(v.transformOrigin), orig, v.svgOrigin, v.smoothOrigin, true); 5193 x = orig.xOrigin; 5194 y = orig.yOrigin; 5195 m2.x -= orig.xOffset - m1.xOffset; 5196 m2.y -= orig.yOffset - m1.yOffset; 5197 } 5198 if (x || y) { 5199 matrix = _getMatrix(_tempDiv, true); 5200 m2.x -= x - (x * matrix[0] + y * matrix[2]); 5201 m2.y -= y - (x * matrix[1] + y * matrix[3]); 5202 } 5203 } 5204 _doc.body.removeChild(_tempDiv); 5205 if (!m2.perspective) { 5206 m2.perspective = m1.perspective; //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case. 5207 } 5208 if (v.xPercent != null) { 5209 m2.xPercent = _parseVal(v.xPercent, m1.xPercent); 5210 } 5211 if (v.yPercent != null) { 5212 m2.yPercent = _parseVal(v.yPercent, m1.yPercent); 5213 } 5214 } else if (typeof(v) === "object") { //for values like scaleX, scaleY, rotation, x, y, skewX, and skewY or transform:{...} (object) 5215 m2 = {scaleX:_parseVal((v.scaleX != null) ? v.scaleX : v.scale, m1.scaleX), 5216 scaleY:_parseVal((v.scaleY != null) ? v.scaleY : v.scale, m1.scaleY), 5217 scaleZ:_parseVal(v.scaleZ, m1.scaleZ), 5218 x:_parseVal(v.x, m1.x), 5219 y:_parseVal(v.y, m1.y), 5220 z:_parseVal(v.z, m1.z), 5221 xPercent:_parseVal(v.xPercent, m1.xPercent), 5222 yPercent:_parseVal(v.yPercent, m1.yPercent), 5223 perspective:_parseVal(v.transformPerspective, m1.perspective)}; 5224 dr = v.directionalRotation; 5225 if (dr != null) { 5226 if (typeof(dr) === "object") { 5227 for (copy in dr) { 5228 v[copy] = dr[copy]; 5229 } 5230 } else { 5231 v.rotation = dr; 5232 } 5233 } 5234 if (typeof(v.x) === "string" && v.x.indexOf("%") !== -1) { 5235 m2.x = 0; 5236 m2.xPercent = _parseVal(v.x, m1.xPercent); 5237 } 5238 if (typeof(v.y) === "string" && v.y.indexOf("%") !== -1) { 5239 m2.y = 0; 5240 m2.yPercent = _parseVal(v.y, m1.yPercent); 5241 } 5242 5243 m2.rotation = _parseAngle(("rotation" in v) ? v.rotation : ("shortRotation" in v) ? v.shortRotation + "_short" : ("rotationZ" in v) ? v.rotationZ : m1.rotation, m1.rotation, "rotation", endRotations); 5244 if (_supports3D) { 5245 m2.rotationX = _parseAngle(("rotationX" in v) ? v.rotationX : ("shortRotationX" in v) ? v.shortRotationX + "_short" : m1.rotationX || 0, m1.rotationX, "rotationX", endRotations); 5246 m2.rotationY = _parseAngle(("rotationY" in v) ? v.rotationY : ("shortRotationY" in v) ? v.shortRotationY + "_short" : m1.rotationY || 0, m1.rotationY, "rotationY", endRotations); 5247 } 5248 m2.skewX = _parseAngle(v.skewX, m1.skewX); 5249 m2.skewY = _parseAngle(v.skewY, m1.skewY); 5250 } 5251 if (_supports3D && v.force3D != null) { 5252 m1.force3D = v.force3D; 5253 hasChange = true; 5254 } 5255 5256 has3D = (m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective); 5257 if (!has3D && v.scale != null) { 5258 m2.scaleZ = 1; //no need to tween scaleZ. 5259 } 5260 5261 while (--i > -1) { 5262 p = _transformProps[i]; 5263 orig = m2[p] - m1[p]; 5264 if (orig > min || orig < -min || v[p] != null || _forcePT[p] != null) { 5265 hasChange = true; 5266 pt = new CSSPropTween(m1, p, m1[p], orig, pt); 5267 if (p in endRotations) { 5268 pt.e = endRotations[p]; //directional rotations typically have compensated values during the tween, but we need to make sure they end at exactly what the user requested 5269 } 5270 pt.xs0 = 0; //ensures the value stays numeric in setRatio() 5271 pt.plugin = plugin; 5272 cssp._overwriteProps.push(pt.n); 5273 } 5274 } 5275 5276 orig = v.transformOrigin; 5277 if (m1.svg && (orig || v.svgOrigin)) { 5278 x = m1.xOffset; //when we change the origin, in order to prevent things from jumping we adjust the x/y so we must record those here so that we can create PropTweens for them and flip them at the same time as the origin 5279 y = m1.yOffset; 5280 _parseSVGOrigin(t, _parsePosition(orig), m2, v.svgOrigin, v.smoothOrigin); 5281 pt = _addNonTweeningNumericPT(m1, "xOrigin", (originalGSTransform ? m1 : m2).xOrigin, m2.xOrigin, pt, transformOriginString); //note: if there wasn't a transformOrigin defined yet, just start with the destination one; it's wasteful otherwise, and it causes problems with fromTo() tweens. For example, TweenLite.to("#wheel", 3, {rotation:180, transformOrigin:"50% 50%", delay:1}); TweenLite.fromTo("#wheel", 3, {scale:0.5, transformOrigin:"50% 50%"}, {scale:1, delay:2}); would cause a jump when the from values revert at the beginning of the 2nd tween.
5282 pt = _addNonTweeningNumericPT(m1, "yOrigin", (originalGSTransform ? m1 : m2).yOrigin, m2.yOrigin, pt, transformOriginString); 5283 if (x !== m1.xOffset || y !== m1.yOffset) { 5284 pt = _addNonTweeningNumericPT(m1, "xOffset", (originalGSTransform ? x : m1.xOffset), m1.xOffset, pt, transformOriginString); 5285 pt = _addNonTweeningNumericPT(m1, "yOffset", (originalGSTransform ? y : m1.yOffset), m1.yOffset, pt, transformOriginString); 5286 } 5287 orig = "0px 0px"; //certain browsers (like firefox) completely botch transform-origin, so we must remove it to prevent it from contaminating transforms. We manage it ourselves with xOrigin and yOrigin 5288 } 5289 if (orig || (_supports3D && has3D && m1.zOrigin)) { //if anything 3D is happening and there's a transformOrigin with a z component that's non-zero, we must ensure that the transformOrigin's z-component is set to 0 so that we can manually do those calculations to get around Safari bugs. Even if the user didn't specifically define a "transformOrigin" in this particular tween (maybe they did it via css directly). 5290 if (_transformProp) { 5291 hasChange = true; 5292 p = _transformOriginProp; 5293 orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors 5294 pt = new CSSPropTween(style, p, 0, 0, pt, -1, transformOriginString); 5295 pt.b = style[p]; 5296 pt.plugin = plugin; 5297 if (_supports3D) { 5298 copy = m1.zOrigin; 5299 orig = orig.split(" "); 5300 m1.zOrigin = ((orig.length > 2 && !(copy !== 0 && orig[2] === "0px")) ? parseFloat(orig[2]) : copy) || 0; //Safari doesn't handle the z part of transformOrigin correctly, so we'll manually handle it in the _set3DTransformRatio() method. 5301 pt.xs0 = pt.e = orig[0] + " " + (orig[1] || "50%") + " 0px"; //we must define a z value of 0px specifically otherwise iOS 5 Safari will stick with the old one (if one was defined)! 5302 pt = new CSSPropTween(m1, "zOrigin", 0, 0, pt, -1, pt.n); //we must create a CSSPropTween for the _gsTransform.zOrigin so that it gets reset properly at the beginning if the tween runs backward (as opposed to just setting m1.zOrigin here) 5303 pt.b = copy; 5304 pt.xs0 = pt.e = m1.zOrigin; 5305 } else { 5306 pt.xs0 = pt.e = orig; 5307 } 5308 5309 //for older versions of IE (6-8), we need to manually calculate things inside the setRatio() function. We record origin x and y (ox and oy) and whether or not the values are percentages (oxp and oyp). 5310 } else { 5311 _parsePosition(orig + "", m1); 5312 } 5313 } 5314 if (hasChange) { 5315 cssp._transformType = (!(m1.svg && _useSVGTransformAttr) && (has3D || this._transformType === 3)) ? 3 : 2; //quicker than calling cssp._enableTransforms(); 5316 } 5317 if (swapFunc) { 5318 vars[parsingProp] = swapFunc; 5319 } 5320 if (scaleFunc) { 5321 vars.scale = scaleFunc; 5322 } 5323 return pt; 5324 }, prefix:true}); 5325 5326 _registerComplexSpecialProp("boxShadow", {defaultValue:"0px 0px 0px 0px #999", prefix:true, color:true, multi:true, keyword:"inset"}); 5327 5328 _registerComplexSpecialProp("borderRadius", {defaultValue:"0px", parser:function(t, e, p, cssp, pt, plugin) { 5329 e = this.format(e); 5330 var props = ["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"], 5331 style = t.style, 5332 ea1, i, es2, bs2, bs, es, bn, en, w, h, esfx, bsfx, rel, hn, vn, em; 5333 w = parseFloat(t.offsetWidth); 5334 h = parseFloat(t.offsetHeight); 5335 ea1 = e.split(" "); 5336 for (i = 0; i < props.length; i++) { //if we're dealing with percentages, we must convert things separately for the horizontal and vertical axis! 5337 if (this.p.indexOf("border")) { //older browsers used a prefix 5338 props[i] = _checkPropPrefix(props[i]); 5339 } 5340 bs = bs2 = _getStyle(t, props[i], _cs, false, "0px"); 5341 if (bs.indexOf(" ") !== -1) { 5342 bs2 = bs.split(" "); 5343 bs = bs2[0]; 5344 bs2 = bs2[1]; 5345 } 5346 es = es2 = ea1[i]; 5347 bn = parseFloat(bs); 5348 bsfx = bs.substr((bn + "").length); 5349 rel = (es.charAt(1) === "="); 5350 if (rel) { 5351 en = parseInt(es.charAt(0)+"1", 10); 5352 es = es.substr(2); 5353 en *= parseFloat(es); 5354 esfx = es.substr((en + "").length - (en < 0 ? 1 : 0)) || ""; 5355 } else { 5356 en = parseFloat(es); 5357 esfx = es.substr((en + "").length); 5358 } 5359 if (esfx === "") { 5360 esfx = _suffixMap[p] || bsfx; 5361 } 5362 if (esfx !== bsfx) { 5363 hn = _convertToPixels(t, "borderLeft", bn, bsfx); //horizontal number (we use a bogus "borderLeft" property just because the _convertToPixels() method searches for the keywords "Left", "Right", "Top", and "Bottom" to determine of it's a horizontal or vertical property, and we need "border" in the name so that it knows it should measure relative to the element itself, not its parent. 5364 vn = _convertToPixels(t, "borderTop", bn, bsfx); //vertical number 5365 if (esfx === "%") { 5366 bs = (hn / w * 100) + "%"; 5367 bs2 = (vn / h * 100) + "%"; 5368 } else if (esfx === "em") { 5369 em = _convertToPixels(t, "borderLeft", 1, "em"); 5370 bs = (hn / em) + "em"; 5371 bs2 = (vn / em) + "em"; 5372 } else { 5373 bs = hn + "px"; 5374 bs2 = vn + "px"; 5375 } 5376 if (rel) { 5377 es = (parseFloat(bs) + en) + esfx; 5378 es2 = (parseFloat(bs2) + en) + esfx; 5379 } 5380 } 5381 pt = _parseComplex(style, props[i], bs + " " + bs2, es + " " + es2, false, "0px", pt); 5382 } 5383 return pt; 5384 }, prefix:true, formatter:_getFormatter("0px 0px 0px 0px", false, true)}); 5385 _registerComplexSpecialProp("borderBottomLeftRadius,borderBottomRightRadius,borderTopLeftRadius,borderTopRightRadius", {defaultValue:"0px", parser:function(t, e, p, cssp, pt, plugin) { 5386 return _parseComplex(t.style, p, this.format(_getStyle(t, p, _cs, false, "0px 0px")), this.format(e), false, "0px", pt); 5387 }, prefix:true, formatter:_getFormatter("0px 0px", false, true)}); 5388 _registerComplexSpecialProp("backgroundPosition", {defaultValue:"0 0", parser:function(t, e, p, cssp, pt, plugin) { 5389 var bp = "background-position", 5390 cs = (_cs || _getComputedStyle(t, null)), 5391 bs = this.format( ((cs) ? _ieVers ? cs.getPropertyValue(bp + "-x") + " " + cs.getPropertyValue(bp + "-y") : cs.getPropertyValue(bp) : t.currentStyle.backgroundPositionX + " " + t.currentStyle.backgroundPositionY) || "0 0"), //Internet Explorer doesn't report background-position correctly - we must query background-position-x and background-position-y and combine them (even in IE10). Before IE9, we must do the same with the currentStyle object and use camelCase 5392 es = this.format(e), 5393 ba, ea, i, pct, overlap, src; 5394 if ((bs.indexOf("%") !== -1) !== (es.indexOf("%") !== -1) && es.split(",").length < 2) { 5395 src = _getStyle(t, "backgroundImage").replace(_urlExp, ""); 5396 if (src && src !== "none") { 5397 ba = bs.split(" "); 5398 ea = es.split(" "); 5399 _tempImg.setAttribute("src", src); //set the temp IMG's src to the background-image so that we can measure its width/height 5400 i = 2; 5401 while (--i > -1) { 5402 bs = ba[i]; 5403 pct = (bs.indexOf("%") !== -1); 5404 if (pct !== (ea[i].indexOf("%") !== -1)) { 5405 overlap = (i === 0) ? t.offsetWidth - _tempImg.width : t.offsetHeight - _tempImg.height; 5406 ba[i] = pct ? (parseFloat(bs) / 100 * overlap) + "px" : (parseFloat(bs) / overlap * 100) + "%"; 5407 } 5408 } 5409 bs = ba.join(" "); 5410 } 5411 } 5412 return this.parseComplex(t.style, bs, es, pt, plugin); 5413 }, formatter:_parsePosition}); 5414 _registerComplexSpecialProp("backgroundSize", {defaultValue:"0 0", formatter:function(v) { 5415 v += ""; //ensure it's a string 5416 return (v.substr(0,2) === "co") ? v : _parsePosition(v.indexOf(" ") === -1 ? v + " " + v : v); //if set to something like "100% 100%", Safari typically reports the computed style as just "100%" (no 2nd value), but we should ensure that there are two values, so copy the first one. Otherwise, it'd be interpreted as "100% 0" (wrong). Also remember that it could be "cover" or "contain" which we can't tween but should be able to set. 5417 }}); 5418 _registerComplexSpecialProp("perspective", {defaultValue:"0px", prefix:true}); 5419 _registerComplexSpecialProp("perspectiveOrigin", {defaultValue:"50% 50%", prefix:true}); 5420 _registerComplexSpecialProp("transformStyle", {prefix:true}); 5421 _registerComplexSpecialProp("backfaceVisibility", {prefix:true}); 5422 _registerComplexSpecialProp("userSelect", {prefix:true}); 5423 _registerComplexSpecialProp("margin", {parser:_getEdgeParser("marginTop,marginRight,marginBottom,marginLeft")}); 5424 _registerComplexSpecialProp("padding", {parser:_getEdgeParser("paddingTop,paddingRight,paddingBottom,paddingLeft")}); 5425 _registerComplexSpecialProp("clip", {defaultValue:"rect(0px,0px,0px,0px)", parser:function(t, e, p, cssp, pt, plugin){ 5426 var b, cs, delim; 5427 if (_ieVers < 9) { //IE8 and earlier don't report a "clip" value in the currentStyle - instead, the values are split apart into clipTop, clipRight, clipBottom, and clipLeft. Also, in IE7 and earlier, the values inside rect() are space-delimited, not comma-delimited. 5428 cs = t.currentStyle; 5429 delim = _ieVers < 8 ? " " : ","; 5430 b = "rect(" + cs.clipTop + delim + cs.clipRight + delim + cs.clipBottom + delim + cs.clipLeft + ")"; 5431 e = this.format(e).split(",").join(delim); 5432 } else { 5433 b = this.format(_getStyle(t, this.p, _cs, false, this.dflt)); 5434 e = this.format(e); 5435 } 5436 return this.parseComplex(t.style, b, e, pt, plugin); 5437 }}); 5438 _registerComplexSpecialProp("textShadow", {defaultValue:"0px 0px 0px #999", color:true, multi:true}); 5439 _registerComplexSpecialProp("autoRound,strictUnits", {parser:function(t, e, p, cssp, pt) {return pt;}}); //just so that we can ignore these properties (not tween them) 5440 _registerComplexSpecialProp("border", {defaultValue:"0px solid #000", parser:function(t, e, p, cssp, pt, plugin) { 5441 var bw = _getStyle(t, "borderTopWidth", _cs, false, "0px"), 5442 end = this.format(e).split(" "), 5443 esfx = end[0].replace(_suffixExp, ""); 5444 if (esfx !== "px") { //if we're animating to a non-px value, we need to convert the beginning width to that unit. 5445 bw = (parseFloat(bw) / _convertToPixels(t, "borderTopWidth", 1, esfx)) + esfx; 5446 } 5447 return this.parseComplex(t.style, this.format(bw + " " + _getStyle(t, "borderTopStyle", _cs, false, "solid") + " " + _getStyle(t, "borderTopColor", _cs, false, "#000")), end.join(" "), pt, plugin); 5448 }, color:true, formatter:function(v) { 5449 var a = v.split(" "); 5450 return a[0] + " " + (a[1] || "solid") + " " + (v.match(_colorExp) || ["#000"])[0]; 5451 }}); 5452 _registerComplexSpecialProp("borderWidth", {parser:_getEdgeParser("borderTopWidth,borderRightWidth,borderBottomWidth,borderLeftWidth")}); //Firefox doesn't pick up on borderWidth set in style sheets (only inline). 5453 _registerComplexSpecialProp("float,cssFloat,styleFloat", {parser:function(t, e, p, cssp, pt, plugin) { 5454 var s = t.style, 5455 prop = ("cssFloat" in s) ? "cssFloat" : "styleFloat"; 5456 return new CSSPropTween(s, prop, 0, 0, pt, -1, p, false, 0, s[prop], e); 5457 }}); 5458 5459 //opacity-related 5460 var _setIEOpacityRatio = function(v) { 5461 var t = this.t, //refers to the element's style property 5462 filters = t.filter || _getStyle(this.data, "filter") || "", 5463 val = (this.s + this.c * v) | 0, 5464 skip; 5465 if (val === 100) { //for older versions of IE that need to use a filter to apply opacity, we should remove the filter if opacity hits 1 in order to improve performance, but make sure there isn't a transform (matrix) or gradient in the filters. 5466 if (filters.indexOf("atrix(") === -1 && filters.indexOf("radient(") === -1 && filters.indexOf("oader(") === -1) { 5467 t.removeAttribute("filter"); 5468 skip = (!_getStyle(this.data, "filter")); //if a class is applied that has an alpha filter, it will take effect (we don't want that), so re-apply our alpha filter in that case. We must first remove it and then check. 5469 } else {
5470 t.filter = filters.replace(_alphaFilterExp, ""); 5471 skip = true; 5472 } 5473 } 5474 if (!skip) { 5475 if (this.xn1) { 5476 t.filter = filters = filters || ("alpha(opacity=" + val + ")"); //works around bug in IE7/8 that prevents changes to "visibility" from being applied properly if the filter is changed to a different alpha on the same frame. 5477 } 5478 if (filters.indexOf("pacity") === -1) { //only used if browser doesn't support the standard opacity style property (IE 7 and 8). We omit the "O" to avoid case-sensitivity issues 5479 if (val !== 0 || !this.xn1) { //bugs in IE7/8 won't render the filter properly if opacity is ADDED on the same frame/render as "visibility" changes (this.xn1 is 1 if this tween is an "autoAlpha" tween) 5480 t.filter = filters + " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly. 5481 } 5482 } else { 5483 t.filter = filters.replace(_opacityExp, "opacity=" + val); 5484 } 5485 } 5486 }; 5487 _registerComplexSpecialProp("opacity,alpha,autoAlpha", {defaultValue:"1", parser:function(t, e, p, cssp, pt, plugin) { 5488 var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")), 5489 style = t.style, 5490 isAutoAlpha = (p === "autoAlpha"); 5491 if (typeof(e) === "string" && e.charAt(1) === "=") { 5492 e = ((e.charAt(0) === "-") ? -1 : 1) * parseFloat(e.substr(2)) + b; 5493 } 5494 if (isAutoAlpha && b === 1 && _getStyle(t, "visibility", _cs) === "hidden" && e !== 0) { //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) 5495 b = 0; 5496 } 5497 if (_supportsOpacity) { 5498 pt = new CSSPropTween(style, "opacity", b, e - b, pt); 5499 } else { 5500 pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt); 5501 pt.xn1 = isAutoAlpha ? 1 : 0; //we need to record whether or not this is an autoAlpha so that in the setRatio(), we know to duplicate the setting of the alpha in order to work around a bug in IE7 and IE8 that prevents changes to "visibility" from taking effect if the filter is changed to a different alpha(opacity) at the same time. Setting it to the SAME value first, then the new value works around the IE7/8 bug. 5502 style.zoom = 1; //helps correct an IE issue. 5503 pt.type = 2; 5504 pt.b = "alpha(opacity=" + pt.s + ")"; 5505 pt.e = "alpha(opacity=" + (pt.s + pt.c) + ")"; 5506 pt.data = t; 5507 pt.plugin = plugin; 5508 pt.setRatio = _setIEOpacityRatio; 5509 } 5510 if (isAutoAlpha) { //we have to create the "visibility" PropTween after the opacity one in the linked list so that they run in the order that works properly in IE8 and earlier 5511 pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, ((b !== 0) ? "inherit" : "hidden"), ((e === 0) ? "hidden" : "inherit")); 5512 pt.xs0 = "inherit"; 5513 cssp._overwriteProps.push(pt.n); 5514 cssp._overwriteProps.push(p); 5515 } 5516 return pt; 5517 }}); 5518 5519 5520 var _removeProp = function(s, p) { 5521 if (p) { 5522 if (s.removeProperty) { 5523 if (p.substr(0,2) === "ms" || p.substr(0,6) === "webkit") { //Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash, it's correct (otherwise it'd be "ms-transform" instead of "-ms-transform" for IE9, for example) 5524 p = "-" + p; 5525 } 5526 s.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 5527 } else { //note: old versions of IE use "removeAttribute()" instead of "removeProperty()" 5528 s.removeAttribute(p); 5529 } 5530 } 5531 }, 5532 _setClassNameRatio = function(v) { 5533 this.t._gsClassPT = this; 5534 if (v === 1 || v === 0) { 5535 this.t.setAttribute("class", (v === 0) ? this.b : this.e); 5536 var mpt = this.data, //first MiniPropTween 5537 s = this.t.style; 5538 while (mpt) { 5539 if (!mpt.v) { 5540 _removeProp(s, mpt.p); 5541 } else { 5542 s[mpt.p] = mpt.v; 5543 } 5544 mpt = mpt._next; 5545 } 5546 if (v === 1 && this.t._gsClassPT === this) { 5547 this.t._gsClassPT = null; 5548 } 5549 } else if (this.t.getAttribute("class") !== this.e) { 5550 this.t.setAttribute("class", this.e); 5551 } 5552 }; 5553 _registerComplexSpecialProp("className", {parser:function(t, e, p, cssp, pt, plugin, vars) { 5554 var b = t.getAttribute("class") || "", //don't use t.className because it doesn't work consistently on SVG elements; getAttribute("class") and setAttribute("class", value") is more reliable. 5555 cssText = t.style.cssText, 5556 difData, bs, cnpt, cnptLookup, mpt; 5557 pt = cssp._classNamePT = new CSSPropTween(t, p, 0, 0, pt, 2); 5558 pt.setRatio = _setClassNameRatio; 5559 pt.pr = -11; 5560 _hasPriority = true; 5561 pt.b = b; 5562 bs = _getAllStyles(t, _cs); 5563 //if there's a className tween already operating on the target, force it to its end so that the necessary inline styles are removed and the class name is applied before we determine the end state (we don't want inline styles interfer
5563ing that were there just for class-specific values) 5564 cnpt = t._gsClassPT; 5565 if (cnpt) { 5566 cnptLookup = {}; 5567 mpt = cnpt.data; //first MiniPropTween which stores the inline styles - we need to force these so that the inline styles don't contaminate things. Otherwise, there's a small chance that a tween could start and the inline values match the destination values and they never get cleaned. 5568 while (mpt) { 5569 cnptLookup[mpt.p] = 1; 5570 mpt = mpt._next; 5571 } 5572 cnpt.setRatio(1); 5573 } 5574 t._gsClassPT = pt; 5575 pt.e = (e.charAt(1) !== "=") ? e : b.replace(new RegExp("(?:\\s|^)" + e.substr(2) + "(?![\\w-])"), "") + ((e.charAt(0) === "+") ? " " + e.substr(2) : ""); 5576 t.setAttribute("class", pt.e); 5577 difData = _cssDif(t, bs, _getAllStyles(t), vars, cnptLookup); 5578 t.setAttribute("class", b); 5579 pt.data = difData.firstMPT; 5580 t.style.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity). 5581 pt = pt.xfirst = cssp.parse(t, difData.difs, pt, plugin); //we record the CSSPropTween as the xfirst so that we can handle overwriting propertly (if "className" gets overwritten, we must kill all the properties associated with the className part of the tween, so we can loop through from xfirst to the pt itself) 5582 return pt; 5583 }}); 5584 5585 5586 var _setClearPropsRatio = function(v) { 5587 if (v === 1 || v === 0) if (this.data._totalTime === this.data._totalDuration && this.data.data !== "isFromStart") { //this.data refers to the tween. Only clear at the END of the tween (remember, from() tweens make the ratio go from 1 to 0, so we can't just check that and if the tween is the zero-duration one that's created internally to render the starting values in a from() tween, ignore that because otherwise, for example, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in). 5588 var s = this.t.style, 5589 transformParse = _specialProps.transform.parse, 5590 a, p, i, clearTransform, transform; 5591 if (this.e === "all") { 5592 s.cssText = ""; 5593 clearTransform = true; 5594 } else { 5595 a = this.e.split(" ").join("").split(","); 5596 i = a.length; 5597 while (--i > -1) { 5598 p = a[i]; 5599 if (_specialProps[p]) { 5600 if (_specialProps[p].parse === transformParse) { 5601 clearTransform = true; 5602 } else { 5603 p = (p === "transformOrigin") ? _transformOriginProp : _specialProps[p].p; //ensures that special properties use the proper browser-specific property name, like "scaleX" might be "-webkit-transform" or "boxShadow" might be "-moz-box-shadow" 5604 } 5605 } 5606 _removeProp(s, p); 5607 } 5608 } 5609 if (clearTransform) { 5610 _removeProp(s, _transformProp); 5611 transform = this.t._gsTransform; 5612 if (transform) { 5613 if (transform.svg) { 5614 this.t.removeAttribute("data-svg-origin"); 5615 this.t.removeAttribute("transform"); 5616 } 5617 delete this.t._gsTransform; 5618 } 5619 } 5620 5621 } 5622 }; 5623 _registerComplexSpecialProp("clearProps", {parser:function(t, e, p, cssp, pt) { 5624 pt = new CSSPropTween(t, p, 0, 0, pt, 2); 5625 pt.setRatio = _setClearPropsRatio; 5626 pt.e = e; 5627 pt.pr = -10; 5628 pt.data = cssp._tween; 5629 _hasPriority = true; 5630 return pt; 5631 }}); 5632 5633 p = "bezier,throwProps,physicsProps,physics2D".split(","); 5634 i = p.length; 5635 while (i--) { 5636 _registerPluginProp(p[i]); 5637 } 5638 5639 5640 5641 5642 5643 5644 5645 5646 p = CSSPlugin.prototype; 5647 p._firstPT = p._lastParsedTransform = p._transform = null; 5648 5649 //gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc. 5650 p._onInitTween = function(target, vars, tween, index) { 5651 if (!target.nodeType) { //css is only for dom elements 5652 return false; 5653 } 5654 this._target = _target = target; 5655 this._tween = tween; 5656 this._vars = vars; 5657 _index = index; 5658 _autoRound = vars.autoRound; 5659 _hasPriority = false;
5660 _suffixMap = vars.suffixMap || CSSPlugin.suffixMap; 5661 _cs = _getComputedStyle(target, ""); 5662 _overwriteProps = this._overwriteProps; 5663 var style = target.style, 5664 v, pt, pt2, first, last, next, zIndex, tpt, threeD; 5665 if (_reqSafariFix) if (style.zIndex === "") { 5666 v = _getStyle(target, "zIndex", _cs); 5667 if (v === "auto" || v === "") { 5668 //corrects a bug in [non-Android] Safari that prevents it from repainting elements in their new positions if they don't have a zIndex set. We also can't just apply this inside _parseTransform() because anything that's moved in any way (like using "left" or "top" instead of transforms like "x" and "y") can be affected, so it is best to ensure that anything that's tweening has a z-index. Setting "WebkitPerspective" to a non-zero value worked too except that on iOS Safari things would flicker randomly. Plus zIndex is less memory-intensive. 5669 this._addLazySet(style, "zIndex", 0); 5670 } 5671 } 5672 5673 if (typeof(vars) === "string") { 5674 first = style.cssText; 5675 v = _getAllStyles(target, _cs); 5676 style.cssText = first + ";" + vars; 5677 v = _cssDif(target, v, _getAllStyles(target)).difs; 5678 if (!_supportsOpacity && _opacityValExp.test(vars)) { 5679 v.opacity = parseFloat( RegExp.$1 ); 5680 } 5681 vars = v; 5682 style.cssText = first; 5683 } 5684 5685 if (vars.className) { //className tweens will combine any differences they find in the css with the vars that are passed in, so {className:"myClass", scale:0.5, left:20} would work. 5686 this._firstPT = pt = _specialProps.className.parse(target, vars.className, "className", this, null, null, vars); 5687 } else { 5688 this._firstPT = pt = this.parse(target, vars, null); 5689 } 5690 5691 if (this._transformType) { 5692 threeD = (this._transformType === 3); 5693 if (!_transformProp) { 5694 style.zoom = 1; //helps correct an IE issue. 5695 } else if (_isSafari) { 5696 _reqSafariFix = true; 5697 //if zIndex isn't set, iOS Safari doesn't repaint things correctly sometimes (seemingly at random). 5698 if (style.zIndex === "") { 5699 zIndex = _getStyle(target, "zIndex", _cs); 5700 if (zIndex === "auto" || zIndex === "") { 5701 this._addLazySet(style, "zIndex", 0); 5702 } 5703 } 5704 //Setting WebkitBackfaceVisibility corrects 3 bugs: 5705 // 1) [non-Android] Safari skips rendering changes to "top" and "left" that are made on the same frame/render as a transform update. 5706 // 2) iOS Safari sometimes neglects to repaint elements in their new positions. Setting "WebkitPerspective" to a non-zero value worked too except that on iOS Safari things would flicker randomly. 5707 // 3) Safari sometimes displayed odd artifacts when tweening the transform (or WebkitTransform) property, like ghosts of the edges of the element remained. Definitely a browser bug. 5708 //Note: we allow the user to override the auto-setting by defining WebkitBackfaceVisibility in the vars of the tween. 5709 if (_isSafariLT6) { 5710 this._addLazySet(style, "WebkitBackfaceVisibility", this._vars.WebkitBackfaceVisibility || (threeD ? "visible" : "hidden")); 5711 } 5712 } 5713 pt2 = pt; 5714 while (pt2 && pt2._next) { 5715 pt2 = pt2._next; 5716 } 5717 tpt = new CSSPropTween(target, "transform", 0, 0, null, 2); 5718 this._linkCSSP(tpt, null, pt2); 5719 tpt.setRatio = _transformProp ? _setTransformRatio : _setIETransformRatio; 5720 tpt.data = this._transform || _getTransform(target, _cs, true); 5721 tpt.tween = tween; 5722 tpt.pr = -1; //ensures that the transforms get applied after the components are updated. 5723 _overwriteProps.pop(); //we don't want to force the overwrite of all "transform" tweens of the target - we only care about individual transform properties like scaleX, rotation, etc. The CSSPropTween constructor automatically adds the property to _overwriteProps which is why we need to pop() here. 5724 } 5725 5726 if (_hasPriority) { 5727 //reorders the linked list in order of pr (priority) 5728 while (pt) { 5729 next = pt._next; 5730 pt2 = first; 5731 while (pt2 && pt2.pr > pt.pr) { 5732 pt2 = pt2._next; 5733 } 5734 if ((pt._prev = pt2 ? pt2._prev : last)) { 5735 pt._prev._next = pt; 5736 } else { 5737 first = pt; 5738 } 5739 if ((pt._next = pt2)) { 5740 pt2._prev = pt; 5741 } else { 5742 last = pt; 5743 } 5744 pt = next; 5745 } 5746 this._firstPT = first; 5747 } 5748 return true; 5749 }; 5750 5751 5752 p.parse = function(target, vars, pt, plugin) { 5753 var style = target.style, 5754 p, sp, bn, en, bs, es, bsfx, esfx, isStr, rel; 5755 for (p in vars) { 5756 es = vars[p]; //ending value string 5757 if (typeof(es) === "function") { 5758 es = es(_index, _target); 5759 } 5760 sp = _specialProps[p]; //SpecialProp lookup. 5761 if (sp) { 5762 pt = sp.parse(target, es, p, this, pt, plugin, vars); 5763 } else if (p.substr(0,2) === "--") { //for tweening CSS variables (which always start with "--"). To maximize performance and simplicity, we bypass CSSPlugin altogether and just add a normal property tween to the tween instance itself. 5764 this._tween._propLookup[p] = this._addTween.call(this._tween, target.style, "setProperty", _getComputedStyle(target).getPropertyValue(p) + "", es + "", p, false, p); 5765 continue; 5766 } else { 5767 bs = _getStyle(target, p, _cs) + ""; 5768 isStr = (typeof(es) === "string"); 5769 if (p === "color" || p === "fill" || p === "stroke" || p.indexOf("Color") !== -1 || (isStr && _rgbhslExp.test(es))) { //Opera uses background: to define color sometimes in addition to backgroundColor: 5770 if (!isStr) { 5771 es = _parseColor(es); 5772 es = ((es.length > 3) ? "rgba(" : "rgb(") + es.join(",") + ")"; 5773 } 5774 pt = _parseComplex(style, p, bs, es, true, "transparent", pt, 0, plugin); 5775 5776 } else if (isStr && _complexExp.test(es)) { 5777 pt = _parseComplex(style, p, bs, es, true, null, pt, 0, plugin); 5778 5779 } else { 5780 bn = parseFloat(bs); 5781 bsfx = (bn || bn === 0) ? bs.substr((bn + "").length) : ""; //remember, bs could be non-numeric like "normal" for fontWeight, so we should default to a blank suffix in that case. 5782 5783 if (bs === "" || bs === "auto") { 5784 if (p === "width" || p === "height") { 5785 bn = _getDimension(target, p, _cs); 5786 bsfx = "px"; 5787 } else if (p === "left" || p === "top") {
5788 bn = _calculateOffset(target, p, _cs); 5789 bsfx = "px"; 5790 } else { 5791 bn = (p !== "opacity") ? 0 : 1; 5792 bsfx = ""; 5793 } 5794 } 5795 5796 rel = (isStr && es.charAt(1) === "="); 5797 if (rel) { 5798 en = parseInt(es.charAt(0) + "1", 10); 5799 es = es.substr(2); 5800 en *= parseFloat(es); 5801 esfx = es.replace(_suffixExp, ""); 5802 } else { 5803 en = parseFloat(es); 5804 esfx = isStr ? es.replace(_suffixExp, "") : ""; 5805 } 5806 5807 if (esfx === "") { 5808 esfx = (p in _suffixMap) ? _suffixMap[p] : bsfx; //populate the end suffix, prioritizing the map, then if none is found, use the beginning suffix. 5809 } 5810 5811 es = (en || en === 0) ? (rel ? en + bn : en) + esfx : vars[p]; //ensures that any += or -= prefixes are taken care of. Record the end value before normalizing the suffix because we always want to end the tween on exactly what they intended even if it doesn't match the beginning value's suffix. 5812 //if the beginning/ending suffixes don't match, normalize them... 5813 if (bsfx !== esfx) if (esfx !== "" || p === "lineHeight") if (en || en === 0) if (bn) { //note: if the beginning value (bn) is 0, we don't need to convert units! 5814 bn = _convertToPixels(target, p, bn, bsfx); 5815 if (esfx === "%") { 5816 bn /= _convertToPixels(target, p, 100, "%") / 100; 5817 if (vars.strictUnits !== true) { //some browsers report only "px" values instead of allowing "%" with getComputedStyle(), so we assume that if we're tweening to a %, we should start there too unless strictUnits:true is defined. This approach is particularly useful for responsive designs that use from() tweens. 5818 bs = bn + "%"; 5819 } 5820 5821 } else if (esfx === "em" || esfx === "rem" || esfx === "vw" || esfx === "vh") { 5822 bn /= _convertToPixels(target, p, 1, esfx); 5823 5824 //otherwise convert to pixels. 5825 } else if (esfx !== "px") { 5826 en = _convertToPixels(target, p, en, esfx); 5827 esfx = "px"; //we don't use bsfx after this, so we don't need to set it to px too. 5828 } 5829 if (rel) if (en || en === 0) { 5830 es = (en + bn) + esfx; //the changes we made affect relative calculations, so adjust the end value here. 5831 } 5832 } 5833 5834 if (rel) { 5835 en += bn; 5836 } 5837 5838 if ((bn || bn === 0) && (en || en === 0)) { //faster than isNaN(). Also, previously we required en !== bn but that doesn't really gain much performance and it prevents _parseToProxy() from working properly if beginning and ending values match but need to get tweened by an external plugin anyway. For example, a bezier tween where the target starts at left:0 and has these points: [{left:50},{left:0}] wouldn't work properly because when parsing the last point, it'd match the first (current) one and a non-tweening CSSPropTween would be recorded when we actually need a normal tween (type:0) so that things get updated during the tween properly. 5839 pt = new CSSPropTween(style, p, bn, en - bn, pt, 0, p, (_autoRound !== false && (esfx === "px" || p === "zIndex")), 0, bs, es); 5840 pt.xs0 = esfx; 5841 //DEBUG: _log("tween "+p+" from "+pt.b+" ("+bn+esfx+") to "+pt.e+" with suffix: "+pt.xs0); 5842 } else if (style[p] === undefined || !es && (es + "" === "NaN" || es == null)) { 5843 _log("invalid " + p + " tween value: " + vars[p]); 5844 } else { 5845 pt = new CSSPropTween(style, p, en || bn || 0, 0, pt, -1, p, false, 0, bs, es); 5846 pt.xs0 = (es === "none" && (p === "display" || p.indexOf("Style") !== -1)) ? bs : es; //intermediate value should typically be set immediately (end value) except for "display" or things like borderTopStyle, borderBottomStyle, etc. which should use the beginning value during the tween. 5847 //DEBUG: _log("non-tweening value "+p+": "+pt.xs0); 5848 } 5849 } 5850 } 5851 if (plugin) if (pt && !pt.plugin) { 5852 pt.plugin = plugin; 5853 } 5854 } 5855 return pt; 5856 }; 5857 5858 5859 //gets called every time the tween updates, passing the new ratio (typically a value between 0 and 1, but not always (for example, if an Elastic.easeOut is used, the value can jump above 1 mid-tween). It will always start and 0 and end at 1. 5860 p.setRatio = function(v) { 5861 var pt = this._firstPT, 5862 min = 0.000001, 5863 val, str, i; 5864 //at the end of the tween, we set the values to exactly what we received in order to make sure non-tweening values (like "position" or "float" or whatever) are set and so that if the beginning/ending suffixes (units) didn't match and we normalized to px, the value that the user passed in is used here. We check to see if the tween is at its beginning in case it's a from() tween in which case the ratio will actually go from 1 to 0 over the course of the tween (backwards). 5865 if (v === 1 && (this._tween._time === this._tween._duration || this._tween._time === 0)) { 5866 while (pt) { 5867 if (pt.type !== 2) { 5868 if (pt.r && pt.type !== -1) { 5869 val = pt.r(pt.s + pt.c); 5870 if (!pt.type) { 5871 pt.t[pt.p] = val + pt.xs0; 5872 } else if (pt.type === 1) { //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)" 5873 i = pt.l; 5874 str = pt.xs0 + val + pt.xs1; 5875 for (i = 1; i < pt.l; i++) {
5876 str += pt["xn"+i] + pt["xs"+(i+1)]; 5877 } 5878 pt.t[pt.p] = str; 5879 } 5880 } else { 5881 pt.t[pt.p] = pt.e; 5882 } 5883 } else { 5884 pt.setRatio(v); 5885 } 5886 pt = pt._next; 5887 } 5888 5889 } else if (v || !(this._tween._time === this._tween._duration || this._tween._time === 0) || this._tween._rawPrevTime === -0.000001) { 5890 while (pt) { 5891 val = pt.c * v + pt.s; 5892 if (pt.r) { 5893 val = pt.r(val); 5894 } else if (val < min) if (val > -min) { 5895 val = 0; 5896 } 5897 if (!pt.type) { 5898 pt.t[pt.p] = val + pt.xs0; 5899 } else if (pt.type === 1) { //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)" 5900 i = pt.l; 5901 if (i === 2) { 5902 pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2; 5903 } else if (i === 3) { 5904 pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3; 5905 } else if (i === 4) { 5906 pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4; 5907 } else if (i === 5) { 5908 pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4 + pt.xn4 + pt.xs5; 5909 } else { 5910 str = pt.xs0 + val + pt.xs1; 5911 for (i = 1; i < pt.l; i++) { 5912 str += pt["xn"+i] + pt["xs"+(i+1)]; 5913 } 5914 pt.t[pt.p] = str; 5915 } 5916 5917 } else if (pt.type === -1) { //non-tweening value 5918 pt.t[pt.p] = pt.xs0; 5919 5920 } else if (pt.setRatio) { //custom setRatio() for things like SpecialProps, external plugins, etc. 5921 pt.setRatio(v); 5922 } 5923 pt = pt._next; 5924 } 5925 5926 //if the tween is reversed all the way back to the beginning, we need to restore the original values which may have different units (like % instead of px or em or whatever). 5927 } else { 5928 while (pt) { 5929 if (pt.type !== 2) { 5930 pt.t[pt.p] = pt.b; 5931 } else { 5932 pt.setRatio(v); 5933 } 5934 pt = pt._next; 5935 } 5936 } 5937 }; 5938 5939 /** 5940 * @private 5941 * Forces rendering of the target's transforms (rotation, scale, etc.) whenever the CSSPlugin's setRatio() is called. 5942 * Basically, this tells the CSSPlugin to create a CSSPropTween (type 2) after instantiation that runs last in the linked 5943 * list and calls the appropriate (3D or 2D) rendering function. We separate this into its own method so that we can call 5944 * it from other plugins like BezierPlugin if, for example, it needs to apply an autoRotation and this CSSPlugin 5945 * doesn't have any transform-related properties of its own. You can call this method as many times as you 5946 * want and it won't create duplicate CSSPropTweens. 5947 * 5948 * @param {boolean} threeD if true, it should apply 3D tweens (otherwise, just 2D ones are fine and typically faster) 5949 */ 5950 p._enableTransforms = function(threeD) { 5951 this._transform = this._transform || _getTransform(this._target, _cs, true); //ensures that the element has a _gsTransform property with the appropriate values. 5952 this._transformType = (!(this._transform.svg && _useSVGTransformAttr) && (threeD || this._transformType === 3)) ? 3 : 2; 5953 }; 5954 5955 var lazySet = function(v) { 5956 this.t[this.p] = this.e; 5957 this.data._linkCSSP(this, this._next, null, true); //we purposefully keep this._next even though it'd make sense to null it, but this is a performance optimization, as this happens during the while (pt) {} loop in setRatio() at the bottom of which it sets pt = pt._next, so if we null it, the linked list will be broken in that loop. 5958 }; 5959 /** @private Gives us a way to set a value on the first render (and only the first render). **/ 5960 p._addLazySet = function(t, p, v) { 5961 var pt = this._firstPT = new CSSPropTween(t, p, 0, 0, this._firstPT, 2); 5962 pt.e = v; 5963 pt.setRatio = lazySet; 5964 pt.data = this; 5965 }; 5966 5967 /** @private **/ 5968 p._linkCSSP = function(pt, next, prev, remove) { 5969 if (pt) { 5970 if (next) { 5971 next._prev = pt; 5972 } 5973 if (pt._next) { 5974 pt._next._prev = pt._prev; 5975 } 5976 if (pt._prev) { 5977 pt._prev._next = pt._next; 5978 } else if (this._firstPT === pt) { 5979 this._firstPT = pt._next; 5980 remove = true; //just to prevent resetting this._firstPT 5 lines down in case pt._next is null. (optimized for speed) 5981 } 5982 if (prev) { 5983 prev._next = pt; 5984 } else if (!remove && this._firstPT === null) { 5985 this._firstPT = pt; 5986 } 5987 pt._next = next; 5988 pt._prev = prev; 5989 } 5990 return pt; 5991 }; 5992 5993 p._mod = function(lookup) { 5994 var pt = this._firstPT; 5995 while (pt) { 5996 if (typeof(lookup[pt.p]) === "function") { //only gets called by RoundPropsPlugin (ModifyPlugin manages all the rendering internally for CSSPlugin properties that need modification). Remember, we handle rounding a bit differently in this plugin for performance reasons, leveraging "r" as an indicator that the value should be roun
5996ded internally. 5997 pt.r = lookup[pt.p]; 5998 } 5999 pt = pt._next; 6000 } 6001 }; 6002 6003 //we need to make sure that if alpha or autoAlpha is killed, opacity is too. And autoAlpha affects the "visibility" property. 6004 p._kill = function(lookup) { 6005 var copy = lookup, 6006 pt, p, xfirst; 6007 if (lookup.autoAlpha || lookup.alpha) { 6008 copy = {}; 6009 for (p in lookup) { //copy the lookup so that we're not changing the original which may be passed elsewhere. 6010 copy[p] = lookup[p]; 6011 } 6012 copy.opacity = 1; 6013 if (copy.autoAlpha) { 6014 copy.visibility = 1; 6015 } 6016 } 6017 if (lookup.className && (pt = this._classNamePT)) { //for className tweens, we need to kill any associated CSSPropTweens too; a linked list starts at the className's "xfirst". 6018 xfirst = pt.xfirst; 6019 if (xfirst && xfirst._prev) { 6020 this._linkCSSP(xfirst._prev, pt._next, xfirst._prev._prev); //break off the prev 6021 } else if (xfirst === this._firstPT) { 6022 this._firstPT = pt._next; 6023 } 6024 if (pt._next) { 6025 this._linkCSSP(pt._next, pt._next._next, xfirst._prev); 6026 } 6027 this._classNamePT = null; 6028 } 6029 pt = this._firstPT; 6030 while (pt) { 6031 if (pt.plugin && pt.plugin !== p && pt.plugin._kill) { //for plugins that are registered with CSSPlugin, we should notify them of the kill. 6032 pt.plugin._kill(lookup); 6033 p = pt.plugin; 6034 } 6035 pt = pt._next; 6036 } 6037 return TweenPlugin.prototype._kill.call(this, copy); 6038 }; 6039 6040 6041 6042 //used by cascadeTo() for gathering all the style properties of each child element into an array for comparison. 6043 var _getChildStyles = function(e, props, targets) { 6044 var children, i, child, type; 6045 if (e.slice) { 6046 i = e.length; 6047 while (--i > -1) { 6048 _getChildStyles(e[i], props, targets); 6049 } 6050 return; 6051 } 6052 children = e.childNodes; 6053 i = children.length; 6054 while (--i > -1) { 6055 child = children[i]; 6056 type = child.type; 6057 if (child.style) { 6058 props.push(_getAllStyles(child)); 6059 if (targets) { 6060 targets.push(child); 6061 } 6062 } 6063 if ((type === 1 || type === 9 || type === 11) && child.childNodes.length) { 6064 _getChildStyles(child, props, targets); 6065 } 6066 } 6067 }; 6068 6069 /** 6070 * Typically only useful for className tweens that may affect child elements, this method creates a TweenLite 6071 * and then compares the style properties of all the target's child elements at the tween's start and end, and 6072 * if any are different, it also creates tweens for those and returns an array containing ALL of the resulting 6073 * tweens (so that you can easily add() them to a TimelineLite, for example). The reason this functionality is 6074 * wrapped into a separate static method of CSSPlugin instead of being integrated into all regular className tweens 6075 * is because it creates entirely new tweens that may have completely different targets than the original tween, 6076 * so if they were all lumped into the original tween instance, it would be inconsistent with the rest of the API 6077 * and it would create other problems. For example: 6078 * - If I create a tween of elementA, that tween instance may suddenly change its target to include 50 other elements (unintuitive if I specifically defined the target I wanted) 6079 * - We can't just create new independent tweens because otherwise, what happens if the original/parent tween is reversed or pause or dropped into a TimelineLite for tight control? You'd expect that tween's behavior to affect all the others. 6080 * - Analyzing every style property of every child before and after the tween is an expensive operation when there are many children, so this behavior shouldn't be imposed on all className tweens by default, especially since it's probably rare that this extra functionality is needed. 6081 * 6082 * @param {Object} target object to be tweened 6083 * @param {number} Duration in seconds (or frames for frames-based tweens) 6084 * @param {Object} Object containing the end values, like {className:"newClass", ease:Linear.easeNone} 6085 * @return {Array} An array of TweenLite instances 6086 */ 6087 CSSPlugin.cascadeTo = function(target, duration, vars) { 6088 var tween = TweenLite.to(target, duration, vars), 6089 results = [tween], 6090 b = [], 6091 e = [], 6092 targets = [], 6093 _reservedProps = TweenLite._internals.reservedProps, 6094 i, difs, p, from; 6095 target = tween._targets || tween.target; 6096 _getChildStyles(target, b, targets); 6097 tween.render(duration, true, true); 6098 _getChildStyles(target, e); 6099 tween.render(0, true, true); 6100 tween._enabled(true); 6101 i = targets.length; 6102 while (--i > -1) { 6103 difs = _cssDif(targets[i], b[i], e[i]); 6104 if (difs.firstMPT) { 6105 difs = difs.difs; 6106 for (p in vars) { 6107 if (_reservedProps[p]) { 6108 difs[p] = vars[p]; 6109 } 6110 } 6111 from = {}; 6112 for (p in difs) { 6113 from[p] = b[i][p]; 6114 } 6115 results.push(TweenLite.fromTo(targets[i], duration, from, difs)); 6116 } 6117 } 6118 return results; 6119 }; 6120 6121 TweenPlugin.activate([CSSPlugin]); 6122 return CSSPlugin; 6123 6124 }, true); 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136/* 6137 * ---------------------------------------------------------------- 6138 * RoundPropsPlugin 6139 * ---------------------------------------------------------------- 6140 */ 6141 (function() { 6142 6143 var RoundPropsPlugin = _gsScope._gsDefine.plugin({ 6144 propName: "roundProps", 6145 version: "1.7.0", 6146 priority: -1, 6147 API: 2, 6148 6149 //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. 6150 init: function(target, value, tween) { 6151 this._tween = tween; 6152 return true; 6153 } 6154 6155 }), 6156 _getRoundFunc = function(v) { //pass in 0.1 get a function that'll round to the nearest tenth, or 5 to round to the closest 5, or 0.001 to the closest 1000th, etc. 6157 var p = v < 1 ? Math.pow(10, (v + "").length - 2) : 1; //to avoid floating point math errors (like 24 * 0.1 == 2.4000000000000004), we chop off at a specific number of decimal places (much faster than toFixed() 6158 return function(n) { 6159 return ((Math.round(n / v) * v * p) | 0) / p; 6160 }; 6161 }, 6162 _roundLinkedList = function(node, mod) { 6163 while (node) { 6164 if (!node.f && !node.blob) { 6165 node.m = mod || Math.round; 6166 } 6167 node = node._next; 6168 } 6169 }, 6170 p = RoundPropsPlugin.prototype; 6171 6172 p._onInitAllProps = function() { 6173 var tween = this._tween,
6174 rp = tween.vars.roundProps, 6175 lookup = {}, 6176 rpt = tween._propLookup.roundProps, 6177 pt, next, i, p; 6178 if (typeof(rp) === "object" && !rp.push) { 6179 for (p in rp) { 6180 lookup[p] = _getRoundFunc(rp[p]); 6181 } 6182 } else { 6183 if (typeof(rp) === "string") { 6184 rp = rp.split(","); 6185 } 6186 i = rp.length; 6187 while (--i > -1) { 6188 lookup[rp[i]] = Math.round; 6189 } 6190 } 6191 6192 for (p in lookup) { 6193 pt = tween._firstPT; 6194 while (pt) { 6195 next = pt._next; //record here, because it may get removed 6196 if (pt.pg) { 6197 pt.t._mod(lookup); 6198 } else if (pt.n === p) { 6199 if (pt.f === 2 && pt.t) { //a blob (text containing multiple numeric values) 6200 _roundLinkedList(pt.t._firstPT, lookup[p]); 6201 } else { 6202 this._add(pt.t, p, pt.s, pt.c, lookup[p]); 6203 //remove from linked list 6204 if (next) { 6205 next._prev = pt._prev; 6206 } 6207 if (pt._prev) { 6208 pt._prev._next = next; 6209 } else if (tween._firstPT === pt) { 6210 tween._firstPT = next; 6211 } 6212 pt._next = pt._prev = null; 6213 tween._propLookup[p] = rpt; 6214 } 6215 } 6216 pt = next; 6217 } 6218 } 6219 return false; 6220 }; 6221 6222 p._add = function(target, p, s, c, mod) { 6223 this._addTween(target, p, s, s + c, p, mod || Math.round); 6224 this._overwriteProps.push(p); 6225 }; 6226 6227 }()); 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238/* 6239 * ---------------------------------------------------------------- 6240 * AttrPlugin 6241 * ---------------------------------------------------------------- 6242 */ 6243 6244 (function() { 6245 6246 _gsScope._gsDefine.plugin({ 6247 propName: "attr", 6248 API: 2, 6249 version: "0.6.1", 6250 6251 //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. 6252 init: function(target, value, tween, index) { 6253 var p, end; 6254 if (typeof(target.setAttribute) !== "function") { 6255 return false; 6256 } 6257 for (p in value) { 6258 end = value[p]; 6259 if (typeof(end) === "function") { 6260 end = end(index, target); 6261 } 6262 this._addTween(target, "setAttribute", target.getAttribute(p) + "", end + "", p, false, p); 6263 this._overwriteProps.push(p); 6264 } 6265 return true; 6266 } 6267 6268 }); 6269 6270 }()); 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281/* 6282 * ---------------------------------------------------------------- 6283 * DirectionalRotationPlugin 6284 * ---------------------------------------------------------------- 6285 */ 6286 _gsScope._gsDefine.plugin({ 6287 propName: "directionalRotation", 6288 version: "0.3.1", 6289 API: 2, 6290 6291 //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. 6292 init: function(target, value, tween, index) { 6293 if (typeof(value) !== "object") { 6294 value = {rotation:value}; 6295 } 6296 this.finals = {}; 6297 var cap = (value.useRadians === true) ? Math.PI * 2 : 360, 6298 min = 0.000001, 6299 p, v, start, end, dif, split; 6300 for (p in value) { 6301 if (p !== "useRadians") { 6302 end = value[p]; 6303 if (typeof(end) === "function") { 6304 end = end(index, target); 6305 } 6306 split = (end + "").split("_"); 6307 v = split[0]; 6308 start = parseFloat( (typeof(target[p]) !== "function") ? target[p] : target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ]() ); 6309 end = this.finals[p] = (typeof(v) === "string" && v.charAt(1) === "=") ? start + parseInt(v.charAt(0) + "1", 10) * Number(v.substr(2)) : Number(v) || 0; 6310 dif = end - start; 6311 if (split.length) { 6312 v = split.join("_"); 6313 if (v.indexOf("short") !== -1) { 6314 dif = dif % cap; 6315 if (dif !== dif % (cap / 2)) { 6316 dif = (dif < 0) ? dif + cap : dif - cap; 6317 } 6318 } 6319 if (v.indexOf("_cw") !== -1 && dif < 0) { 6320 dif = ((dif + cap * 9999999999) % cap) - ((dif / cap) | 0) * cap; 6321 } else if (v.indexOf("ccw") !== -1 && dif > 0) { 6322 dif = ((dif - cap * 9999999999) % cap) - ((dif / cap) | 0) * cap; 6323 } 6324 } 6325 if (dif > min || dif < -min) { 6326 this._addTween(target, p, start, start + dif, p); 6327 this._overwriteProps.push(p); 6328 } 6329 } 6330 } 6331 return true; 6332 }, 6333 6334 //called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.)
6335 set: function(ratio) { 6336 var pt; 6337 if (ratio !== 1) { 6338 this._super.setRatio.call(this, ratio); 6339 } else { 6340 pt = this._firstPT; 6341 while (pt) { 6342 if (pt.f) { 6343 pt.t[pt.p](this.finals[pt.p]); 6344 } else { 6345 pt.t[pt.p] = this.finals[pt.p]; 6346 } 6347 pt = pt._next; 6348 } 6349 } 6350 } 6351 6352 })._autoCSS = true; 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364/* 6365 * ---------------------------------------------------------------- 6366 * EasePack 6367 * ---------------------------------------------------------------- 6368 */ 6369 _gsScope._gsDefine("easing.Back", ["easing.Ease"], function(Ease) { 6370 6371 var w = (_gsScope.GreenSockGlobals || _gsScope), 6372 gs = w.com.greensock, 6373 _2PI = Math.PI * 2, 6374 _HALF_PI = Math.PI / 2, 6375 _class = gs._class, 6376 _create = function(n, f) { 6377 var C = _class("easing." + n, function(){}, true), 6378 p = C.prototype = new Ease(); 6379 p.constructor = C; 6380 p.getRatio = f; 6381 return C; 6382 }, 6383 _easeReg = Ease.register || function(){}, //put an empty function in place just as a safety measure in case someone loads an OLD version of TweenLite.js where Ease.register doesn't exist. 6384 _wrap = function(name, EaseOut, EaseIn, EaseInOut, aliases) { 6385 var C = _class("easing."+name, { 6386 easeOut:new EaseOut(), 6387 easeIn:new EaseIn(), 6388 easeInOut:new EaseInOut() 6389 }, true); 6390 _easeReg(C, name); 6391 return C; 6392 }, 6393 EasePoint = function(time, value, next) { 6394 this.t = time; 6395 this.v = value; 6396 if (next) { 6397 this.next = next; 6398 next.prev = this; 6399 this.c = next.v - value; 6400 this.gap = next.t - time; 6401 } 6402 }, 6403 6404 //Back 6405 _createBack = function(n, f) { 6406 var C = _class("easing." + n, function(overshoot) { 6407 this._p1 = (overshoot || overshoot === 0) ? overshoot : 1.70158; 6408 this._p2 = this._p1 * 1.525; 6409 }, true), 6410 p = C.prototype = new Ease(); 6411 p.constructor = C; 6412 p.getRatio = f; 6413 p.config = function(overshoot) { 6414 return new C(overshoot); 6415 }; 6416 return C; 6417 }, 6418 6419 Back = _wrap("Back", 6420 _createBack("BackOut", function(p) { 6421 return ((p = p - 1) * p * ((this._p1 + 1) * p + this._p1) + 1); 6422 }), 6423 _createBack("BackIn", function(p) { 6424 return p * p * ((this._p1 + 1) * p - this._p1); 6425 }), 6426 _createBack("BackInOut", function(p) { 6427 return ((p *= 2) < 1) ? 0.5 * p * p * ((this._p2 + 1) * p - this._p2) : 0.5 * ((p -= 2) * p * ((this._p2 + 1) * p + this._p2) + 2); 6428 }) 6429 ), 6430 6431 6432 //SlowMo 6433 SlowMo = _class("easing.SlowMo", function(linearRatio, power, yoyoMode) { 6434 power = (power || power === 0) ? power : 0.7; 6435 if (linearRatio == null) { 6436 linearRatio = 0.7; 6437 } else if (linearRatio > 1) { 6438 linearRatio = 1; 6439 } 6440 this._p = (linearRatio !== 1) ? power : 0; 6441 this._p1 = (1 - linearRatio) / 2; 6442 this._p2 = linearRatio; 6443 this._p3 = this._p1 + this._p2; 6444 this._calcEnd = (yoyoMode === true); 6445 }, true), 6446 p = SlowMo.prototype = new Ease(), 6447 SteppedEase, ExpoScaleEase, RoughEase, _createElastic; 6448 6449 p.constructor = SlowMo; 6450 p.getRatio = function(p) { 6451 var r = p + (0.5 - p) * this._p; 6452 if (p < this._p1) { 6453 return this._calcEnd ? 1 - ((p = 1 - (p / this._p1)) * p) : r - ((p = 1 - (p / this._p1)) * p * p * p * r); 6454 } else if (p > this._p3) { 6455 return this._calcEnd ? (p === 1 ? 0 : 1 - (p = (p - this._p3) / this._p1) * p) : r + ((p - r) * (p = (p - this._p3) / this._p1) * p * p * p); //added p === 1 ? 0 to avoid floating point rounding errors from affecting the final value, like 1 - 0.7 = 0.30000000000000004 instead of 0.3 6456 } 6457 return this._calcEnd ? 1 : r; 6458 }; 6459 SlowMo.ease = new SlowMo(0.7, 0.7); 6460 6461 p.config = SlowMo.config = function(linearRatio, power, yoyoMode) { 6462 return new SlowMo(linearRatio, power, yoyoMode); 6463 }; 6464 6465 6466 //SteppedEase 6467 SteppedEase = _class("easing.SteppedEase", function(steps, immediateStart) { 6468 steps = steps || 1; 6469 this._p1 = 1 / steps; 6470 this._p2 = steps + (immediateStart ? 0 : 1); 6471 this._p3 = immediateStart ? 1 : 0; 6472 }, true); 6473 p = SteppedEase.prototype = new Ease(); 6474 p.constructor = SteppedEase; 6475 p.getRatio = function(p) { 6476 if (p < 0) { 6477 p = 0; 6478 } else if (p >= 1) { 6479 p = 0.999999999; 6480 } 6481 return (((this._p2 * p) | 0) + this._p3) * this._p1; 6482 }; 6483 p.config = SteppedEase.config = function(steps, immediateStart) { 6484 return new SteppedEase(steps, immediateStart); 6485 }; 6486 6487 //ExpoScaleEase 6488 ExpoScaleEase = _class("easing.ExpoScaleEase", function(start, end, ease) { 6489 this._p1 = Math.log(end / start); 6490 this._p2 = end - start; 6491 this._p3 = start; 6492 this._ease = ease; 6493 }, true); 6494 p = ExpoScaleEase.prototype = new Ease(); 6495 p.constructor = ExpoScaleEase; 6496 p.getRatio = function(p) { 6497 if (this._ease) { 6498 p = this._ease.getRatio(p); 6499 } 6500 return (this._p3 * Math.exp(this._p1 * p) - this._p3) / this._p2; 6501 }; 6502 p.config = ExpoScaleEase.config = function(start, end, ease) { 6503 return new ExpoScaleEase(start, end, ease); 6504 }; 6505 6506 6507 //RoughEase 6508 RoughEase = _class("easing.RoughEase", function(vars) { 6509 vars = vars || {}; 6510 var taper = vars.taper || "none", 6511 a = [], 6512 cnt = 0, 6513 points = (vars.points || 20) | 0, 6514 i = points, 6515 randomize = (vars.randomize !== false), 6516 clamp = (vars.clamp === true), 6517 template = (vars.template instanceof Ease) ? vars.template : null,
6518 strength = (typeof(vars.strength) === "number") ? vars.strength * 0.4 : 0.4, 6519 x, y, bump, invX, obj, pnt; 6520 while (--i > -1) { 6521 x = randomize ? Math.random() : (1 / points) * i; 6522 y = template ? template.getRatio(x) : x; 6523 if (taper === "none") { 6524 bump = strength; 6525 } else if (taper === "out") { 6526 invX = 1 - x; 6527 bump = invX * invX * strength; 6528 } else if (taper === "in") { 6529 bump = x * x * strength; 6530 } else if (x < 0.5) { //"both" (start) 6531 invX = x * 2; 6532 bump = invX * invX * 0.5 * strength; 6533 } else { //"both" (end) 6534 invX = (1 - x) * 2; 6535 bump = invX * invX * 0.5 * strength; 6536 } 6537 if (randomize) { 6538 y += (Math.random() * bump) - (bump * 0.5); 6539 } else if (i % 2) { 6540 y += bump * 0.5; 6541 } else { 6542 y -= bump * 0.5; 6543 } 6544 if (clamp) { 6545 if (y > 1) { 6546 y = 1; 6547 } else if (y < 0) { 6548 y = 0; 6549 } 6550 } 6551 a[cnt++] = {x:x, y:y}; 6552 } 6553 a.sort(function(a, b) { 6554 return a.x - b.x; 6555 }); 6556 6557 pnt = new EasePoint(1, 1, null); 6558 i = points; 6559 while (--i > -1) { 6560 obj = a[i]; 6561 pnt = new EasePoint(obj.x, obj.y, pnt); 6562 } 6563 6564 this._prev = new EasePoint(0, 0, (pnt.t !== 0) ? pnt : pnt.next); 6565 }, true); 6566 p = RoughEase.prototype = new Ease(); 6567 p.constructor = RoughEase; 6568 p.getRatio = function(p) { 6569 var pnt = this._prev; 6570 if (p > pnt.t) { 6571 while (pnt.next && p >= pnt.t) { 6572 pnt = pnt.next; 6573 } 6574 pnt = pnt.prev; 6575 } else { 6576 while (pnt.prev && p <= pnt.t) { 6577 pnt = pnt.prev; 6578 } 6579 } 6580 this._prev = pnt; 6581 return (pnt.v + ((p - pnt.t) / pnt.gap) * pnt.c); 6582 }; 6583 p.config = function(vars) { 6584 return new RoughEase(vars); 6585 }; 6586 RoughEase.ease = new RoughEase(); 6587 6588 6589 //Bounce 6590 _wrap("Bounce", 6591 _create("BounceOut", function(p) { 6592 if (p < 1 / 2.75) { 6593 return 7.5625 * p * p; 6594 } else if (p < 2 / 2.75) { 6595 return 7.5625 * (p -= 1.5 / 2.75) * p + 0.75; 6596 } else if (p < 2.5 / 2.75) { 6597 return 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375; 6598 } 6599 return 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375; 6600 }), 6601 _create("BounceIn", function(p) { 6602 if ((p = 1 - p) < 1 / 2.75) { 6603 return 1 - (7.5625 * p * p); 6604 } else if (p < 2 / 2.75) { 6605 return 1 - (7.5625 * (p -= 1.5 / 2.75) * p + 0.75); 6606 } else if (p < 2.5 / 2.75) { 6607 return 1 - (7.5625 * (p -= 2.25 / 2.75) * p + 0.9375); 6608 } 6609 return 1 - (7.5625 * (p -= 2.625 / 2.75) * p + 0.984375); 6610 }), 6611 _create("BounceInOut", function(p) { 6612 var invert = (p < 0.5); 6613 if (invert) { 6614 p = 1 - (p * 2); 6615 } else { 6616 p = (p * 2) - 1; 6617 } 6618 if (p < 1 / 2.75) { 6619 p = 7.5625 * p * p; 6620 } else if (p < 2 / 2.75) { 6621 p = 7.5625 * (p -= 1.5 / 2.75) * p + 0.75; 6622 } else if (p < 2.5 / 2.75) { 6623 p = 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375; 6624 } else { 6625 p = 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375; 6626 } 6627 return invert ? (1 - p) * 0.5 : p * 0.5 + 0.5; 6628 }) 6629 ); 6630 6631 6632 //CIRC 6633 _wrap("Circ", 6634 _create("CircOut", function(p) { 6635 return Math.sqrt(1 - (p = p - 1) * p); 6636 }), 6637 _create("CircIn", function(p) { 6638 return -(Math.sqrt(1 - (p * p)) - 1); 6639 }), 6640 _create("CircInOut", function(p) { 6641 return ((p*=2) < 1) ? -0.5 * (Math.sqrt(1 - p * p) - 1) : 0.5 * (Math.sqrt(1 - (p -= 2) * p) + 1); 6642 }) 6643 ); 6644 6645 6646 //Elastic 6647 _createElastic = function(n, f, def) { 6648 var C = _class("easing." + n, function(amplitude, period) { 6649 this._p1 = (amplitude >= 1) ? amplitude : 1; //note: if amplitude is < 1, we simply adjust the period for a more natural feel. Otherwise the math doesn't work right and the curve starts at 1. 6650 this._p2 = (period || def) / (amplitude < 1 ? amplitude : 1); 6651 this._p3 = this._p2 / _2PI * (Math.asin(1 / this._p1) || 0); 6652 this._p2 = _2PI / this._p2; //precalculate to optimize 6653 }, true), 6654 p = C.prototype = new Ease(); 6655 p.constructor = C; 6656 p.getRatio = f; 6657 p.config = function(amplitude, period) { 6658 return new C(amplitude, period); 6659 }; 6660 return C; 6661 }; 6662 _wrap("Elastic", 6663 _createElastic("ElasticOut", function(p) { 6664 return this._p1 * Math.pow(2, -10 * p) * Math.sin( (p - this._p3) * this._p2 ) + 1; 6665 }, 0.3), 6666 _createElastic("ElasticIn", function(p) { 6667 return -(this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin( (p - this._p3) * this._p2 )); 6668 }, 0.3), 6669 _createElastic("ElasticInOut", function(p) { 6670 return ((p *= 2) < 1) ? -0.5 * (this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin( (p - this._p3) * this._p2)) : this._p1 * Math.pow(2, -10 *(p -= 1)) * Math.sin( (p - this._p3) * this._p2 ) * 0.5 + 1; 6671 }, 0.45) 6672 ); 6673 6674 6675 //Expo 6676 _wrap("Expo", 6677 _create("ExpoOut", function(p) { 6678 return 1 - Math.pow(2, -10 * p); 6679 }), 6680 _create("ExpoIn", function(p) { 6681 return Math.pow(2, 10 * (p - 1)) - 0.001; 6682 }), 6683 _create("ExpoInOut", function(p) { 6684 return ((p *= 2) < 1) ? 0.5 * Math.pow(2, 10 * (p - 1)) : 0.5 * (2 - Math.pow(2, -10 * (p - 1))); 6685 }) 6686 ); 6687 6688 6689 //Sine 6690 _wrap("Sine", 6691 _create("SineOut", function(p) { 6692 return Math.sin(p * _HALF_PI); 6693 }), 6694 _create("SineIn", function(p) { 6695 return -Math.cos(p * _HALF_PI) + 1; 6696 }), 6697 _create("SineInOut", function(p) { 6698 return -0.5 * (Math.cos(Math.PI * p) - 1); 6699 }) 6700 ); 6701 6702 _class("easing.EaseLookup", { 6703 find:function(s) { 6704 return Ease.map[s]; 6705 } 6706 }, true); 6707 6708 //register the non-standard eases 6709 _easeReg(w.SlowMo, "SlowMo", "ease,"); 6710 _easeReg(RoughEase, "RoughEase", "ease,");
6711 _easeReg(SteppedEase, "SteppedEase", "ease,"); 6712 6713 return Back; 6714 6715 }, true); 6716 6717 6718}); 6719 6720if (_gsScope._gsDefine) { _gsScope._gsQueue.pop()(); } //necessary in case TweenLite was already loaded separately. 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732/* 6733 * ---------------------------------------------------------------- 6734 * Base classes like TweenLite, SimpleTimeline, Ease, Ticker, etc. 6735 * ---------------------------------------------------------------- 6736 */ 6737(function(window, moduleName) { 6738 6739 "use strict"; 6740 var _exports = {}, 6741 _doc = window.document, 6742 _globals = window.GreenSockGlobals = window.GreenSockGlobals || window; 6743 if (_globals.TweenLite) { 6744 return _globals.TweenLite; //in case the core set of classes is already loaded, don't instantiate twice. 6745 } 6746 var _namespace = function(ns) { 6747 var a = ns.split("."), 6748 p = _globals, i; 6749 for (i = 0; i < a.length; i++) { 6750 p[a[i]] = p = p[a[i]] || {}; 6751 } 6752 return p; 6753 }, 6754 gs = _namespace("com.greensock"), 6755 _tinyNum = 0.0000000001, 6756 _slice = function(a) { //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 6757 var b = [], 6758 l = a.length, 6759 i; 6760 for (i = 0; i !== l; b.push(a[i++])) {} 6761 return b; 6762 }, 6763 _emptyFunc = function() {}, 6764 _isArray = (function() { //works around issues in iframe environments where the Array global isn't shared, thus if the object originates in a different window/iframe, "(obj instanceof Array)" will evaluate false. We added some speed optimizations to avoid Object.prototype.toString.call() unless it's absolutely necessary because it's VERY slow (like 20x slower) 6765 var toString = Object.prototype.toString, 6766 array = toString.call([]); 6767 return function(obj) { 6768 return obj != null && (obj instanceof Array || (typeof(obj) === "object" && !!obj.push && toString.call(obj) === array)); 6769 }; 6770 }()), 6771 a, i, p, _ticker, _tickerActive, 6772 _defLookup = {}, 6773 6774 /** 6775 * @constructor 6776 * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition. 6777 * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is 6778 * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin 6779 * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally. 6780 * 6781 * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found, 6782 * it will go there as of v1.7). For example, TweenLite will be found at window.com.greensock.TweenLite and since it's a global class that should be available anywhere, 6783 * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so 6784 * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything 6785 * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock 6786 * files and put them into distinct objects (imagine a banner ad uses a newer version but the main site uses an older one). In that case, you could 6787 * sandbox the banner one like: 6788 * 6789 * <script> 6790 * var gs = window.GreenSockGlobals = {}; //the newer version we're about to load could now be referenced in a "gs" object, like gs.TweenLite.to(...). Use whatever alias you want as long as it's unique, "gs" or "banner" or whatever. 6791 * </script> 6792 * <script src="js/greensock/v1.7/TweenMax.js"></script> 6793 * <script> 6794 * window.GreenSockGlobals = window._gsQueue = window._gsDefine = null; //reset it back to null (along with the special _gsQueue variable) so that the next load of TweenMax affects the window and we can reference things directly like TweenLite.to(...) 6795 * </script> 6796 * <script src="js/greensock/v1.6/TweenMax.js"></script> 6797 * <script> 6798 * gs.TweenLite.to(...); //would use v1.7 6799 * TweenLite.to(...); //would use v1.6 6800 * </script> 6801 * 6802 * @param {!string} ns The namespace of the class definition, leaving off "com.greensock." as that's assumed. For example, "TweenLite" or "plugins.CSSPlugin" or "easing.Back". 6803 * @param {!Array.<string>}
6803 dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"] 6804 * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition. 6805 * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object) 6806 */ 6807 Definition = function(ns, dependencies, func, global) { 6808 this.sc = (_defLookup[ns]) ? _defLookup[ns].sc : []; //subclasses 6809 _defLookup[ns] = this; 6810 this.gsClass = null; 6811 this.func = func; 6812 var _classes = []; 6813 this.check = function(init) { 6814 var i = dependencies.length, 6815 missing = i, 6816 cur, a, n, cl; 6817 while (--i > -1) { 6818 if ((cur = _defLookup[dependencies[i]] || new Definition(dependencies[i], [])).gsClass) { 6819 _classes[i] = cur.gsClass; 6820 missing--; 6821 } else if (init) { 6822 cur.sc.push(this); 6823 } 6824 } 6825 if (missing === 0 && func) { 6826 a = ("com.greensock." + ns).split("."); 6827 n = a.pop(); 6828 cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes); 6829 6830 //exports to multiple environments 6831 if (global) { 6832 _globals[n] = _exports[n] = cl; //provides a way to avoid global namespace pollution. By default, the main classes like TweenLite, Power1, Strong, etc. are added to window unless a GreenSockGlobals is defined. So if you want to have things added to a custom object instead, just do something like window.GreenSockGlobals = {} before loading any GreenSock files. You can even set up an alias like window.GreenSockGlobals = windows.gs = {} so that you can access everything like gs.TweenLite. Also remember that ALL classes are added to the window.com.greensock object (in their respective packages, like com.greensock.easing.Power1, com.greensock.TweenLite, etc.) 6833 if (typeof(module) !== "undefined" && module.exports) { //node 6834 if (ns === moduleName) { 6835 module.exports = _exports[moduleName] = cl; 6836 for (i in _exports) { 6837 cl[i] = _exports[i]; 6838 } 6839 } else if (_exports[moduleName]) { 6840 _exports[moduleName][n] = cl; 6841 } 6842 } else if (typeof(define) === "function" && define.amd){ //AMD 6843 define((window.GreenSockAMDPath ? window.GreenSockAMDPath + "/" : "") + ns.split(".").pop(), [], function() { return cl; }); 6844 } 6845 } 6846 for (i = 0; i < this.sc.length; i++) { 6847 this.sc[i].check(); 6848 } 6849 } 6850 }; 6851 this.check(true); 6852 }, 6853 6854 //used to create Definition instances (which basically registers a class that has dependencies). 6855 _gsDefine = window._gsDefine = function(ns, dependencies, func, global) { 6856 return new Definition(ns, dependencies, func, global); 6857 }, 6858 6859 //a quick way to create a class that doesn't have any dependencies. Returns the class, but first registers it in the GreenSock namespace so that other classes can grab it (other classes might be dependent on the class). 6860 _class = gs._class = function(ns, func, global) { 6861 func = func || function() {}; 6862 _gsDefine(ns, [], function(){ return func; }, global); 6863 return func; 6864 }; 6865 6866 _gsDefine.globals = _globals; 6867 6868 6869 6870/* 6871 * ---------------------------------------------------------------- 6872 * Ease 6873 * ---------------------------------------------------------------- 6874 */ 6875 var _baseParams = [0, 0, 1, 1], 6876 Ease = _class("easing.Ease", function(func, extraParams, type, power) { 6877 this._func = func; 6878 this._type = type || 0; 6879 this._power = power || 0; 6880 this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams; 6881 }, true), 6882 _easeMap = Ease.map = {}, 6883 _easeReg = Ease.register = function(ease, names, types, create) { 6884 var na = names.split(","), 6885 i = na.length, 6886 ta = (types || "easeIn,easeOut,easeInOut").split(","), 6887 e, name, j, type; 6888 while (--i > -1) { 6889 name = na[i]; 6890 e = create ? _class("easing."+name, null, true) : gs.easing[name] || {}; 6891 j = ta.length; 6892 while (--j > -1) { 6893 type = ta[j]; 6894 _easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease(); 6895 } 6896 } 6897 }; 6898 6899 p = Ease.prototype; 6900 p._calcEnd = false;
6901 p.getRatio = function(p) { 6902 if (this._func) { 6903 this._params[0] = p; 6904 return this._func.apply(null, this._params); 6905 } 6906 var t = this._type, 6907 pw = this._power, 6908 r = (t === 1) ? 1 - p : (t === 2) ? p : (p < 0.5) ? p * 2 : (1 - p) * 2; 6909 if (pw === 1) { 6910 r *= r; 6911 } else if (pw === 2) { 6912 r *= r * r; 6913 } else if (pw === 3) { 6914 r *= r * r * r; 6915 } else if (pw === 4) { 6916 r *= r * r * r * r; 6917 } 6918 return (t === 1) ? 1 - r : (t === 2) ? r : (p < 0.5) ? r / 2 : 1 - (r / 2); 6919 }; 6920 6921 //create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut) 6922 a = ["Linear","Quad","Cubic","Quart","Quint,Strong"]; 6923 i = a.length; 6924 while (--i > -1) { 6925 p = a[i]+",Power"+i; 6926 _easeReg(new Ease(null,null,1,i), p, "easeOut", true); 6927 _easeReg(new Ease(null,null,2,i), p, "easeIn" + ((i === 0) ? ",easeNone" : "")); 6928 _easeReg(new Ease(null,null,3,i), p, "easeInOut"); 6929 } 6930 _easeMap.linear = gs.easing.Linear.easeIn; 6931 _easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks 6932 6933 6934/* 6935 * ---------------------------------------------------------------- 6936 * EventDispatcher 6937 * ---------------------------------------------------------------- 6938 */ 6939 var EventDispatcher = _class("events.EventDispatcher", function(target) { 6940 this._listeners = {}; 6941 this._eventTarget = target || this; 6942 }); 6943 p = EventDispatcher.prototype; 6944 6945 p.addEventListener = function(type, callback, scope, useParam, priority) { 6946 priority = priority || 0; 6947 var list = this._listeners[type], 6948 index = 0, 6949 listener, i; 6950 if (this === _ticker && !_tickerActive) { 6951 _ticker.wake(); 6952 } 6953 if (list == null) { 6954 this._listeners[type] = list = []; 6955 } 6956 i = list.length; 6957 while (--i > -1) { 6958 listener = list[i]; 6959 if (listener.c === callback && listener.s === scope) { 6960 list.splice(i, 1); 6961 } else if (index === 0 && listener.pr < priority) { 6962 index = i + 1; 6963 } 6964 } 6965 list.splice(index, 0, {c:callback, s:scope, up:useParam, pr:priority}); 6966 }; 6967 6968 p.removeEventListener = function(type, callback) { 6969 var list = this._listeners[type], i; 6970 if (list) { 6971 i = list.length; 6972 while (--i > -1) { 6973 if (list[i].c === callback) { 6974 list.splice(i, 1); 6975 return; 6976 } 6977 } 6978 } 6979 }; 6980 6981 p.dispatchEvent = function(type) { 6982 var list = this._listeners[type], 6983 i, t, listener; 6984 if (list) { 6985 i = list.length; 6986 if (i > 1) { 6987 list = list.slice(0); //in case addEventListener() is called from within a listener/callback (otherwise the index could change, resulting in a skip) 6988 } 6989 t = this._eventTarget; 6990 while (--i > -1) { 6991 listener = list[i]; 6992 if (listener) { 6993 if (listener.up) { 6994 listener.c.call(listener.s || t, {type:type, target:t}); 6995 } else { 6996 listener.c.call(listener.s || t); 6997 } 6998 } 6999 } 7000 } 7001 }; 7002 7003 7004/* 7005 * ---------------------------------------------------------------- 7006 * Ticker 7007 * ---------------------------------------------------------------- 7008 */ 7009 var _reqAnimFrame = window.requestAnimationFrame, 7010 _cancelAnimFrame = window.cancelAnimationFrame, 7011 _getTime = Date.now || function() {return new Date().getTime();}, 7012 _lastUpdate = _getTime(); 7013 7014 //now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill. 7015 a = ["ms","moz","webkit","o"]; 7016 i = a.length; 7017 while (--i > -1 && !_reqAnimFrame) { 7018 _reqAnimFrame = window[a[i] + "RequestAnimationFrame"]; 7019 _cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"]; 7020 } 7021 7022 _class("Ticker", function(fps, useRAF) { 7023 var _self = this, 7024 _startTime = _getTime(), 7025 _useRAF = (useRAF !== false && _reqAnimFrame) ? "auto" : false, 7026 _lagThreshold = 500, 7027 _adjustedLag = 33, 7028 _tickWord = "tick", //helps reduce gc burden 7029 _fps, _req, _id, _gap, _nextTime, 7030 _tick = function(manual) { 7031 var elapsed = _getTime() - _lastUpdate, 7032 overlap, dispatch; 7033 if (elapsed > _lagThreshold) { 7034 _startTime += elapsed - _adjustedLag; 7035 } 7036 _lastUpdate += elapsed; 7037 _self.time = (_lastUpdate - _startTime) / 1000; 7038 overlap = _self.time - _nextTime; 7039 if (!_fps || overlap > 0 || manual === true) { 7040 _self.frame++; 7041 _nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap); 7042 dispatch = true; 7043 } 7044 if (manual !== true) { //make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise. 7045 _id = _req(_tick); 7046 }
7047 if (dispatch) { 7048 _self.dispatchEvent(_tickWord); 7049 } 7050 }; 7051 7052 EventDispatcher.call(_self); 7053 _self.time = _self.frame = 0; 7054 _self.tick = function() { 7055 _tick(true); 7056 }; 7057 7058 _self.lagSmoothing = function(threshold, adjustedLag) { 7059 if (!arguments.length) { //if lagSmoothing() is called with no arguments, treat it like a getter that returns a boolean indicating if it's enabled or not. This is purposely undocumented and is for internal use. 7060 return (_lagThreshold < 1 / _tinyNum); 7061 } 7062 _lagThreshold = threshold || (1 / _tinyNum); //zero should be interpreted as basically unlimited 7063 _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); 7064 }; 7065 7066 _self.sleep = function() { 7067 if (_id == null) { 7068 return; 7069 } 7070 if (!_useRAF || !_cancelAnimFrame) { 7071 clearTimeout(_id); 7072 } else { 7073 _cancelAnimFrame(_id); 7074 } 7075 _req = _emptyFunc; 7076 _id = null; 7077 if (_self === _ticker) { 7078 _tickerActive = false; 7079 } 7080 }; 7081 7082 _self.wake = function(seamless) { 7083 if (_id !== null) { 7084 _self.sleep(); 7085 } else if (seamless) { 7086 _startTime += -_lastUpdate + (_lastUpdate = _getTime()); 7087 } else if (_self.frame > 10) { //don't trigger lagSmoothing if we're just waking up, and make sure that at least 10 frames have elapsed because of the iOS bug that we work around below with the 1.5-second setTimout(). 7088 _lastUpdate = _getTime() - _lagThreshold + 5; 7089 } 7090 _req = (_fps === 0) ? _emptyFunc : (!_useRAF || !_reqAnimFrame) ? function(f) { return setTimeout(f, ((_nextTime - _self.time) * 1000 + 1) | 0); } : _reqAnimFrame; 7091 if (_self === _ticker) { 7092 _tickerActive = true; 7093 } 7094 _tick(2); 7095 }; 7096 7097 _self.fps = function(value) { 7098 if (!arguments.length) { 7099 return _fps; 7100 } 7101 _fps = value; 7102 _gap = 1 / (_fps || 60); 7103 _nextTime = this.time + _gap; 7104 _self.wake(); 7105 }; 7106 7107 _self.useRAF = function(value) { 7108 if (!arguments.length) { 7109 return _useRAF; 7110 } 7111 _self.sleep(); 7112 _useRAF = value; 7113 _self.fps(_fps); 7114 }; 7115 _self.fps(fps); 7116 7117 //a bug in iOS 6 Safari occasionally prevents the requestAnimationFrame from working initially, so we use a 1.5-second timeout that automatically falls back to setTimeout() if it senses this condition. 7118 setTimeout(function() { 7119 if (_useRAF === "auto" && _self.frame < 5 && (_doc || {}).visibilityState !== "hidden") { 7120 _self.useRAF(false); 7121 } 7122 }, 1500); 7123 }); 7124 7125 p = gs.Ticker.prototype = new gs.events.EventDispatcher(); 7126 p.constructor = gs.Ticker; 7127 7128 7129/* 7130 * ---------------------------------------------------------------- 7131 * Animation 7132 * ---------------------------------------------------------------- 7133 */ 7134 var Animation = _class("core.Animation", function(duration, vars) { 7135 this.vars = vars = vars || {}; 7136 this._duration = this._totalDuration = duration || 0; 7137 this._delay = Number(vars.delay) || 0; 7138 this._timeScale = 1; 7139 this._active = (vars.immediateRender === true); 7140 this.data = vars.data; 7141 this._reversed = (vars.reversed === true); 7142 7143 if (!_rootTimeline) { 7144 return; 7145 } 7146 if (!_tickerActive) { //some browsers (like iOS 6 Safari) shut down JavaScript execution when the tab is disabled and they [occasionally] neglect to start up requestAnimationFrame again when returning - this code ensures that the engine starts up again properly. 7147 _ticker.wake(); 7148 } 7149 7150 var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline; 7151 tl.add(this, tl._time); 7152 7153 if (this.vars.paused) { 7154 this.paused(true); 7155 } 7156 }); 7157 7158 _ticker = Animation.ticker = new gs.Ticker(); 7159 p = Animation.prototype; 7160 p._dirty = p._gc = p._initted = p._paused = false; 7161 p._totalTime = p._time = 0; 7162 p._rawPrevTime = -1; 7163 p._next = p._last = p._onUpdate = p._timeline = p.timeline = null; 7164 p._paused = false; 7165 7166 7167 //some browsers (like iOS) occasionally drop the requestAnimationFrame event when the user switches to a different tab and then comes back again, so we use a 2-second setTimeout() to sense if/when that condition occurs and then wake() the ticker. 7168 var _checkTimeout = function() { 7169 if (_tickerActive && _getTime() - _lastUpdate > 2000 && ((_doc || {}).visibilityState !== "hidden" || !_ticker.lagSmoothing())) { //note: if the tab is hidden, we should still wake if lagSmoothing has been disabled. 7170 _ticker.wake(); 7171 } 7172 var t = setTimeout(_checkTimeout, 2000); 7173 if (t.unref) { 7174 // allows a node process to exit even if the timeoutâs callback hasn't been invoked. Without it, the node process could hang as this function is called every two seconds. 7175 t.unref(); 7176 } 7177 }; 7178 _checkTimeout(); 7179 7180 7181 p.play = function(from, suppressEvents) { 7182 if (from != null) { 7183 this.seek(from, suppressEvents); 7184 } 7185 return this.reversed(false).paused(false); 7186 }; 7187 7188 p.pause = function(atTime, suppressEvents) { 7189 if (atTime != null) { 7190 this.seek(atTime, suppressEvents); 7191 } 7192 return this.paused(true); 7193 }; 7194 7195 p.resume = function(from, suppressEvents) { 7196 if (from != null) { 7197 this.seek(from, suppressEvents); 7198 } 7199 return this.paused(false); 7200 }; 7201 7202 p.seek = function(time, suppressEvents) { 7203 return this.totalTime(Number(time), suppressEvents !== false); 7204 }; 7205 7206 p.restart = function(includeDelay, suppressEvents) { 7207 return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, (suppressEvents !== false), true); 7208 }; 7209 7210 p.reverse = function(from, suppressEvents) { 7211 if (from != null) { 7212 this.seek((from || this.totalDuration()), suppressEvents); 7213 } 7214 return this.reversed(true).paused(false); 7215 }; 7216 7217 p.render = function(time, suppressEvents, force) { 7218 //stub - we override this method in subclasses. 7219 }; 7220 7221 p.invalidate = function() { 7222 this._time = this._totalTime = 0; 7223 this._initted = this._gc = false;
7224 this._rawPrevTime = -1; 7225 if (this._gc || !this.timeline) { 7226 this._enabled(true); 7227 } 7228 return this; 7229 }; 7230 7231 p.isActive = function() { 7232 var tl = this._timeline, //the 2 root timelines won't have a _timeline; they're always active. 7233 startTime = this._startTime, 7234 rawTime; 7235 return (!tl || (!this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime(true)) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale - 0.0000001)); 7236 }; 7237 7238 p._enabled = function (enabled, ignoreTimeline) { 7239 if (!_tickerActive) { 7240 _ticker.wake(); 7241 } 7242 this._gc = !enabled; 7243 this._active = this.isActive(); 7244 if (ignoreTimeline !== true) { 7245 if (enabled && !this.timeline) { 7246 this._timeline.add(this, this._startTime - this._delay); 7247 } else if (!enabled && this.timeline) { 7248 this._timeline._remove(this, true); 7249 } 7250 } 7251 return false; 7252 }; 7253 7254 7255 p._kill = function(vars, target) { 7256 return this._enabled(false, false); 7257 }; 7258 7259 p.kill = function(vars, target) { 7260 this._kill(vars, target); 7261 return this; 7262 }; 7263 7264 p._uncache = function(includeSelf) { 7265 var tween = includeSelf ? this : this.timeline; 7266 while (tween) { 7267 tween._dirty = true; 7268 tween = tween.timeline; 7269 } 7270 return this; 7271 }; 7272 7273 p._swapSelfInParams = function(params) { 7274 var i = params.length, 7275 copy = params.concat(); 7276 while (--i > -1) { 7277 if (params[i] === "{self}") { 7278 copy[i] = this; 7279 } 7280 } 7281 return copy; 7282 }; 7283 7284 p._callback = function(type) { 7285 var v = this.vars, 7286 callback = v[type], 7287 params = v[type + "Params"], 7288 scope = v[type + "Scope"] || v.callbackScope || this, 7289 l = params ? params.length : 0; 7290 switch (l) { //speed optimization; call() is faster than apply() so use it when there are only a few parameters (which is by far most common). Previously we simply did var v = this.vars; v[type].apply(v[type + "Scope"] || v.callbackScope || this, v[type + "Params"] || _blankArray); 7291 case 0: callback.call(scope); break; 7292 case 1: callback.call(scope, params[0]); break; 7293 case 2: callback.call(scope, params[0], params[1]); break; 7294 default: callback.apply(scope, params); 7295 } 7296 }; 7297 7298//----Animation getters/setters -------------------------------------------------------- 7299 7300 p.eventCallback = function(type, callback, params, scope) { 7301 if ((type || "").substr(0,2) === "on") { 7302 var v = this.vars; 7303 if (arguments.length === 1) { 7304 return v[type]; 7305 } 7306 if (callback == null) { 7307 delete v[type]; 7308 } else { 7309 v[type] = callback; 7310 v[type + "Params"] = (_isArray(params) && params.join("").indexOf("{self}") !== -1) ? this._swapSelfInParams(params) : params; 7311 v[type + "Scope"] = scope; 7312 } 7313 if (type === "onUpdate") { 7314 this._onUpdate = callback; 7315 } 7316 } 7317 return this; 7318 }; 7319 7320 p.delay = function(value) { 7321 if (!arguments.length) { 7322 return this._delay; 7323 } 7324 if (this._timeline.smoothChildTiming) { 7325 this.startTime( this._startTime + value - this._delay ); 7326 } 7327 this._delay = value; 7328 return this; 7329 }; 7330 7331 p.duration = function(value) { 7332 if (!arguments.length) { 7333 this._dirty = false; 7334 return this._duration; 7335 } 7336 this._duration = this._totalDuration = value; 7337 this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration. 7338 if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) { 7339 this.totalTime(this._totalTime * (value / this._duration), true); 7340 } 7341 return this; 7342 }; 7343 7344 p.totalDuration = function(value) { 7345 this._dirty = false; 7346 return (!arguments.length) ? this._totalDuration : this.duration(value); 7347 }; 7348 7349 p.time = function(value, suppressEvents) { 7350 if (!arguments.length) { 7351 return this._time; 7352 } 7353 if (this._dirty) { 7354 this.totalDuration(); 7355 } 7356 return this.totalTime((value > this._duration) ? this._duration : value, suppressEvents); 7357 }; 7358 7359 p.totalTime = function(time, suppressEvents, uncapped) { 7360 if (!_tickerActive) { 7361 _ticker.wake(); 7362 } 7363 if (!arguments.length) { 7364 return this._totalTime; 7365 } 7366 if (this._timeline) { 7367 if (time < 0 && !uncapped) { 7368 time += this.totalDuration(); 7369 } 7370 if (this._timeline.smoothChildTiming) { 7371 if (this._dirty) { 7372 this.totalDuration(); 7373 } 7374 var totalDuration = this._totalDuration, 7375 tl = this._timeline; 7376 if (time > totalDuration && !uncapped) { 7377 time = totalDuration; 7378 } 7379 this._startTime = (this._paused ? this._pauseTime : tl._time) - ((!this._reversed ? time : totalDuration - time) / this._timeScale); 7380 if (!tl._dirty) { //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here. 7381 this._uncache(false); 7382 } 7383 //in case any of the ancestor timelines had completed but should now be enabled, we should reset the
7383ir totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed. 7384 if (tl._timeline) { 7385 while (tl._timeline) { 7386 if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) { 7387 tl.totalTime(tl._totalTime, true); 7388 } 7389 tl = tl._timeline; 7390 } 7391 } 7392 } 7393 if (this._gc) { 7394 this._enabled(true, false); 7395 } 7396 if (this._totalTime !== time || this._duration === 0) { 7397 if (_lazyTweens.length) { 7398 _lazyRender(); 7399 } 7400 this.render(time, suppressEvents, false); 7401 if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render. 7402 _lazyRender(); 7403 } 7404 } 7405 } 7406 return this; 7407 }; 7408 7409 p.progress = p.totalProgress = function(value, suppressEvents) { 7410 var duration = this.duration(); 7411 return (!arguments.length) ? (duration ? this._time / duration : this.ratio) : this.totalTime(duration * value, suppressEvents); 7412 }; 7413 7414 p.startTime = function(value) { 7415 if (!arguments.length) { 7416 return this._startTime; 7417 } 7418 if (value !== this._startTime) { 7419 this._startTime = value; 7420 if (this.timeline) if (this.timeline._sortChildren) { 7421 this.timeline.add(this, value - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct. 7422 } 7423 } 7424 return this; 7425 }; 7426 7427 p.endTime = function(includeRepeats) { 7428 return this._startTime + ((includeRepeats != false) ? this.totalDuration() : this.duration()) / this._timeScale; 7429 }; 7430 7431 p.timeScale = function(value) { 7432 if (!arguments.length) { 7433 return this._timeScale; 7434 } 7435 var pauseTime, t; 7436 value = value || _tinyNum; //can't allow zero because it'll throw the math off 7437 if (this._timeline && this._timeline.smoothChildTiming) { 7438 pauseTime = this._pauseTime; 7439 t = (pauseTime || pauseTime === 0) ? pauseTime : this._timeline.totalTime(); 7440 this._startTime = t - ((t - this._startTime) * this._timeScale / value); 7441 } 7442 this._timeScale = value; 7443 t = this.timeline; 7444 while (t && t.timeline) { //must update the duration/totalDuration of all ancestor timelines immediately in case in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though. 7445 t._dirty = true; 7446 t.totalDuration(); 7447 t = t.timeline; 7448 } 7449 return this; 7450 }; 7451 7452 p.reversed = function(value) { 7453 if (!arguments.length) { 7454 return this._reversed; 7455 } 7456 if (value != this._reversed) { 7457 this._reversed = value; 7458 this.totalTime(((this._timeline && !this._timeline.smoothChildTiming) ? this.totalDuration() - this._totalTime : this._totalTime), true); 7459 } 7460 return this; 7461 }; 7462 7463 p.paused = function(value) { 7464 if (!arguments.length) { 7465 return this._paused; 7466 } 7467 var tl = this._timeline, 7468 raw, elapsed; 7469 if (value != this._paused) if (tl) { 7470 if (!_tickerActive && !value) { 7471 _ticker.wake(); 7472 } 7473 raw = tl.rawTime(); 7474 elapsed = raw - this._pauseTime; 7475 if (!value && tl.smoothChildTiming) { 7476 this._startTime += elapsed; 7477 this._uncache(false); 7478 } 7479 this._pauseTime = value ? raw : null; 7480 this._paused = value; 7481 this._active = this.isActive(); 7482 if (!value && elapsed !== 0 && this._initted && this.duration()) { 7483 raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale; 7484 this.render(raw, (raw === this._totalTime), true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render. 7485 } 7486 } 7487 if (this._gc && !value) { 7488 this._enabled(true, false); 7489 } 7490 return this; 7491 }; 7492 7493
7494/* 7495 * ---------------------------------------------------------------- 7496 * SimpleTimeline 7497 * ---------------------------------------------------------------- 7498 */ 7499 var SimpleTimeline = _class("core.SimpleTimeline", function(vars) { 7500 Animation.call(this, 0, vars); 7501 this.autoRemoveChildren = this.smoothChildTiming = true; 7502 }); 7503 7504 p = SimpleTimeline.prototype = new Animation(); 7505 p.constructor = SimpleTimeline; 7506 p.kill()._gc = false; 7507 p._first = p._last = p._recent = null; 7508 p._sortChildren = false; 7509 7510 p.add = p.insert = function(child, position, align, stagger) { 7511 var prevTween, st; 7512 child._startTime = Number(position || 0) + child._delay; 7513 if (child._paused) if (this !== child._timeline) { //we only adjust the _pauseTime if it wasn't in this timeline already. Remember, sometimes a tween will be inserted again into the same timeline when its startTime is changed so that the tweens in the TimelineLite/Max are re-ordered properly in the linked list (so everything renders in the proper order). 7514 child._pauseTime = this.rawTime() - (child._timeline.rawTime() - child._pauseTime); 7515 } 7516 if (child.timeline) { 7517 child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one. 7518 } 7519 child.timeline = child._timeline = this; 7520 if (child._gc) { 7521 child._enabled(true, true); 7522 } 7523 prevTween = this._last; 7524 if (this._sortChildren) { 7525 st = child._startTime; 7526 while (prevTween && prevTween._startTime > st) { 7527 prevTween = prevTween._prev; 7528 } 7529 } 7530 if (prevTween) { 7531 child._next = prevTween._next; 7532 prevTween._next = child; 7533 } else { 7534 child._next = this._first; 7535 this._first = child; 7536 } 7537 if (child._next) { 7538 child._next._prev = child; 7539 } else { 7540 this._last = child; 7541 } 7542 child._prev = prevTween; 7543 this._recent = child; 7544 if (this._timeline) { 7545 this._uncache(true); 7546 } 7547 return this; 7548 }; 7549 7550 p._remove = function(tween, skipDisable) { 7551 if (tween.timeline === this) { 7552 if (!skipDisable) { 7553 tween._enabled(false, true); 7554 } 7555 7556 if (tween._prev) { 7557 tween._prev._next = tween._next; 7558 } else if (this._first === tween) { 7559 this._first = tween._next; 7560 } 7561 if (tween._next) { 7562 tween._next._prev = tween._prev; 7563 } else if (this._last === tween) { 7564 this._last = tween._prev; 7565 } 7566 tween._next = tween._prev = tween.timeline = null; 7567 if (tween === this._recent) { 7568 this._recent = this._last; 7569 } 7570 7571 if (this._timeline) { 7572 this._uncache(true); 7573 } 7574 } 7575 return this; 7576 }; 7577 7578 p.render = function(time, suppressEvents, force) { 7579 var tween = this._first, 7580 next; 7581 this._totalTime = this._time = this._rawPrevTime = time; 7582 while (tween) { 7583 next = tween._next; //record it here because the value could change after rendering... 7584 if (tween._active || (time >= tween._startTime && !tween._paused && !tween._gc)) { 7585 if (!tween._reversed) { 7586 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 7587 } else { 7588 tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force); 7589 } 7590 } 7591 tween = next; 7592 } 7593 }; 7594 7595 p.rawTime = function() { 7596 if (!_tickerActive) { 7597 _ticker.wake(); 7598 } 7599 return this._totalTime; 7600 }; 7601 7602/* 7603 * ---------------------------------------------------------------- 7604 * TweenLite 7605 * ---------------------------------------------------------------- 7606 */ 7607 var TweenLite = _class("TweenLite", function(target, duration, vars) { 7608 Animation.call(this, duration, vars); 7609 this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method) 7610 7611 if (target == null) { 7612 throw "Cannot tween a null target."; 7613 } 7614 7615 this.target = target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target; 7616 7617 var isSelector = (target.jquery || (target.length && target !== window && target[0] && (target[0] === window || (target[0].nodeType && target[0].style && !target.nodeType)))),
7618 overwrite = this.vars.overwrite, 7619 i, targ, targets; 7620 7621 this._overwrite = overwrite = (overwrite == null) ? _overwriteLookup[TweenLite.defaultOverwrite] : (typeof(overwrite) === "number") ? overwrite >> 0 : _overwriteLookup[overwrite]; 7622 7623 if ((isSelector || target instanceof Array || (target.push && _isArray(target))) && typeof(target[0]) !== "number") { 7624 this._targets = targets = _slice(target); //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 7625 this._propLookup = []; 7626 this._siblings = []; 7627 for (i = 0; i < targets.length; i++) { 7628 targ = targets[i]; 7629 if (!targ) { 7630 targets.splice(i--, 1); 7631 continue; 7632 } else if (typeof(targ) === "string") { 7633 targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings 7634 if (typeof(targ) === "string") { 7635 targets.splice(i+1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case) 7636 } 7637 continue; 7638 } else if (targ.length && targ !== window && targ[0] && (targ[0] === window || (targ[0].nodeType && targ[0].style && !targ.nodeType))) { //in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that <select> elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself. 7639 targets.splice(i--, 1); 7640 this._targets = targets = targets.concat(_slice(targ)); 7641 continue; 7642 } 7643 this._siblings[i] = _register(targ, this, false); 7644 if (overwrite === 1) if (this._siblings[i].length > 1) { 7645 _applyOverwrite(targ, this, null, 1, this._siblings[i]); 7646 } 7647 } 7648 7649 } else { 7650 this._propLookup = {}; 7651 this._siblings = _register(target, this, false); 7652 if (overwrite === 1) if (this._siblings.length > 1) { 7653 _applyOverwrite(target, this, null, 1, this._siblings); 7654 } 7655 } 7656 if (this.vars.immediateRender || (duration === 0 && this._delay === 0 && this.vars.immediateRender !== false)) { 7657 this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render) 7658 this.render(Math.min(0, -this._delay)); //in case delay is negative 7659 } 7660 }, true), 7661 _isSelector = function(v) { 7662 return (v && v.length && v !== window && v[0] && (v[0] === window || (v[0].nodeType && v[0].style && !v.nodeType))); //we cannot check "nodeType" if the target is window from within an iframe, otherwise it will trigger a security error in some browsers like Firefox. 7663 }, 7664 _autoCSS = function(vars, target) { 7665 var css = {}, 7666 p; 7667 for (p in vars) { 7668 if (!_reservedProps[p] && (!(p in target) || p === "transform" || p === "x" || p === "y" || p === "width" || p === "height" || p === "className" || p === "border") && (!_plugins[p] || (_plugins[p] && _plugins[p]._autoCSS))) { //note: <img> elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties. 7669 css[p] = vars[p]; 7670 delete vars[p]; 7671 } 7672 } 7673 vars.css = css; 7674 }; 7675 7676 p = TweenLite.prototype = new Animation(); 7677 p.constructor = TweenLite; 7678 p.kill()._gc = false; 7679 7680//----TweenLite defaults, overwrite management, and root updates ---------------------------------------------------- 7681 7682 p.ratio = 0; 7683 p._firstPT = p._targets = p._overwrittenProps = p._startAt = null; 7684 p._notifyPluginsOfEnabled = p._lazy = false; 7685 7686 TweenLite.version = "1.20.5"; 7687 TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1); 7688 TweenLite.defaultOverwrite = "auto"; 7689 TweenLite.ticker = _ticker; 7690 TweenLite.autoSleep = 120; 7691 TweenLite.lagSmoothing = function(threshold, adjustedLag) { 7692 _ticker.lagSmoothing(threshold, adjustedLag); 7693 }; 7694 7695 TweenLite.selector = window.$ || window.jQuery || function(e) { 7696 var selector = window.$ || window.jQuery; 7697 if (selector) { 7698 TweenLite.selector = selector; 7699 return selector(e); 7700 } 7701 if (!_doc) { //in some dev environments (like Angular 6), GSAP gets loaded before the document is defined! So re-query it here if/when necessary. 7702 _doc = window.document; 7703 } 7704 return (!_doc) ? e : (_doc.querySelectorAll ? _doc.querySelectorAll(e) : _doc.getElementById((e.charAt(0) === "#") ? e.substr(1) : e)); 7705 }; 7706 7707 var _lazyTweens = [], 7708 _lazyLookup = {}, 7709 _numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 7710 _relExp = /[\+-]=-?[\.\d]/, 7711 //_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig, 7712 _setRatio = function(v) { 7713 var pt = this._firstPT, 7714 min = 0.000001, 7715 val; 7716 while (pt) { 7717 val = !pt.blob ? pt.c * v + pt.s : (v === 1 && this.end != null) ? this.end : v ? this.join("") : this.start; 7718 if (pt.m) { 7719 val = pt.m.call(this._tween, val, this._target || pt.t, this._tween); 7720 } else if (val < min) if (val >
7720 -min && !pt.blob) { //prevents issues with converting very small numbers to strings in the browser 7721 val = 0; 7722 } 7723 if (!pt.f) { 7724 pt.t[pt.p] = val; 7725 } else if (pt.fp) { 7726 pt.t[pt.p](pt.fp, val); 7727 } else { 7728 pt.t[pt.p](val); 7729 } 7730 pt = pt._next; 7731 } 7732 }, 7733 //compares two strings (start/end), finds the numbers that are different and spits back an array representing the whole value but with the changing values isolated as elements. For example, "rgb(0,0,0)" and "rgb(100,50,0)" would become ["rgb(", 0, ",", 50, ",0)"]. Notice it merges the parts that are identical (performance optimization). The array also has a linked list of PropTweens attached starting with _firstPT that contain the tweening data (t, p, s, c, f, etc.). It also stores the starting value as a "start" property so that we can revert to it if/when necessary, like when a tween rewinds fully. If the quantity of numbers differs between the start and end, it will always prioritize the end value(s). The pt parameter is optional - it's for a PropTween that will be appended to the end of the linked list and is typically for actually setting the value after all of the elements have been updated (with array.join("")). 7734 _blobDif = function(start, end, filter, pt) { 7735 var a = [], 7736 charIndex = 0, 7737 s = "", 7738 color = 0, 7739 startNums, endNums, num, i, l, nonNumbers, currentNum; 7740 a.start = start; 7741 a.end = end; 7742 start = a[0] = start + ""; //ensure values are strings 7743 end = a[1] = end + ""; 7744 if (filter) { 7745 filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values. 7746 start = a[0]; 7747 end = a[1]; 7748 } 7749 a.length = 0; 7750 startNums = start.match(_numbersExp) || []; 7751 endNums = end.match(_numbersExp) || []; 7752 if (pt) { 7753 pt._next = null; 7754 pt.blob = 1; 7755 a._firstPT = a._applyPT = pt; //apply last in the linked list (which means inserting it first) 7756 } 7757 l = endNums.length; 7758 for (i = 0; i < l; i++) { 7759 currentNum = endNums[i]; 7760 nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex)-charIndex); 7761 s += (nonNumbers || !i) ? nonNumbers : ","; //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case. 7762 charIndex += nonNumbers.length; 7763 if (color) { //sense rgba() values and round them. 7764 color = (color + 1) % 5; 7765 } else if (nonNumbers.substr(-5) === "rgba(") { 7766 color = 1; 7767 } 7768 if (currentNum === startNums[i] || startNums.length <= i) { 7769 s += currentNum; 7770 } else { 7771 if (s) { 7772 a.push(s); 7773 s = ""; 7774 } 7775 num = parseFloat(startNums[i]); 7776 a.push(num); 7777 a._firstPT = {_next: a._firstPT, t:a, p: a.length-1, s:num, c:((currentNum.charAt(1) === "=") ? parseInt(currentNum.charAt(0) + "1", 10) * parseFloat(currentNum.substr(2)) : (parseFloat(currentNum) - num)) || 0, f:0, m:(color && color < 4) ? Math.round : 0}; 7778 //note: we don't set _prev because we'll never need to remove individual PropTweens from this list. 7779 } 7780 charIndex += currentNum.length; 7781 } 7782 s += end.substr(charIndex); 7783 if (s) { 7784 a.push(s); 7785 } 7786 a.setRatio = _setRatio; 7787 if (_relExp.test(end)) { //if the end string contains relative values, delete it so that on the final render (in _setRatio()), we don't actually set it to the string with += or -= characters (forces it to use the calculated value). 7788 a.end = null; 7789 } 7790 return a; 7791 }, 7792 //note: "funcParam" is only necessary for function-based getters/setters that require an extra parameter like getAttribute("width") and setAttribute("width", value). In this example, funcParam would be "width". Used by AttrPlugin for example. 7793 _addPropTween = function(target, prop, start, end, overwriteProp, mod, funcParam, stringFilter, index) { 7794 if (typeof(end) === "function") { 7795 end = end(index || 0, target); 7796 } 7797 var type = typeof(target[prop]), 7798 getterName = (type !== "function") ? "" : ((prop.indexOf("set") || typeof(target["get" + prop.substr(3)]) !== "function") ? prop : "get" + prop.substr(3)), 7799 s = (start !== "get") ? start : !getterName ? target[prop] : funcParam ? target[getterName](funcParam) : target[getterName](), 7800 isRelative = (typeof(end) === "string" && end.charAt(1) === "="), 7801 pt = {t:target, p:prop, s:s, f:(type === "function"), pg:0, n:overwriteProp || prop, m:(!mod ? 0 : (typeof(mod) === "function") ? mod : Math.round), pr:0, c:isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : (parseFloat(end) - s) || 0}, 7802 blob; 7803 7804 if (typeof(s) !== "number" || (typeof(end) !== "number" && !isRelative)) { 7805 if (funcParam || isNaN(s) || (!isRelative && isNaN(end)) || typeof(s) === "boolean" || typeof(end) === "boolean") { 7806 //a blob (string that has multiple numbers in it) 7807 pt.fp = funcParam; 7808 blob = _blobDif(s, (isRelative ? (parseFloat(pt.s) + pt.c) + (pt.s + "").replace(/[0-9\-\.]/g, "") : end), stringFilter || TweenLite.defaultStringFilter, pt); 7809 pt = {t: blob, p: "setRatio", s: 0, c: 1, f: 2, pg: 0, n: overwriteProp || prop, pr: 0, m: 0}; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example. 7810 } else { 7811 pt.s = parseFloat(s); 7812 if (!isRelative) { 7813 pt.c = (parseFloat(end) - pt.s) || 0; 7814 } 7815 } 7816 } 7817 if (pt.c) { //only add it to the linked list if there's a change. 7818 if ((pt._next = this._firstPT)) { 7819 pt._next._prev = pt; 7820 } 7821 this._firstPT = pt; 7822 return pt; 7823 } 7824 }, 7825 _internals = TweenLite._internals = {isArray:_isArray, isSelector:_isSelector, lazyTweens:_lazyTweens, blobDif:_blobDif}, //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object. 7826 _plugins = TweenLite._plugins = {}, 7827 _tweenLookup = _internals.tweenLookup = {}, 7828 _tweenLookupNum = 0, 7829 _reservedProps = _internals.reservedProps = {ease:1, delay:1, overwrite:1, onComplete:1, onCompleteParams:1, onCompleteScope:1, useFrames:1, runBackwards:1, startAt:1, onUp
7829date:1, onUpdateParams:1, onUpdateScope:1, onStart:1, onStartParams:1, onStartScope:1, onReverseComplete:1, onReverseCompleteParams:1, onReverseCompleteScope:1, onRepeat:1, onRepeatParams:1, onRepeatScope:1, easeParams:1, yoyo:1, immediateRender:1, repeat:1, repeatDelay:1, data:1, paused:1, reversed:1, autoCSS:1, lazy:1, onOverwrite:1, callbackScope:1, stringFilter:1, id:1, yoyoEase:1}, 7830 _overwriteLookup = {none:0, all:1, auto:2, concurrent:3, allOnStart:4, preexisting:5, "true":1, "false":0}, 7831 _rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(), 7832 _rootTimeline = Animation._rootTimeline = new SimpleTimeline(), 7833 _nextGCFrame = 30, 7834 _lazyRender = _internals.lazyRender = function() { 7835 var i = _lazyTweens.length, 7836 tween; 7837 _lazyLookup = {}; 7838 while (--i > -1) { 7839 tween = _lazyTweens[i]; 7840 if (tween && tween._lazy !== false) { 7841 tween.render(tween._lazy[0], tween._lazy[1], true); 7842 tween._lazy = false; 7843 } 7844 } 7845 _lazyTweens.length = 0; 7846 }; 7847 7848 _rootTimeline._startTime = _ticker.time; 7849 _rootFramesTimeline._startTime = _ticker.frame; 7850 _rootTimeline._active = _rootFramesTimeline._active = true; 7851 setTimeout(_lazyRender, 1); //on some mobile devices, there isn't a "tick" before code runs which means any lazy renders wouldn't run before the next official "tick". 7852 7853 Animation._updateRoot = TweenLite.render = function() { 7854 var i, a, p; 7855 if (_lazyTweens.length) { //if code is run outside of the requestAnimationFrame loop, there may be tweens queued AFTER the engine refreshed, so we need to ensure any pending renders occur before we refresh again. 7856 _lazyRender(); 7857 } 7858 _rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false); 7859 _rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false); 7860 if (_lazyTweens.length) { 7861 _lazyRender(); 7862 } 7863 if (_ticker.frame >= _nextGCFrame) { //dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to 7864 _nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120); 7865 for (p in _tweenLookup) { 7866 a = _tweenLookup[p].tweens; 7867 i = a.length; 7868 while (--i > -1) { 7869 if (a[i]._gc) { 7870 a.splice(i, 1); 7871 } 7872 } 7873 if (a.length === 0) { 7874 delete _tweenLookup[p]; 7875 } 7876 } 7877 //if there are no more tweens in the root timelines, or if they're all paused, make the _timer sleep to reduce load on the CPU slightly 7878 p = _rootTimeline._first; 7879 if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) { 7880 while (p && p._paused) { 7881 p = p._next; 7882 } 7883 if (!p) { 7884 _ticker.sleep(); 7885 } 7886 } 7887 } 7888 }; 7889 7890 _ticker.addEventListener("tick", Animation._updateRoot); 7891 7892 var _register = function(target, tween, scrub) { 7893 var id = target._gsTweenID, a, i; 7894 if (!_tweenLookup[id || (target._gsTweenID = id = "t" + (_tweenLookupNum++))]) { 7895 _tweenLookup[id] = {target:target, tweens:[]}; 7896 } 7897 if (tween) { 7898 a = _tweenLookup[id].tweens; 7899 a[(i = a.length)] = tween; 7900 if (scrub) { 7901 while (--i > -1) { 7902 if (a[i] === tween) { 7903 a.splice(i, 1); 7904 } 7905 } 7906 } 7907 } 7908 return _tweenLookup[id].tweens; 7909 }, 7910 _onOverwrite = function(overwrittenTween, overwritingTween, target, killedProps) { 7911 var func = overwrittenTween.vars.onOverwrite, r1, r2; 7912 if (func) { 7913 r1 = func(overwrittenTween, overwritingTween, target, killedProps); 7914 } 7915 func = TweenLite.onOverwrite; 7916 if (func) { 7917 r2 = func(overwrittenTween, overwritingTween, target, killedProps); 7918 } 7919 return (r1 !== false && r2 !== false); 7920 }, 7921 _applyOverwrite = function(target, tween, props, mode, siblings) { 7922 var i, changed, curTween, l; 7923 if (mode === 1 || mode >= 4) { 7924 l = siblings.length; 7925 for (i = 0; i < l; i++) { 7926 if ((curTween = siblings[i]) !== tween) { 7927 if (!curTween._gc) { 7928 if (curTween._kill(null, target, tween)) { 7929 changed = true; 7930 } 7931 } 7932 } else if (mode === 5) { 7933 break; 7934 } 7935 } 7936 return changed; 7937 } 7938 //NOTE: Add 0.0000000001 to overcome floating point errors that can cause the startTime to be VERY slightly off (when a tween's time() is set for example) 7939 var startTime = tween._startTime + _tinyNum, 7940 overlaps = [], 7941 oCount = 0, 7942 zeroDur = (tween._duration === 0), 7943 globalStart; 7944 i = siblings.length; 7945 while (--i > -1) { 7946 if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) { 7947 //ignore 7948 } else if (curTween._timeline !== tween._timeline) { 7949 globalStart = globalStart || _checkOverlap(tween, 0, zeroDur); 7950 if (_checkOverlap(curTween, globalStart, zeroDur) === 0) { 7951 overlaps[oCount++] = curTween; 7952 } 7953 } else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) { 7954 overlaps[oCount++] = curTween; 7955 } 7956 } 7957 7958 i = oCount; 7959 while (--i > -1) { 7960 curTween = overlaps[i]; 7961 if (mode === 2) if (curTween._kill(props, target, tween)) { 7962 changed = true; 7963 } 7964 if (mode !== 2 || (!curTween._firstPT && curTween._initted)) { 7965 if (mode !== 2 && !_onOverwrite(curTween, tween)) { 7966 continue; 7967 } 7968 if (curTween._enabled(false, false)) { //if all property tweens have been overwritten, kill the tween. 7969 changed = true; 7970 } 7971 } 7972 } 7973 return changed; 7974 }, 7975 _checkOverlap = function(tween, reference, zeroDur) { 7976 var tl = tween._timeline, 7977 ts = tl._timeScale, 7978 t = tween._startTime; 7979 while (tl._timeline) { 7980 t += tl._startTime; 7981 ts *= tl._timeScale; 7982 if (tl._paused) { 7983 return -100; 7984 } 7985 tl = tl._timeline; 7986 } 7987 t /= ts; 7988 return (t > reference) ? t - reference : ((zeroDur && t === reference) || (!tween._initted && t - reference < 2 * _tinyNum)) ? _tinyNum : ((t += tween.totalDuration() / tween._timeScale / ts) > reference + _tinyNum) ? 0 : t - reference - _tinyNum; 7989 }; 7990 7991 7992//---- TweenLite instance methods ----------------------------------------------------------------------------- 7993 7994 p._init = function() { 7995 var v = this.vars, 7996 op = this._overwrittenProps, 7997 dur = this._duration, 7998 immediate = !!v.immediateRender, 7999 ease = v.ease, 8000 i, initPlugins, pt, p, startVars, l; 8001 if (v.startAt) { 8002 if (this._startAt) { 8003 this._startAt.render(-1, true); //if we've run a startAt previously (when the tween instantiated), we should revert it so that the values re-instantiate correctly particularly for relative tweens. Without this, a TweenLite.fromTo(obj, 1, {x:"+=100"}, {x:"-=100"}), for example, would actually jump to +=200 because the startAt would run twice, doubling the relative change. 8004 this._startAt.kill(); 8005 } 8006 startVars = {}; 8007 for (p in v.startAt) { //copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, 1, from, to).fromTo(e, 1, to, from); 8008 startVars[p] = v.startAt[p]; 8009 } 8010 startVars.data = "isStart"; 8011 startVars.overwrite = false;
8012 startVars.immediateRender = true; 8013 startVars.lazy = (immediate && v.lazy !== false); 8014 startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop). 8015 startVars.onUpdate = v.onUpdate; 8016 startVars.onUpdateParams = v.onUpdateParams; 8017 startVars.onUpdateScope = v.onUpdateScope || v.callbackScope || this; 8018 this._startAt = TweenLite.to(this.target || {}, 0, startVars); 8019 if (immediate) { 8020 if (this._time > 0) { 8021 this._startAt = null; //tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in TimelineLite/Max instances where immediateRender was false (which is the default in the convenience methods like from()). 8022 } else if (dur !== 0) { 8023 return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a TimelineLite or TimelineMax, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting. 8024 } 8025 } 8026 } else if (v.runBackwards && dur !== 0) { 8027 //from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards) 8028 if (this._startAt) { 8029 this._startAt.render(-1, true); 8030 this._startAt.kill(); 8031 this._startAt = null; 8032 } else { 8033 if (this._time !== 0) { //in rare cases (like if a from() tween runs and then is invalidate()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0 8034 immediate = false; 8035 } 8036 pt = {}; 8037 for (p in v) { //copy props into a new object and skip any reserved props, otherwise onComplete or onUpdate or onStart could fire. We should, however, permit autoCSS to go through. 8038 if (!_reservedProps[p] || p === "autoCSS") { 8039 pt[p] = v[p]; 8040 } 8041 } 8042 pt.overwrite = 0; 8043 pt.data = "isFromStart"; //we tag the tween with as "isFromStart" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a "from()" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in. 8044 pt.lazy = (immediate && v.lazy !== false); 8045 pt.immediateRender = immediate; //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after) 8046 this._startAt = TweenLite.to(this.target, 0, pt); 8047 if (!immediate) { 8048 this._startAt._init(); //ensures that the initial values are recorded 8049 this._startAt._enabled(false); //no need to have the tween render on the next cycle. Disable it because we'll always manually control the renders of the _startAt tween. 8050 if (this.vars.immediateRender) { 8051 this._startAt = null; 8052 } 8053 } else if (this._time === 0) { 8054 return; 8055 } 8056 } 8057 } 8058 this._ease = ease = (!ease) ? TweenLite.defaultEase : (ease instanceof Ease) ? ease : (typeof(ease) === "function") ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase; 8059 if (v.easeParams instanceof Array && ease.config) { 8060 this._ease = ease.config.apply(ease, v.easeParams); 8061 } 8062 this._easeType = this._ease._type; 8063 this._easePower = this._ease._power; 8064 this._firstPT = null; 8065 8066 if (this._targets) { 8067 l = this._targets.length; 8068 for (i = 0; i < l; i++) { 8069 if ( this._initProps( this._targets[i], (this._propLookup[i] = {}), this._siblings[i], (op ? op[i] : null), i) ) { 8070 initPlugins = true; 8071 } 8072 } 8073 } else { 8074 initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op, 0); 8075 } 8076 8077 if (initPlugins) { 8078 TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite 8079 } 8080 if (op) if (!this._firstPT) if (typeof(this.target) !== "function") { //if all tweening properties have been overwritten, kill the tween. If the target is a function, it's probably a delayedCall so let it live. 8081 this._enabled(false, false); 8082 } 8083 if (v.runBackwards) { 8084 pt = this._firstPT; 8085 while (pt) { 8086 pt.s += pt.c; 8087 pt.c = -pt.c; 8088 pt = pt._next; 8089 } 8090 } 8091 this._onUpdate = v.onUpdate; 8092 this._initted = true; 8093 }; 8094 8095 p._initProps = function(target, propLookup, siblings, overwrittenProps, index) { 8096 var p, i, initPlugins, plugin, pt, v; 8097 if (target == null) { 8098 return false;
8099 } 8100 8101 if (_lazyLookup[target._gsTweenID]) { 8102 _lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end) 8103 } 8104 8105 if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) { //it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity). Note: we cannot check "nodeType" on the window inside an iframe. 8106 _autoCSS(this.vars, target); 8107 } 8108 for (p in this.vars) { 8109 v = this.vars[p]; 8110 if (_reservedProps[p]) { 8111 if (v) if ((v instanceof Array) || (v.push && _isArray(v))) if (v.join("").indexOf("{self}") !== -1) { 8112 this.vars[p] = v = this._swapSelfInParams(v, this); 8113 } 8114 8115 } else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this, index)) { 8116 8117 //t - target [object] 8118 //p - property [string] 8119 //s - start [number] 8120 //c - change [number] 8121 //f - isFunction [boolean] 8122 //n - name [string] 8123 //pg - isPlugin [boolean] 8124 //pr - priority [number] 8125 //m - mod [function | 0] 8126 this._firstPT = pt = {_next:this._firstPT, t:plugin, p:"setRatio", s:0, c:1, f:1, n:p, pg:1, pr:plugin._priority, m:0}; 8127 i = plugin._overwriteProps.length; 8128 while (--i > -1) { 8129 propLookup[plugin._overwriteProps[i]] = this._firstPT; 8130 } 8131 if (plugin._priority || plugin._onInitAllProps) { 8132 initPlugins = true; 8133 } 8134 if (plugin._onDisable || plugin._onEnable) { 8135 this._notifyPluginsOfEnabled = true; 8136 } 8137 if (pt._next) { 8138 pt._next._prev = pt; 8139 } 8140 8141 } else { 8142 propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter, index); 8143 } 8144 } 8145 8146 if (overwrittenProps) if (this._kill(overwrittenProps, target)) { //another tween may have tried to overwrite properties of this tween before init() was called (like if two tweens start at the same time, the one created second will run first) 8147 return this._initProps(target, propLookup, siblings, overwrittenProps, index); 8148 } 8149 if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) { 8150 this._kill(propLookup, target); 8151 return this._initProps(target, propLookup, siblings, overwrittenProps, index); 8152 } 8153 if (this._firstPT) if ((this.vars.lazy !== false && this._duration) || (this.vars.lazy && !this._duration)) { //zero duration tweens don't lazy render by default; everything else does. 8154 _lazyLookup[target._gsTweenID] = true; 8155 } 8156 return initPlugins; 8157 }; 8158 8159 p.render = function(time, suppressEvents, force) { 8160 var prevTime = this._time, 8161 duration = this._duration, 8162 prevRawPrevTime = this._rawPrevTime, 8163 isComplete, callback, pt, rawPrevTime; 8164 if (time >= duration - 0.0000001 && time >= 0) { //to work around occasional floating point math artifacts. 8165 this._totalTime = this._time = duration; 8166 this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1; 8167 if (!this._reversed ) { 8168 isComplete = true; 8169 callback = "onComplete"; 8170 force = (force || this._timeline.autoRemoveChildren); //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 8171 } 8172 if (duration === 0) if (this._initted || !this.vars.lazy || force) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 8173 if (this._startTime === this._timeline._duration) { //if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent roun
8173ding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate. 8174 time = 0; 8175 } 8176 if (prevRawPrevTime < 0 || (time <= 0 && time >= -0.0000001) || (prevRawPrevTime === _tinyNum && this.data !== "isPause")) if (prevRawPrevTime !== time) { //note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause. 8177 force = true; 8178 if (prevRawPrevTime > _tinyNum) { 8179 callback = "onReverseComplete"; 8180 } 8181 } 8182 this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 8183 } 8184 8185 } else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0. 8186 this._totalTime = this._time = 0; 8187 this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0; 8188 if (prevTime !== 0 || (duration === 0 && prevRawPrevTime > 0)) { 8189 callback = "onReverseComplete"; 8190 isComplete = this._reversed; 8191 } 8192 if (time < 0) { 8193 this._active = false; 8194 if (duration === 0) if (this._initted || !this.vars.lazy || force) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 8195 if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) { 8196 force = true; 8197 } 8198 this._rawPrevTime = rawPrevTime = (!suppressEvents || time || prevRawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 8199 } 8200 } 8201 if (!this._initted || (this._startAt && this._startAt.progress())) { //if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. Also, we check progress() because if startAt has already rendered at its end, we should force a render at its beginning. Otherwise, if you put the playhead directly on top of where a fromTo({immediateRender:false}) starts, and then move it backwards, the from() won't revert its values. 8202 force = true; 8203 } 8204 } else { 8205 this._totalTime = this._time = time; 8206 8207 if (this._easeType) { 8208 var r = time / duration, type = this._easeType, pow = this._easePower; 8209 if (type === 1 || (type === 3 && r >= 0.5)) { 8210 r = 1 - r; 8211 } 8212 if (type === 3) { 8213 r *= 2; 8214 } 8215 if (pow === 1) { 8216 r *= r; 8217 } else if (pow === 2) { 8218 r *= r * r; 8219 } else if (pow === 3) { 8220 r *= r * r * r; 8221 } else if (pow === 4) { 8222 r *= r * r * r * r; 8223 } 8224 8225 if (type === 1) { 8226 this.ratio = 1 - r; 8227 } else if (type === 2) { 8228 this.ratio = r; 8229 } else if (time / duration < 0.5) { 8230 this.ratio = r / 2; 8231 } else { 8232 this.ratio = 1 - (r / 2); 8233 } 8234 8235 } else { 8236 this.ratio = this._ease.getRatio(time / duration); 8237 } 8238 } 8239 8240 if (this._time === prevTime && !force) { 8241 return; 8242 } else if (!this._initted) { 8243 this._init(); 8244 if (!this._initted || this._gc) { //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that over
8244writing occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example. 8245 return; 8246 } else if (!force && this._firstPT && ((this.vars.lazy !== false && this._duration) || (this.vars.lazy && !this._duration))) { 8247 this._time = this._totalTime = prevTime; 8248 this._rawPrevTime = prevRawPrevTime; 8249 _lazyTweens.push(this); 8250 this._lazy = [time, suppressEvents]; 8251 return; 8252 } 8253 //_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently. 8254 if (this._time && !isComplete) { 8255 this.ratio = this._ease.getRatio(this._time / duration); 8256 } else if (isComplete && this._ease._calcEnd) { 8257 this.ratio = this._ease.getRatio((this._time === 0) ? 0 : 1); 8258 } 8259 } 8260 if (this._lazy !== false) { //in case a lazy render is pending, we should flush it because the new render is occurring now (imagine a lazy tween instantiating and then immediately the user calls tween.seek(tween.duration()), skipping to the end - the end render would be forced, and then if we didn't flush the lazy render, it'd fire AFTER the seek(), rendering it at the wrong time. 8261 this._lazy = false; 8262 } 8263 if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) { 8264 this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. 8265 } 8266 if (prevTime === 0) { 8267 if (this._startAt) { 8268 if (time >= 0) { 8269 this._startAt.render(time, true, force); 8270 } else if (!callback) { 8271 callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area. 8272 } 8273 } 8274 if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) { 8275 this._callback("onStart"); 8276 } 8277 } 8278 pt = this._firstPT; 8279 while (pt) { 8280 if (pt.f) { 8281 pt.t[pt.p](pt.c * this.ratio + pt.s); 8282 } else { 8283 pt.t[pt.p] = pt.c * this.ratio + pt.s; 8284 } 8285 pt = pt._next; 8286 } 8287 8288 if (this._onUpdate) { 8289 if (time < 0) if (this._startAt && time !== -0.0001) { //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values. 8290 this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete. 8291 } 8292 if (!suppressEvents) if (this._time !== prevTime || isComplete || force) { 8293 this._callback("onUpdate"); 8294 } 8295 } 8296 if (callback) if (!this._gc || force) { //check _gc because there's a chance that kill() could be called in an onUpdate 8297 if (time < 0 && this._startAt && !this._onUpdate && time !== -0.0001) { //-0.0001 is a special value that we use when looping back to the beginning of a repeated TimelineMax, in which case we shouldn't render the _startAt values. 8298 this._startAt.render(time, true, force); 8299 } 8300 if (isComplete) { 8301 if (this._timeline.autoRemoveChildren) { 8302 this._enabled(false, false); 8303 } 8304 this._active = false;
8305 } 8306 if (!suppressEvents && this.vars[callback]) { 8307 this._callback(callback); 8308 } 8309 if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { //the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon scenario, but possible nonetheless. 8310 this._rawPrevTime = 0; 8311 } 8312 } 8313 }; 8314 8315 p._kill = function(vars, target, overwritingTween) { 8316 if (vars === "all") { 8317 vars = null; 8318 } 8319 if (vars == null) if (target == null || target === this.target) { 8320 this._lazy = false; 8321 return this._enabled(false, false); 8322 } 8323 target = (typeof(target) !== "string") ? (target || this._targets || this.target) : TweenLite.selector(target) || target; 8324 var simultaneousOverwrite = (overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline), 8325 i, overwrittenProps, p, pt, propLookup, changed, killProps, record, killed; 8326 if ((_isArray(target) || _isSelector(target)) && typeof(target[0]) !== "number") { 8327 i = target.length; 8328 while (--i > -1) { 8329 if (this._kill(vars, target[i], overwritingTween)) { 8330 changed = true; 8331 } 8332 } 8333 } else { 8334 if (this._targets) { 8335 i = this._targets.length; 8336 while (--i > -1) { 8337 if (target === this._targets[i]) { 8338 propLookup = this._propLookup[i] || {}; 8339 this._overwrittenProps = this._overwrittenProps || []; 8340 overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all"; 8341 break; 8342 } 8343 } 8344 } else if (target !== this.target) { 8345 return false; 8346 } else { 8347 propLookup = this._propLookup; 8348 overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all"; 8349 } 8350 8351 if (propLookup) { 8352 killProps = vars || propLookup; 8353 record = (vars !== overwrittenProps && overwrittenProps !== "all" && vars !== propLookup && (typeof(vars) !== "object" || !vars._tempKill)); //_tempKill is a super-secret way to delete a particular tweening property but NOT have it remembered as an official overwritten property (like in BezierPlugin) 8354 if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) { 8355 for (p in killProps) { 8356 if (propLookup[p]) { 8357 if (!killed) { 8358 killed = []; 8359 } 8360 killed.push(p); 8361 } 8362 } 8363 if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) { //if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it). 8364 return false; 8365 } 8366 } 8367 8368 for (p in killProps) { 8369 if ((pt = propLookup[p])) { 8370 if (simultaneousOverwrite) { //if another tween overwrites this one and they both start at exactly the same time, yet this tween has already rendered once (for example, at 0.001) because it's first in the queue, we should revert the values to where they were at 0 so that the starting values aren't contaminated on the overwriting tween. 8371 if (pt.f) { 8372 pt.t[pt.p](pt.s); 8373 } else { 8374 pt.t[pt.p] = pt.s; 8375 } 8376 changed = true; 8377 } 8378 if (pt.pg && pt.t._kill(killProps)) { 8379 changed = true; //some plugins need to be notified so they can perform cleanup tasks first 8380 } 8381 if (!pt.pg || pt.t._overwriteProps.length === 0) { 8382 if (pt._prev) { 8383 pt._prev._next = pt._next; 8384 } else if (pt === this._firstPT) { 8385 this._firstPT = pt._next; 8386 } 8387 if (pt._next) { 8388 pt._next._prev = pt._prev; 8389 } 8390 pt._next = pt._prev = null; 8391 } 8392 delete propLookup[p]; 8393 } 8394 if (record) { 8395 overwrittenProps[p] = 1; 8396 } 8397 } 8398 if (!this._firstPT && this._initted) { //if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening. 8399 this._enabled(false, false); 8400 } 8401 } 8402 } 8403 return changed; 8404 }; 8405 8406 p.invalidate = function() { 8407 if (this._notifyPluginsOfEnabled) { 8408 TweenLite._onPluginEvent("_onDisable", this); 8409 } 8410 this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null; 8411 this._notifyPluginsOfEnabled = this._active = this._lazy = false;
8412 this._propLookup = (this._targets) ? {} : []; 8413 Animation.prototype.invalidate.call(this); 8414 if (this.vars.immediateRender) { 8415 this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render) 8416 this.render(Math.min(0, -this._delay)); //in case delay is negative. 8417 } 8418 return this; 8419 }; 8420 8421 p._enabled = function(enabled, ignoreTimeline) { 8422 if (!_tickerActive) { 8423 _ticker.wake(); 8424 } 8425 if (enabled && this._gc) { 8426 var targets = this._targets, 8427 i; 8428 if (targets) { 8429 i = targets.length; 8430 while (--i > -1) { 8431 this._siblings[i] = _register(targets[i], this, true); 8432 } 8433 } else { 8434 this._siblings = _register(this.target, this, true); 8435 } 8436 } 8437 Animation.prototype._enabled.call(this, enabled, ignoreTimeline); 8438 if (this._notifyPluginsOfEnabled) if (this._firstPT) { 8439 return TweenLite._onPluginEvent((enabled ? "_onEnable" : "_onDisable"), this); 8440 } 8441 return false; 8442 }; 8443 8444 8445//----TweenLite static methods ----------------------------------------------------- 8446 8447 TweenLite.to = function(target, duration, vars) { 8448 return new TweenLite(target, duration, vars); 8449 }; 8450 8451 TweenLite.from = function(target, duration, vars) { 8452 vars.runBackwards = true; 8453 vars.immediateRender = (vars.immediateRender != false); 8454 return new TweenLite(target, duration, vars); 8455 }; 8456 8457 TweenLite.fromTo = function(target, duration, fromVars, toVars) { 8458 toVars.startAt = fromVars; 8459 toVars.immediateRender = (toVars.immediateRender != false && fromVars.immediateRender != false); 8460 return new TweenLite(target, duration, toVars); 8461 }; 8462 8463 TweenLite.delayedCall = function(delay, callback, params, scope, useFrames) { 8464 return new TweenLite(callback, 0, {delay:delay, onComplete:callback, onCompleteParams:params, callbackScope:scope, onReverseComplete:callback, onReverseCompleteParams:params, immediateRender:false, lazy:false, useFrames:useFrames, overwrite:0}); 8465 }; 8466 8467 TweenLite.set = function(target, vars) { 8468 return new TweenLite(target, 0, vars); 8469 }; 8470 8471 TweenLite.getTweensOf = function(target, onlyActive) { 8472 if (target == null) { return []; } 8473 target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target; 8474 var i, a, j, t; 8475 if ((_isArray(target) || _isSelector(target)) && typeof(target[0]) !== "number") { 8476 i = target.length; 8477 a = []; 8478 while (--i > -1) { 8479 a = a.concat(TweenLite.getTweensOf(target[i], onlyActive)); 8480 } 8481 i = a.length; 8482 //now get rid of any duplicates (tweens of arrays of objects could cause duplicates) 8483 while (--i > -1) { 8484 t = a[i]; 8485 j = i; 8486 while (--j > -1) { 8487 if (t === a[j]) { 8488 a.splice(i, 1); 8489 } 8490 } 8491 } 8492 } else if (target._gsTweenID) { 8493 a = _register(target).concat(); 8494 i = a.length; 8495 while (--i > -1) { 8496 if (a[i]._gc || (onlyActive && !a[i].isActive())) { 8497 a.splice(i, 1); 8498 } 8499 } 8500 } 8501 return a || []; 8502 }; 8503 8504 TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function(target, onlyActive, vars) { 8505 if (typeof(onlyActive) === "object") { 8506 vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted) 8507 onlyActive = false; 8508 } 8509 var a = TweenLite.getTweensOf(target, onlyActive), 8510 i = a.length; 8511 while (--i > -1) { 8512 a[i]._kill(vars, target); 8513 } 8514 }; 8515 8516 8517 8518/* 8519 * ---------------------------------------------------------------- 8520 * TweenPlugin (could easily be split out as a separate file/class, but included for ease of use (so that people don't need to include another script call before loading plugins which is easy to forget) 8521 * ---------------------------------------------------------------- 8522 */ 8523 var TweenPlugin = _class("plugins.TweenPlugin", function(props, priority) { 8524 this._overwriteProps = (props || "").split(","); 8525 this._propName = this._overwriteProps[0]; 8526 this._priority = priority || 0; 8527 this._super = TweenPlugin.prototype; 8528 }, true); 8529 8530 p = TweenPlugin.prototype; 8531 TweenPlugin.version = "1.19.0"; 8532 TweenPlugin.API = 2; 8533 p._firstPT = null; 8534 p._addTween = _addPropTween; 8535 p.setRatio = _setRatio; 8536 8537 p._kill = function(lookup) { 8538 var a = this._overwriteProps, 8539 pt = this._firstPT, 8540 i; 8541 if (lookup[this._propName] != null) { 8542 this._overwriteProps = []; 8543 } else { 8544 i = a.length; 8545 while (--i > -1) { 8546 if (lookup[a[i]] != null) { 8547 a.splice(i, 1); 8548 } 8549 } 8550 } 8551 while (pt) { 8552 if (lookup[pt.n] != null) { 8553 if (pt._next) { 8554 pt._next._prev = pt._prev; 8555 } 8556 if (pt._prev) { 8557 pt._prev._next = pt._next; 8558 pt._prev = null; 8559 } else if (this._firstPT === pt) { 8560 this._firstPT = pt._next; 8561 } 8562 } 8563 pt = pt._next; 8564 } 8565 return false;
8566 }; 8567 8568 p._mod = p._roundProps = function(lookup) { 8569 var pt = this._firstPT, 8570 val; 8571 while (pt) { 8572 val = lookup[this._propName] || (pt.n != null && lookup[ pt.n.split(this._propName + "_").join("") ]); 8573 if (val && typeof(val) === "function") { //some properties that are very plugin-specific add a prefix named after the _propName plus an underscore, so we need to ignore that extra stuff here. 8574 if (pt.f === 2) { 8575 pt.t._applyPT.m = val; 8576 } else { 8577 pt.m = val; 8578 } 8579 } 8580 pt = pt._next; 8581 } 8582 }; 8583 8584 TweenLite._onPluginEvent = function(type, tween) { 8585 var pt = tween._firstPT, 8586 changed, pt2, first, last, next; 8587 if (type === "_onInitAllProps") { 8588 //sorts the PropTween linked list in order of priority because some plugins need to render earlier/later than others, like MotionBlurPlugin applies its effects after all x/y/alpha tweens have rendered on each frame. 8589 while (pt) { 8590 next = pt._next; 8591 pt2 = first; 8592 while (pt2 && pt2.pr > pt.pr) { 8593 pt2 = pt2._next; 8594 } 8595 if ((pt._prev = pt2 ? pt2._prev : last)) { 8596 pt._prev._next = pt; 8597 } else { 8598 first = pt; 8599 } 8600 if ((pt._next = pt2)) { 8601 pt2._prev = pt; 8602 } else { 8603 last = pt; 8604 } 8605 pt = next; 8606 } 8607 pt = tween._firstPT = first; 8608 } 8609 while (pt) { 8610 if (pt.pg) if (typeof(pt.t[type]) === "function") if (pt.t[type]()) { 8611 changed = true; 8612 } 8613 pt = pt._next; 8614 } 8615 return changed; 8616 }; 8617 8618 TweenPlugin.activate = function(plugins) { 8619 var i = plugins.length; 8620 while (--i > -1) { 8621 if (plugins[i].API === TweenPlugin.API) { 8622 _plugins[(new plugins[i]())._propName] = plugins[i]; 8623 } 8624 } 8625 return true; 8626 }; 8627 8628 //provides a more concise way to define plugins that have no dependencies besides TweenPlugin and TweenLite, wrapping common boilerplate stuff into one function (added in 1.9.0). You don't NEED to use this to define a plugin - the old way still works and can be useful in certain (rare) situations. 8629 _gsDefine.plugin = function(config) { 8630 if (!config || !config.propName || !config.init || !config.API) { throw "illegal plugin definition."; } 8631 var propName = config.propName, 8632 priority = config.priority || 0, 8633 overwriteProps = config.overwriteProps, 8634 map = {init:"_onInitTween", set:"setRatio", kill:"_kill", round:"_mod", mod:"_mod", initAll:"_onInitAllProps"}, 8635 Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin", 8636 function() { 8637 TweenPlugin.call(this, propName, priority); 8638 this._overwriteProps = overwriteProps || []; 8639 }, (config.global === true)), 8640 p = Plugin.prototype = new TweenPlugin(propName), 8641 prop; 8642 p.constructor = Plugin; 8643 Plugin.API = config.API; 8644 for (prop in map) { 8645 if (typeof(config[prop]) === "function") { 8646 p[map[prop]] = config[prop]; 8647 } 8648 } 8649 Plugin.version = config.version; 8650 TweenPlugin.activate([Plugin]); 8651 return Plugin; 8652 }; 8653 8654 8655 //now run through all the dependencies discovered and if any are missing, log that to the console as a warning. This is why it's best to have TweenLite load last - it can check all the dependencies for you. 8656 a = window._gsQueue; 8657 if (a) { 8658 for (i = 0; i < a.length; i++) { 8659 a[i](); 8660 } 8661 for (p in _defLookup) { 8662 if (!_defLookup[p].func) { 8663 window.console.log("GSAP encountered missing dependency: " + p); 8664 } 8665 } 8666 } 8667 8668 _tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated 8669 8670})((typeof(module) !== "undefined" && module.exports && typeof(global) !== "undefined") ? global : this || window, "TweenMax"); 8671}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 8672},{}],5:[function(require,module,exports){ 8673/*! 8674 * jQuery JavaScript Library v3.3.1 8675 * https://jquery.com/ 8676 * 8677 * Includes Sizzle.js 8678 * https://sizzlejs.com/ 8679 * 8680 * Copyright JS Foundation and other contributors 8681 * Released under the MIT license 8682 * https://jquery.org/license 8683 * 8684 * Date: 2018-01-20T17:24Z 8685 */ 8686( function( global, factory ) { 8687 8688 "use strict"; 8689 8690 if ( typeof module === "object" && typeof module.exports === "object" ) { 8691 8692 // For CommonJS and CommonJS-like environments where a proper `window` 8693 // is present, execute the factory and get jQuery. 8694 // For environments that do not have a `window` with a `document` 8695 // (such as Node.js), expose a factory as module.exports. 8696 // This accentuates the need for the creation of a real `window`. 8697 // e.g. var jQuery = require("jquery")(window); 8698 // See ticket #14549 for more info. 8699 module.exports = global.document ? 8700 factory( global, true ) : 8701 function( w ) { 8702 if ( !w.document ) { 8703 throw new Error( "jQuery requires a window with a document" ); 8704 } 8705 return factory( w ); 8706 }; 8707 } else { 8708 factory( global ); 8709 } 8710 8711// Pass this if window is not defined yet 8712} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 8713 8714// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 8715// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 8716// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), str
vendor: 33,472 bytes, lines 8716-9961
8716ict mode should be common 8717// enough that all such attempts are guarded in a try block. 8718"use strict"; 8719 8720var arr = []; 8721 8722var document = window.document; 8723 8724var getProto = Object.getPrototypeOf; 8725 8726var slice = arr.slice; 8727 8728var concat = arr.concat; 8729 8730var push = arr.push; 8731 8732var indexOf = arr.indexOf; 8733 8734var class2type = {}; 8735 8736var toString = class2type.toString; 8737 8738var hasOwn = class2type.hasOwnProperty; 8739 8740var fnToString = hasOwn.toString; 8741 8742var ObjectFunctionString = fnToString.call( Object ); 8743 8744var support = {}; 8745 8746var isFunction = function isFunction( obj ) { 8747 8748 // Support: Chrome <=57, Firefox <=52 8749 // In some browsers, typeof returns "function" for HTML <object> elements 8750 // (i.e., `typeof document.createElement( "object" ) === "function"`). 8751 // We don't want to classify *any* DOM node as a function. 8752 return typeof obj === "function" && typeof obj.nodeType !== "number"; 8753 }; 8754 8755 8756var isWindow = function isWindow( obj ) { 8757 return obj != null && obj === obj.window; 8758 }; 8759 8760 8761 8762 8763 var preservedScriptAttributes = { 8764 type: true, 8765 src: true, 8766 noModule: true 8767 }; 8768 8769 function DOMEval( code, doc, node ) { 8770 doc = doc || document; 8771 8772 var i, 8773 script = doc.createElement( "script" ); 8774 8775 script.text = code; 8776 if ( node ) { 8777 for ( i in preservedScriptAttributes ) { 8778 if ( node[ i ] ) { 8779 script[ i ] = node[ i ]; 8780 } 8781 } 8782 } 8783 doc.head.appendChild( script ).parentNode.removeChild( script ); 8784 } 8785 8786 8787function toType( obj ) { 8788 if ( obj == null ) { 8789 return obj + ""; 8790 } 8791 8792 // Support: Android <=2.3 only (functionish RegExp) 8793 return typeof obj === "object" || typeof obj === "function" ? 8794 class2type[ toString.call( obj ) ] || "object" : 8795 typeof obj; 8796} 8797/* global Symbol */ 8798// Defining this global in .eslintrc.json would create a danger of using the global 8799// unguarded in another place, it seems safer to define global only for this module 8800 8801 8802 8803var 8804 version = "3.3.1", 8805 8806 // Define a local copy of jQuery 8807 jQuery = function( selector, context ) { 8808 8809 // The jQuery object is actually just the init constructor 'enhanced' 8810 // Need init if jQuery is called (just allow error to be thrown if not included) 8811 return new jQuery.fn.init( selector, context ); 8812 }, 8813 8814 // Support: Android <=4.0 only 8815 // Make sure we trim BOM and NBSP 8816 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 8817 8818jQuery.fn = jQuery.prototype = { 8819 8820 // The current version of jQuery being used 8821 jquery: version, 8822 8823 constructor: jQuery, 8824 8825 // The default length of a jQuery object is 0 8826 length: 0, 8827 8828 toArray: function() { 8829 return slice.call( this ); 8830 }, 8831 8832 // Get the Nth element in the matched element set OR 8833 // Get the whole matched element set as a clean array 8834 get: function( num ) { 8835 8836 // Return all the elements in a clean array 8837 if ( num == null ) { 8838 return slice.call( this ); 8839 } 8840 8841 // Return just the one element from the set 8842 return num < 0 ? this[ num + this.length ] : this[ num ]; 8843 }, 8844 8845 // Take an array of elements and push it onto the stack 8846 // (returning the new matched element set) 8847 pushStack: function( elems ) { 8848 8849 // Build a new jQuery matched element set 8850 var ret = jQuery.merge( this.constructor(), elems ); 8851 8852 // Add the old object onto the stack (as a reference) 8853 ret.prevObject = this; 8854 8855 // Return the newly-formed element set 8856 return ret; 8857 }, 8858 8859 // Execute a callback for every element in the matched set. 8860 each: function( callback ) { 8861 return jQuery.each( this, callback ); 8862 }, 8863 8864 map: function( callback ) { 8865 return this.pushStack( jQuery.map( this, function( elem, i ) { 8866 return callback.call( elem, i, elem ); 8867 } ) ); 8868 }, 8869 8870 slice: function() { 8871 return this.pushStack( slice.apply( this, arguments ) ); 8872 }, 8873 8874 first: function() { 8875 return this.eq( 0 ); 8876 }, 8877 8878 last: function() { 8879 return this.eq( -1 ); 8880 }, 8881 8882 eq: function( i ) { 8883 var len = this.length, 8884 j = +i + ( i < 0 ? len : 0 ); 8885 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 8886 }, 8887 8888 end: function() { 8889 return this.prevObject || this.constructor(); 8890 }, 8891 8892 // For internal use only. 8893 // Behaves like an Array's method, not like a jQuery method. 8894 push: push, 8895 sort: arr.sort, 8896 splice: arr.splice 8897}; 8898 8899jQuery.extend = jQuery.fn.extend = function() { 8900 var options, name, src, copy, copyIsArray, clone, 8901 target = arguments[ 0 ] || {}, 8902 i = 1, 8903 length = arguments.length, 8904 deep = false; 8905 8906 // Handle a deep copy situation 8907 if ( typeof target === "boolean" ) { 8908 deep = target; 8909 8910 // Skip the boolean and the target 8911 target = arguments[ i ] || {}; 8912 i++; 8913 } 8914 8915 // Handle case when target is a string or something (possible in deep copy) 8916 if ( typeof target !== "object" && !isFunction( target ) ) { 8917 target = {}; 8918 } 8919 8920 // Extend jQuery itself if only one argument is passed 8921 if ( i === length ) { 8922 target = this; 8923 i--; 8924 } 8925 8926 for ( ; i < length; i++ ) { 8927 8928 // Only deal with non-null/undefined values 8929 if ( ( options = arguments[ i ] ) != null ) { 8930 8931 // Extend the base object 8932 for ( name in options ) { 8933 src = target[ name ]; 8934 copy = options[ name ]; 8935 8936 // Prevent never-ending loop 8937 if ( target === copy ) { 8938 continue; 8939 } 8940 8941 // Recurse if we're merging plain objects or arrays 8942 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 8943 ( copyIsArray = Array.isArray( copy ) ) ) ) { 8944 8945 if ( copyIsArray ) { 8946 copyIsArray = false; 8947 clone = src && Array.isArray( src ) ? src : []; 8948 8949 } else { 8950 clone = src && jQuery.isPlainObject( src ) ? src : {}; 8951 } 8952 8953 // Never move original objects, clone them 8954 target[ name ] = jQuery.extend( deep, clone, copy ); 8955 8956 // Don't bring in undefined values 8957 } else if ( copy !== undefined ) { 8958 target[ name ] = copy; 8959 } 8960 } 8961 } 8962 } 8963 8964 // Return the modified object 8965 return target; 8966}; 8967 8968jQuery.extend( { 8969 8970 // Unique for each copy of jQuery on the page 8971 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 8972 8973 // Assume jQuery is ready without the ready module 8974 isReady: true, 8975 8976 error: function( msg ) { 8977 throw new Error( msg ); 8978 }, 8979 8980 noop: function() {}, 8981 8982 isPlainObject: function( obj ) { 8983 var proto, Ctor; 8984 8985 // Detect obvious negatives 8986 // Use toString instead of jQuery.type to catch host objects 8987 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 8988 return false; 8989 } 8990 8991 proto = getProto( obj ); 8992 8993 // Objects with no prototype (e.g., `Object.create( null )`) are plain 8994 if ( !proto ) { 8995 return true; 8996 } 8997 8998 // Objects with prototype are plain iff they were constructed by a global Object function 8999 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 9000 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 9001 }, 9002 9003 isEmptyObject: function( obj ) { 9004 9005 /* eslint-disable no-unused-vars */ 9006 // See https://github.com/eslint/eslint/issues/6125 9007 var name; 9008 9009 for ( name in obj ) { 9010 return false; 9011 } 9012 return true; 9013 }, 9014 9015 // Evaluates a script in a global context 9016 globalEval: function( code ) { 9017 DOMEval( code ); 9018 }, 9019 9020 each: function( obj, callback ) { 9021 var length, i = 0; 9022 9023 if ( isArrayLike( obj ) ) { 9024 length = obj.length; 9025 for ( ; i < length; i++ ) { 9026 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 9027 break; 9028 } 9029 } 9030 } else { 9031 for ( i in obj ) { 9032 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 9033 break; 9034 } 9035 } 9036 } 9037 9038 return obj; 9039 }, 9040 9041 // Support: Android <=4.0 only 9042 trim: function( text ) { 9043 return text == null ? 9044 "" : 9045 ( text + "" ).replace( rtrim, "" ); 9046 }, 9047 9048 // results is for internal usage only 9049 makeArray: function( arr, results ) { 9050 var ret = results || []; 9051 9052 if ( arr != null ) { 9053 if ( isArrayLike( Object( arr ) ) ) { 9054 jQuery.merge( ret, 9055 typeof arr === "string" ? 9056 [ arr ] : arr 9057 ); 9058 } else { 9059 push.call( ret, arr ); 9060 } 9061 } 9062 9063 return ret; 9064 }, 9065 9066 inArray: function( elem, arr, i ) { 9067 return arr == null ? -1 : indexOf.call( arr, elem, i ); 9068 }, 9069 9070 // Support: Android <=4.0 only, PhantomJS 1 only 9071 // push.apply(_, arraylike) throws on ancient WebKit 9072 merge: function( first, second ) { 9073 var len = +second.length, 9074 j = 0, 9075 i = first.length; 9076 9077 for ( ; j < len; j++ ) { 9078 first[ i++ ] = second[ j ]; 9079 } 9080 9081 first.length = i; 9082 9083 return first; 9084 }, 9085 9086 grep: function( elems, callback, invert ) { 9087 var callbackInverse, 9088 matches = [], 9089 i = 0, 9090 length = elems.length, 9091 callbackExpect = !invert; 9092 9093 // Go through the array, only saving the items 9094 // that pass the validator function 9095 for ( ; i < length; i++ ) { 9096 callbackInverse = !callback( elems[ i ], i ); 9097 if ( callbackInverse !== callbackExpect ) { 9098 matches.push( elems[ i ] ); 9099 } 9100 } 9101 9102 return matches; 9103 }, 9104 9105 // arg is for internal usage only 9106 map: function( elems, callback, arg ) { 9107 var length, value, 9108 i = 0, 9109 ret = []; 9110 9111 // Go through the array, translating each of the items to their new values 9112 if ( isArrayLike( elems ) ) { 9113 length = elems.length; 9114 for ( ; i < length; i++ ) { 9115 value = callback( elems[ i ], i, arg ); 9116 9117 if ( value != null ) { 9118 ret.push( value ); 9119 } 9120 } 9121 9122 // Go through every key on the object, 9123 } else { 9124 for ( i in elems ) { 9125 value = callback( elems[ i ], i, arg ); 9126 9127 if ( value != null ) { 9128 ret.push( value ); 9129 } 9130 } 9131 } 9132 9133 // Flatten any nested arrays 9134 return concat.apply( [], ret ); 9135 }, 9136 9137 // A global GUID counter for objects 9138 guid: 1, 9139 9140 // jQuery.support is not used in Core but other projects attach their 9141 // properties to it so it needs to exist. 9142 support: support 9143} ); 9144 9145if ( typeof Symbol === "function" ) { 9146 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 9147} 9148 9149// Populate the class2type map 9150jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 9151function( i, name ) { 9152 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 9153} ); 9154 9155function isArrayLike( obj ) { 9156 9157 // Support: real iOS 8.2 only (not reproducible in simulator) 9158 // `in` check used to prevent JIT error (gh-2145) 9159 // hasOwn isn't used here due to false negatives 9160 // regarding Nodelist length in IE 9161 var length = !!obj && "length" in obj && obj.length, 9162 type = toType( obj ); 9163 9164 if ( isFunction( obj ) || isWindow( obj ) ) { 9165 return false; 9166 } 9167 9168 return type === "array" || length === 0 || 9169 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 9170} 9171var Sizzle = 9172/*! 9173 * Sizzle CSS Selector Engine v2.3.3 9174 * https://sizzlejs.com/ 9175 * 9176 * Copyright jQuery Foundation and other contributors 9177 * Released under the MIT license 9178 * http://jquery.org/license 9179 * 9180 * Date: 2016-08-08 9181 */ 9182(function( window ) { 9183 9184var i, 9185 support, 9186 Expr, 9187 getText, 9188 isXML, 9189 tokenize, 9190 compile, 9191 select, 9192 outermostContext, 9193 sortInput, 9194 hasDuplicate, 9195 9196 // Local document vars 9197 setDocument, 9198 document, 9199 docElem, 9200 documentIsHTML, 9201 rbuggyQSA, 9202 rbuggyMatches, 9203 matches, 9204 contains, 9205 9206 // Instance-specific data 9207 expando = "sizzle" + 1 * new Date(), 9208 preferredDoc = window.document, 9209 dirruns = 0, 9210 done = 0, 9211 classCache = createCache(), 9212 tokenCache = createCache(), 9213 compilerCache = createCache(), 9214 sortOrder = function( a, b ) { 9215 if ( a === b ) { 9216 hasDuplicate = true; 9217 } 9218 return 0; 9219 }, 9220 9221 // Instance methods 9222 hasOwn = ({}).hasOwnProperty, 9223 arr = [], 9224 pop = arr.pop, 9225 push_native = arr.push, 9226 push = arr.push, 9227 slice = arr.slice, 9228 // Use a stripped-down indexOf as it's faster than native 9229 // https://jsperf.com/thor-indexof-vs-for/5 9230 indexOf = function( list, elem ) { 9231 var i = 0, 9232 len = list.length; 9233 for ( ; i < len; i++ ) { 9234 if ( list[i] === elem ) { 9235 return i; 9236 } 9237 } 9238 return -1; 9239 }, 9240 9241 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", 9242 9243 // Regular expressions 9244 9245 // http://www.w3.org/TR/css3-selectors/#whitespace 9246 whitespace = "[\\x20\\t\\r\\n\\f]", 9247 9248 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 9249 identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", 9250 9251 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 9252 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 9253 // Operator (capture 2) 9254 "*([*^$|!~]?=)" + whitespace + 9255 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 9256 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + 9257 "*\\]", 9258 9259 pseudos = ":(" + identifier + ")(?:\\((" + 9260 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 9261 // 1. quoted (capture 3; capture 4 or capture 5) 9262 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 9263 // 2. simple (capture 6) 9264 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 9265 // 3. anything else (capture 2) 9266 ".*" + 9267 ")\\)|)", 9268 9269 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 9270 rwhitespace = new RegExp( whitespace + "+", "g" ), 9271 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 9272 9273 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 9274 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), 9275 9276 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), 9277 9278 rpseudo = new RegExp( pseudos ), 9279 ridentifier = new RegExp( "^" + identifier + "$" ), 9280 9281 matchExpr = { 9282 "ID": new RegExp( "^#(" + identifier + ")" ), 9283 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 9284 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 9285 "ATTR": new RegExp( "^" + attributes ), 9286 "PSEUDO": new RegExp( "^" + pseudos ), 9287 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + 9288 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 9289 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 9290 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 9291 // For use in libraries implementing .is() 9292 // We use this for POS matching in `select` 9293 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + 9294 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 9295 }, 9296 9297 rinputs = /^(?:input|select|textarea|button)$/i, 9298 rheader = /^h\d$/i, 9299 9300 rnative = /^[^{]+\{\s*\[native \w/, 9301 9302 // Easily-parseable/retrievable ID or TAG or CLASS selectors 9303 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 9304 9305 rsibling = /[+~]/, 9306 9307 // CSS escapes 9308 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 9309 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), 9310 funescape = function( _, escaped, escapedWhitespace ) { 9311 var high = "0x" + escaped - 0x10000; 9312 // NaN means non-codepoint 9313 // Support: Firefox<24 9314 // Workaround erroneous numeric interpretation of +"0x" 9315 return high !== high || escapedWhitespace ? 9316 escaped : 9317 high < 0 ? 9318 // BMP codepoint 9319 String.fromCharCode( high + 0x10000 ) : 9320 // Supplemental Plane codepoint (surrogate pair) 9321 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 9322 }, 9323 9324 // CSS string/identifier serialization 9325 // https://drafts.csswg.org/cssom/#common-serializing-idioms 9326 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, 9327 fcssescape = function( ch, asCodePoint ) { 9328 if ( asCodePoint ) { 9329 9330 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 9331 if ( ch === "\0" ) { 9332 return "\uFFFD"; 9333 } 9334 9335 // Control characters and (dependent upon position) numbers get escaped as code points 9336 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 9337 } 9338 9339 // Other potentially-special ASCII characters get backslash-escaped 9340 return "\\" + ch; 9341 }, 9342 9343 // Used for iframes 9344 // See setDocument() 9345 // Removing the function wrapper causes a "Permission Denied" 9346 // error in IE 9347 unloadHandler = function() { 9348 setDocument(); 9349 }, 9350 9351 disabledAncestor = addCombinator( 9352 function( elem ) { 9353 return elem.disabled === true && ("form" in elem || "label" in elem); 9354 }, 9355 { dir: "parentNode", next: "legend" } 9356 ); 9357 9358// Optimize for push.apply( _, NodeList ) 9359try { 9360 push.apply( 9361 (arr = slice.call( preferredDoc.childNodes )), 9362 preferredDoc.childNodes 9363 ); 9364 // Support: Android<4.0 9365 // Detect silently failing push.apply 9366 arr[ preferredDoc.childNodes.length ].nodeType; 9367} catch ( e ) { 9368 push = { apply: arr.length ? 9369 9370 // Leverage slice if possible 9371 function( target, els ) { 9372 push_native.apply( target, slice.call(els) ); 9373 } : 9374 9375 // Support: IE<9 9376 // Otherwise append directly 9377 function( target, els ) { 9378 var j = target.length, 9379 i = 0; 9380 // Can't trust NodeList.length 9381 while ( (target[j++] = els[i++]) ) {} 9382 target.length = j - 1; 9383 } 9384 }; 9385} 9386 9387function Sizzle( selector, context, results, seed ) { 9388 var m, i, elem, nid, match, groups, newSelector, 9389 newContext = context && context.ownerDocument, 9390 9391 // nodeType defaults to 9, since context defaults to document 9392 nodeType = context ? context.nodeType : 9; 9393 9394 results = results || []; 9395 9396 // Return early from calls with invalid selector or context 9397 if ( typeof selector !== "string" || !selector || 9398 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 9399 9400 return results; 9401 } 9402 9403 // Try to shortcut find operations (as opposed to filters) in HTML documents 9404 if ( !seed ) { 9405 9406 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { 9407 setDocument( context ); 9408 } 9409 context = context || document; 9410 9411 if ( documentIsHTML ) { 9412 9413 // If the selector is sufficiently simple, try using a "get*By*" DOM method 9414 // (excepting DocumentFragment context, where the methods don't exist) 9415 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { 9416 9417 // ID selector 9418 if ( (m = match[1]) ) { 9419 9420 // Document context 9421 if ( nodeType === 9 ) { 9422 if ( (elem = context.getElementById( m )) ) { 9423 9424 // Support: IE, Opera, Webkit 9425 // TODO: identify versions 9426 // getElementById can match elements by name instead of ID 9427 if ( elem.id === m ) { 9428 results.push( elem ); 9429 return results; 9430 } 9431 } else { 9432 return results; 9433 } 9434 9435 // Element context 9436 } else { 9437 9438 // Support: IE, Opera, Webkit 9439 // TODO: identify versions 9440 // getElementById can match elements by name instead of ID 9441 if ( newContext && (elem = newContext.getElementById( m )) && 9442 contains( context, elem ) && 9443 elem.id === m ) { 9444 9445 results.push( elem ); 9446 return results; 9447 } 9448 } 9449 9450 // Type selector 9451 } else if ( match[2] ) { 9452 push.apply( results, context.getElementsByTagName( selector ) ); 9453 return results; 9454 9455 // Class selector 9456 } else if ( (m = match[3]) && support.getElementsByClassName && 9457 context.getElementsByClassName ) { 9458 9459 push.apply( results, context.getElementsByClassName( m ) ); 9460 return results; 9461 } 9462 } 9463 9464 // Take advantage of querySelectorAll 9465 if ( support.qsa && 9466 !compilerCache[ selector + " " ] && 9467 (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { 9468 9469 if ( nodeType !== 1 ) { 9470 newContext = context; 9471 newSelector = selector; 9472 9473 // qSA looks outside Element context, which is not what we want 9474 // Thanks to Andrew Dupont for this workaround technique 9475 // Support: IE <=8 9476 // Exclude object elements 9477 } else if ( context.nodeName.toLowerCase() !== "object" ) { 9478 9479 // Capture the context ID, setting it first if necessary 9480 if ( (nid = context.getAttribute( "id" )) ) { 9481 nid = nid.replace( rcssescape, fcssescape ); 9482 } else { 9483 context.setAttribute( "id", (nid = expando) ); 9484 } 9485 9486 // Prefix every selector in the list 9487 groups = tokenize( selector ); 9488 i = groups.length; 9489 while ( i-- ) { 9490 groups[i] = "#" + nid + " " + toSelector( groups[i] ); 9491 } 9492 newSelector = groups.join( "," ); 9493 9494 // Expand context for sibling selectors 9495 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 9496 context; 9497 } 9498 9499 if ( newSelector ) { 9500 try { 9501 push.apply( results, 9502 newContext.querySelectorAll( newSelector ) 9503 ); 9504 return results; 9505 } catch ( qsaError ) { 9506 } finally { 9507 if ( nid === expando ) { 9508 context.removeAttribute( "id" ); 9509 } 9510 } 9511 } 9512 } 9513 } 9514 } 9515 9516 // All others 9517 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 9518} 9519 9520/** 9521 * Create key-value caches of limited size 9522 * @returns {function(string, object)} Returns the Object data after storing it on itself with 9523 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 9524 * deleting the oldest entry 9525 */ 9526function createCache() { 9527 var keys = []; 9528 9529 function cache( key, value ) { 9530 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 9531 if ( keys.push( key + " " ) > Expr.cacheLength ) { 9532 // Only keep the most recent entries 9533 delete cache[ keys.shift() ]; 9534 } 9535 return (cache[ key + " " ] = value); 9536 } 9537 return cache; 9538} 9539 9540/** 9541 * Mark a function for special use by Sizzle 9542 * @param {Function} fn The function to mark 9543 */ 9544function markFunction( fn ) { 9545 fn[ expando ] = true; 9546 return fn; 9547} 9548 9549/** 9550 * Support testing using an element 9551 * @param {Function} fn Passed the created element and returns a boolean result 9552 */ 9553function assert( fn ) { 9554 var el = document.createElement("fieldset"); 9555 9556 try { 9557 return !!fn( el ); 9558 } catch (e) { 9559 return false; 9560 } finally { 9561 // Remove from its parent by default 9562 if ( el.parentNode ) { 9563 el.parentNode.removeChild( el ); 9564 } 9565 // release memory in IE 9566 el = null; 9567 } 9568} 9569 9570/** 9571 * Adds the same handler for all of the specified attrs 9572 * @param {String} attrs Pipe-separated list of attributes 9573 * @param {Function} handler The method that will be applied 9574 */ 9575function addHandle( attrs, handler ) { 9576 var arr = attrs.split("|"), 9577 i = arr.length; 9578 9579 while ( i-- ) { 9580 Expr.attrHandle[ arr[i] ] = handler; 9581 } 9582} 9583 9584/** 9585 * Checks document order of two siblings 9586 * @param {Element} a 9587 * @param {Element} b 9588 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 9589 */ 9590function siblingCheck( a, b ) { 9591 var cur = b && a, 9592 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 9593 a.sourceIndex - b.sourceIndex; 9594 9595 // Use IE sourceIndex if available on both nodes 9596 if ( diff ) { 9597 return diff; 9598 } 9599 9600 // Check if b follows a 9601 if ( cur ) { 9602 while ( (cur = cur.nextSibling) ) { 9603 if ( cur === b ) { 9604 return -1; 9605 } 9606 } 9607 } 9608 9609 return a ? 1 : -1; 9610} 9611 9612/** 9613 * Returns a function to use in pseudos for input types 9614 * @param {String} type 9615 */ 9616function createInputPseudo( type ) { 9617 return function( elem ) { 9618 var name = elem.nodeName.toLowerCase(); 9619 return name === "input" && elem.type === type; 9620 }; 9621} 9622 9623/** 9624 * Returns a function to use in pseudos for buttons 9625 * @param {String} type 9626 */ 9627function createButtonPseudo( type ) { 9628 return function( elem ) { 9629 var name = elem.nodeName.toLowerCase(); 9630 return (name === "input" || name === "button") && elem.type === type; 9631 }; 9632} 9633 9634/** 9635 * Returns a function to use in pseudos for :enabled/:disabled 9636 * @param {Boolean} disabled true for :disabled; false for :enabled 9637 */ 9638function createDisabledPseudo( disabled ) { 9639 9640 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 9641 return function( elem ) { 9642 9643 // Only certain elements can match :enabled or :disabled 9644 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 9645 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 9646 if ( "form" in elem ) { 9647 9648 // Check for inherited disabledness on relevant non-disabled elements: 9649 // * listed form-associated elements in a disabled fieldset 9650 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 9651 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 9652 // * option elements in a disabled optgroup 9653 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 9654 // All such elements have a "form" property. 9655 if ( elem.parentNode && elem.disabled === false ) { 9656 9657 // Option elements defer to a parent optgroup if present 9658 if ( "label" in elem ) { 9659 if ( "label" in elem.parentNode ) { 9660 return elem.parentNode.disabled === disabled; 9661 } else { 9662 return elem.disabled === disabled; 9663 } 9664 } 9665 9666 // Support: IE 6 - 11 9667 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 9668 return elem.isDisabled === disabled || 9669 9670 // Where there is no isDisabled, check manually 9671 /* jshint -W018 */ 9672 elem.isDisabled !== !disabled && 9673 disabledAncestor( elem ) === disabled; 9674 } 9675 9676 return elem.disabled === disabled; 9677 9678 // Try to winnow out elements that can't be disabled before trusting the disabled property. 9679 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 9680 // even exist on them, let alone have a boolean value. 9681 } else if ( "label" in elem ) { 9682 return elem.disabled === disabled; 9683 } 9684 9685 // Remaining elements are neither :enabled nor :disabled 9686 return false; 9687 }; 9688} 9689 9690/** 9691 * Returns a function to use in pseudos for positionals 9692 * @param {Function} fn 9693 */ 9694function createPositionalPseudo( fn ) { 9695 return markFunction(function( argument ) { 9696 argument = +argument; 9697 return markFunction(function( seed, matches ) { 9698 var j, 9699 matchIndexes = fn( [], seed.length, argument ), 9700 i = matchIndexes.length; 9701 9702 // Match elements found at the specified indexes 9703 while ( i-- ) { 9704 if ( seed[ (j = matchIndexes[i]) ] ) { 9705 seed[j] = !(matches[j] = seed[j]); 9706 } 9707 } 9708 }); 9709 }); 9710} 9711 9712/** 9713 * Checks a node for validity as a Sizzle context 9714 * @param {Element|Object=} context 9715 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 9716 */ 9717function testContext( context ) { 9718 return context && typeof context.getElementsByTagName !== "undefined" && context; 9719} 9720 9721// Expose support vars for convenience 9722support = Sizzle.support = {}; 9723 9724/** 9725 * Detects XML nodes 9726 * @param {Element|Object} elem An element or a document 9727 * @returns {Boolean} True iff elem is a non-HTML XML node 9728 */ 9729isXML = Sizzle.isXML = function( elem ) { 9730 // documentElement is verified for cases where it doesn't yet exist 9731 // (such as loading iframes in IE - #4833) 9732 var documentElement = elem && (elem.ownerDocument || elem).documentElement; 9733 return documentElement ? documentElement.nodeName !== "HTML" : false; 9734}; 9735 9736/** 9737 * Sets document-related variables once based on the current document 9738 * @param {Element|Object} [doc] An element or document object to use to set the document 9739 * @returns {Object} Returns the current document 9740 */ 9741setDocument = Sizzle.setDocument = function( node ) { 9742 var hasCompare, subWindow, 9743 doc = node ? node.ownerDocument || node : preferredDoc; 9744 9745 // Return early if doc is invalid or already selected 9746 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { 9747 return document; 9748 } 9749 9750 // Update global variables 9751 document = doc; 9752 docElem = document.documentElement; 9753 documentIsHTML = !isXML( document ); 9754 9755 // Support: IE 9-11, Edge 9756 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 9757 if ( preferredDoc !== document && 9758 (subWindow = document.defaultView) && subWindow.top !== subWindow ) { 9759 9760 // Support: IE 11, Edge 9761 if ( subWindow.addEventListener ) { 9762 subWindow.addEventListener( "unload", unloadHandler, false ); 9763 9764 // Support: IE 9 - 10 only 9765 } else if ( subWindow.attachEvent ) { 9766 subWindow.attachEvent( "onunload", unloadHandler ); 9767 } 9768 } 9769 9770 /* Attributes 9771 ---------------------------------------------------------------------- */ 9772 9773 // Support: IE<8 9774 // Verify that getAttribute really returns attributes and not properties 9775 // (excepting IE8 booleans) 9776 support.attributes = assert(function( el ) { 9777 el.className = "i"; 9778 return !el.getAttribute("className"); 9779 }); 9780 9781 /* getElement(s)By* 9782 ---------------------------------------------------------------------- */ 9783 9784 // Check if getElementsByTagName("*") returns only elements 9785 support.getElementsByTagName = assert(function( el ) { 9786 el.appendChild( document.createComment("") ); 9787 return !el.getElementsByTagName("*").length; 9788 }); 9789 9790 // Support: IE<9 9791 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 9792 9793 // Support: IE<10 9794 // Check if getElementById returns elements by name 9795 // The broken getElementById methods don't pick up programmatically-set names, 9796 // so use a roundabout getElementsByName test 9797 support.getById = assert(function( el ) { 9798 docElem.appendChild( el ).id = expando; 9799 return !document.getElementsByName || !document.getElementsByName( expando ).length; 9800 }); 9801 9802 // ID filter and find 9803 if ( support.getById ) { 9804 Expr.filter["ID"] = function( id ) { 9805 var attrId = id.replace( runescape, funescape ); 9806 return function( elem ) { 9807 return elem.getAttribute("id") === attrId; 9808 }; 9809 }; 9810 Expr.find["ID"] = function( id, context ) { 9811 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 9812 var elem = context.getElementById( id ); 9813 return elem ? [ elem ] : []; 9814 } 9815 }; 9816 } else { 9817 Expr.filter["ID"] = function( id ) { 9818 var attrId = id.replace( runescape, funescape ); 9819 return function( elem ) { 9820 var node = typeof elem.getAttributeNode !== "undefined" && 9821 elem.getAttributeNode("id"); 9822 return node && node.value === attrId; 9823 }; 9824 }; 9825 9826 // Support: IE 6 - 7 only 9827 // getElementById is not reliable as a find shortcut 9828 Expr.find["ID"] = function( id, context ) { 9829 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 9830 var node, i, elems, 9831 elem = context.getElementById( id ); 9832 9833 if ( elem ) { 9834 9835 // Verify the id attribute 9836 node = elem.getAttributeNode("id"); 9837 if ( node && node.value === id ) { 9838 return [ elem ]; 9839 } 9840 9841 // Fall back on getElementsByName 9842 elems = context.getElementsByName( id ); 9843 i = 0; 9844 while ( (elem = elems[i++]) ) { 9845 node = elem.getAttributeNode("id"); 9846 if ( node && node.value === id ) { 9847 return [ elem ]; 9848 } 9849 } 9850 } 9851 9852 return []; 9853 } 9854 }; 9855 } 9856 9857 // Tag 9858 Expr.find["TAG"] = support.getElementsByTagName ? 9859 function( tag, context ) { 9860 if ( typeof context.getElementsByTagName !== "undefined" ) { 9861 return context.getElementsByTagName( tag ); 9862 9863 // DocumentFragment nodes don't have gEBTN 9864 } else if ( support.qsa ) { 9865 return context.querySelectorAll( tag ); 9866 } 9867 } : 9868 9869 function( tag, context ) { 9870 var elem, 9871 tmp = [], 9872 i = 0, 9873 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 9874 results = context.getElementsByTagName( tag ); 9875 9876 // Filter out possible comments 9877 if ( tag === "*" ) { 9878 while ( (elem = results[i++]) ) { 9879 if ( elem.nodeType === 1 ) { 9880 tmp.push( elem ); 9881 } 9882 } 9883 9884 return tmp; 9885 } 9886 return results; 9887 }; 9888 9889 // Class 9890 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { 9891 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 9892 return context.getElementsByClassName( className ); 9893 } 9894 }; 9895 9896 /* QSA/matchesSelector 9897 ---------------------------------------------------------------------- */ 9898 9899 // QSA and matchesSelector support 9900 9901 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 9902 rbuggyMatches = []; 9903 9904 // qSa(:focus) reports false when true (Chrome 21) 9905 // We allow this because of a bug in IE8/9 that throws an error 9906 // whenever `document.activeElement` is accessed on an iframe 9907 // So, we allow :focus to pass through QSA all the time to avoid the IE error 9908 // See https://bugs.jquery.com/ticket/13378 9909 rbuggyQSA = []; 9910 9911 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { 9912 // Build QSA regex 9913 // Regex strategy adopted from Diego Perini 9914 assert(function( el ) { 9915 // Select is set to empty string on purpose 9916 // This is to test IE's treatment of not explicitly 9917 // setting a boolean content attribute, 9918 // since its presence should be enough 9919 // https://bugs.jquery.com/ticket/12359 9920 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + 9921 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 9922 "<option selected=''></option></select>"; 9923 9924 // Support: IE8, Opera 11-12.16 9925 // Nothing should be selected when empty strings follow ^= or $= or *= 9926 // The test attribute must be unknown in Opera but "safe" for WinRT 9927 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 9928 if ( el.querySelectorAll("[msallowcapture^='']").length ) { 9929 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 9930 } 9931 9932 // Support: IE8 9933 // Boolean attributes and "value" are not treated correctly 9934 if ( !el.querySelectorAll("[selected]").length ) { 9935 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 9936 } 9937 9938 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 9939 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 9940 rbuggyQSA.push("~="); 9941 } 9942 9943 // Webkit/Opera - :checked should return selected option elements 9944 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 9945 // IE8 throws error here and will not see later tests 9946 if ( !el.querySelectorAll(":checked").length ) { 9947 rbuggyQSA.push(":checked"); 9948 } 9949 9950 // Support: Safari 8+, iOS 8+ 9951 // https://bugs.webkit.org/show_bug.cgi?id=136851 9952 // In-page `selector#id sibling-combinator selector` fails 9953 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 9954 rbuggyQSA.push(".#.+[+~]"); 9955 } 9956 }); 9957 9958 assert(function( el ) { 9959 el.innerHTML = "<a href='' disabled='disabled'></a>" + 9960 "<select disabled='disabled'><option/></select>"; 9961
vendor: 6,849 bytes, lines 9962-10209
9962 // Support: Windows 8 Native Apps 9963 // The type and name attributes are restricted during .innerHTML assignment 9964 var input = document.createElement("input"); 9965 input.setAttribute( "type", "hidden" ); 9966 el.appendChild( input ).setAttribute( "name", "D" ); 9967 9968 // Support: IE8 9969 // Enforce case-sensitivity of name attribute 9970 if ( el.querySelectorAll("[name=d]").length ) { 9971 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 9972 } 9973 9974 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 9975 // IE8 throws error here and will not see later tests 9976 if ( el.querySelectorAll(":enabled").length !== 2 ) { 9977 rbuggyQSA.push( ":enabled", ":disabled" ); 9978 } 9979 9980 // Support: IE9-11+ 9981 // IE's :disabled selector does not pick up the children of disabled fieldsets 9982 docElem.appendChild( el ).disabled = true; 9983 if ( el.querySelectorAll(":disabled").length !== 2 ) { 9984 rbuggyQSA.push( ":enabled", ":disabled" ); 9985 } 9986 9987 // Opera 10-11 does not throw on post-comma invalid pseudos 9988 el.querySelectorAll("*,:x"); 9989 rbuggyQSA.push(",.*:"); 9990 }); 9991 } 9992 9993 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || 9994 docElem.webkitMatchesSelector || 9995 docElem.mozMatchesSelector || 9996 docElem.oMatchesSelector || 9997 docElem.msMatchesSelector) )) ) { 9998 9999 assert(function( el ) { 10000 // Check to see if it's possible to do matchesSelector 10001 // on a disconnected node (IE 9) 10002 support.disconnectedMatch = matches.call( el, "*" ); 10003 10004 // This should fail with an exception 10005 // Gecko does not error, returns false instead 10006 matches.call( el, "[s!='']:x" ); 10007 rbuggyMatches.push( "!=", pseudos ); 10008 }); 10009 } 10010 10011 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); 10012 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); 10013 10014 /* Contains 10015 ---------------------------------------------------------------------- */ 10016 hasCompare = rnative.test( docElem.compareDocumentPosition ); 10017 10018 // Element contains another 10019 // Purposefully self-exclusive 10020 // As in, an element does not contain itself 10021 contains = hasCompare || rnative.test( docElem.contains ) ? 10022 function( a, b ) { 10023 var adown = a.nodeType === 9 ? a.documentElement : a, 10024 bup = b && b.parentNode; 10025 return a === bup || !!( bup && bup.nodeType === 1 && ( 10026 adown.contains ? 10027 adown.contains( bup ) : 10028 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 10029 )); 10030 } : 10031 function( a, b ) { 10032 if ( b ) { 10033 while ( (b = b.parentNode) ) { 10034 if ( b === a ) { 10035 return true; 10036 } 10037 } 10038 } 10039 return false; 10040 }; 10041 10042 /* Sorting 10043 ---------------------------------------------------------------------- */ 10044 10045 // Document order sorting 10046 sortOrder = hasCompare ? 10047 function( a, b ) { 10048 10049 // Flag for duplicate removal 10050 if ( a === b ) { 10051 hasDuplicate = true; 10052 return 0; 10053 } 10054 10055 // Sort on method existence if only one input has compareDocumentPosition 10056 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 10057 if ( compare ) { 10058 return compare; 10059 } 10060 10061 // Calculate position if both inputs belong to the same document 10062 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? 10063 a.compareDocumentPosition( b ) : 10064 10065 // Otherwise we know they are disconnected 10066 1; 10067 10068 // Disconnected nodes 10069 if ( compare & 1 || 10070 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { 10071 10072 // Choose the first element that is related to our preferred document 10073 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { 10074 return -1; 10075 } 10076 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { 10077 return 1; 10078 } 10079 10080 // Maintain original order 10081 return sortInput ? 10082 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 10083 0; 10084 } 10085 10086 return compare & 4 ? -1 : 1; 10087 } : 10088 function( a, b ) { 10089 // Exit early if the nodes are identical 10090 if ( a === b ) { 10091 hasDuplicate = true; 10092 return 0; 10093 } 10094 10095 var cur, 10096 i = 0, 10097 aup = a.parentNode, 10098 bup = b.parentNode, 10099 ap = [ a ], 10100 bp = [ b ]; 10101 10102 // Parentless nodes are either documents or disconnected 10103 if ( !aup || !bup ) { 10104 return a === document ? -1 : 10105 b === document ? 1 : 10106 aup ? -1 : 10107 bup ? 1 : 10108 sortInput ? 10109 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 10110 0; 10111 10112 // If the nodes are siblings, we can do a quick check 10113 } else if ( aup === bup ) { 10114 return siblingCheck( a, b ); 10115 } 10116 10117 // Otherwise we need full lists of their ancestors for comparison 10118 cur = a; 10119 while ( (cur = cur.parentNode) ) { 10120 ap.unshift( cur ); 10121 } 10122 cur = b; 10123 while ( (cur = cur.parentNode) ) { 10124 bp.unshift( cur ); 10125 } 10126 10127 // Walk down the tree looking for a discrepancy 10128 while ( ap[i] === bp[i] ) { 10129 i++; 10130 } 10131 10132 return i ? 10133 // Do a sibling check if the nodes have a common ancestor 10134 siblingCheck( ap[i], bp[i] ) : 10135 10136 // Otherwise nodes in our document sort first 10137 ap[i] === preferredDoc ? -1 : 10138 bp[i] === preferredDoc ? 1 : 10139 0; 10140 }; 10141 10142 return document; 10143}; 10144 10145Sizzle.matches = function( expr, elements ) { 10146 return Sizzle( expr, null, null, elements ); 10147}; 10148 10149Sizzle.matchesSelector = function( elem, expr ) { 10150 // Set document vars if needed 10151 if ( ( elem.ownerDocument || elem ) !== document ) { 10152 setDocument( elem ); 10153 } 10154 10155 // Make sure that attribute selectors are quoted 10156 expr = expr.replace( rattributeQuotes, "='$1']" ); 10157 10158 if ( support.matchesSelector && documentIsHTML && 10159 !compilerCache[ expr + " " ] && 10160 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 10161 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 10162 10163 try { 10164 var ret = matches.call( elem, expr ); 10165 10166 // IE 9's matchesSelector returns false on disconnected nodes 10167 if ( ret || support.disconnectedMatch || 10168 // As well, disconnected nodes are said to be in a document 10169 // fragment in IE 9 10170 elem.document && elem.document.nodeType !== 11 ) { 10171 return ret; 10172 } 10173 } catch (e) {} 10174 } 10175 10176 return Sizzle( expr, document, null, [ elem ] ).length > 0; 10177}; 10178 10179Sizzle.contains = function( context, elem ) { 10180 // Set document vars if needed 10181 if ( ( context.ownerDocument || context ) !== document ) { 10182 setDocument( context ); 10183 } 10184 return contains( context, elem ); 10185}; 10186 10187Sizzle.attr = function( elem, name ) { 10188 // Set document vars if needed 10189 if ( ( elem.ownerDocument || elem ) !== document ) { 10190 setDocument( elem ); 10191 } 10192 10193 var fn = Expr.attrHandle[ name.toLowerCase() ], 10194 // Don't get fooled by Object.prototype properties (jQuery #13807) 10195 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 10196 fn( elem, name, !documentIsHTML ) : 10197 undefined; 10198 10199 return val !== undefined ? 10200 val : 10201 support.attributes || !documentIsHTML ? 10202 elem.getAttribute( name ) : 10203 (val = elem.getAttributeNode(name)) && val.specified ? 10204 val.value : 10205 null; 10206}; 10207 10208Sizzle.escape = function( sel ) { 10209 return (sel + "").replace( rcssescape, fcssescape )
vendor: 13,124 bytes, lines 10209-10660
10209; 10210}; 10211 10212Sizzle.error = function( msg ) { 10213 throw new Error( "Syntax error, unrecognized expression: " + msg ); 10214}; 10215 10216/** 10217 * Document sorting and removing duplicates 10218 * @param {ArrayLike} results 10219 */ 10220Sizzle.uniqueSort = function( results ) { 10221 var elem, 10222 duplicates = [], 10223 j = 0, 10224 i = 0; 10225 10226 // Unless we *know* we can detect duplicates, assume their presence 10227 hasDuplicate = !support.detectDuplicates; 10228 sortInput = !support.sortStable && results.slice( 0 ); 10229 results.sort( sortOrder ); 10230 10231 if ( hasDuplicate ) { 10232 while ( (elem = results[i++]) ) { 10233 if ( elem === results[ i ] ) { 10234 j = duplicates.push( i ); 10235 } 10236 } 10237 while ( j-- ) { 10238 results.splice( duplicates[ j ], 1 ); 10239 } 10240 } 10241 10242 // Clear input after sorting to release objects 10243 // See https://github.com/jquery/sizzle/pull/225 10244 sortInput = null; 10245 10246 return results; 10247}; 10248 10249/** 10250 * Utility function for retrieving the text value of an array of DOM nodes 10251 * @param {Array|Element} elem 10252 */ 10253getText = Sizzle.getText = function( elem ) { 10254 var node, 10255 ret = "", 10256 i = 0, 10257 nodeType = elem.nodeType; 10258 10259 if ( !nodeType ) { 10260 // If no nodeType, this is expected to be an array 10261 while ( (node = elem[i++]) ) { 10262 // Do not traverse comment nodes 10263 ret += getText( node ); 10264 } 10265 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 10266 // Use textContent for elements 10267 // innerText usage removed for consistency of new lines (jQuery #11153) 10268 if ( typeof elem.textContent === "string" ) { 10269 return elem.textContent; 10270 } else { 10271 // Traverse its children 10272 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 10273 ret += getText( elem ); 10274 } 10275 } 10276 } else if ( nodeType === 3 || nodeType === 4 ) { 10277 return elem.nodeValue; 10278 } 10279 // Do not include comment or processing instruction nodes 10280 10281 return ret; 10282}; 10283 10284Expr = Sizzle.selectors = { 10285 10286 // Can be adjusted by the user 10287 cacheLength: 50, 10288 10289 createPseudo: markFunction, 10290 10291 match: matchExpr, 10292 10293 attrHandle: {}, 10294 10295 find: {}, 10296 10297 relative: { 10298 ">": { dir: "parentNode", first: true }, 10299 " ": { dir: "parentNode" }, 10300 "+": { dir: "previousSibling", first: true }, 10301 "~": { dir: "previousSibling" } 10302 }, 10303 10304 preFilter: { 10305 "ATTR": function( match ) { 10306 match[1] = match[1].replace( runescape, funescape ); 10307 10308 // Move the given value to match[3] whether quoted or unquoted 10309 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); 10310 10311 if ( match[2] === "~=" ) { 10312 match[3] = " " + match[3] + " "; 10313 } 10314 10315 return match.slice( 0, 4 ); 10316 }, 10317 10318 "CHILD": function( match ) { 10319 /* matches from matchExpr["CHILD"] 10320 1 type (only|nth|...) 10321 2 what (child|of-type) 10322 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 10323 4 xn-component of xn+y argument ([+-]?\d*n|) 10324 5 sign of xn-component 10325 6 x of xn-component 10326 7 sign of y-component 10327 8 y of y-component 10328 */ 10329 match[1] = match[1].toLowerCase(); 10330 10331 if ( match[1].slice( 0, 3 ) === "nth" ) { 10332 // nth-* requires argument 10333 if ( !match[3] ) { 10334 Sizzle.error( match[0] ); 10335 } 10336 10337 // numeric x and y parameters for Expr.filter.CHILD 10338 // remember that false/true cast respectively to 0/1 10339 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); 10340 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); 10341 10342 // other types prohibit arguments 10343 } else if ( match[3] ) { 10344 Sizzle.error( match[0] ); 10345 } 10346 10347 return match; 10348 }, 10349 10350 "PSEUDO": function( match ) { 10351 var excess, 10352 unquoted = !match[6] && match[2]; 10353 10354 if ( matchExpr["CHILD"].test( match[0] ) ) { 10355 return null; 10356 } 10357 10358 // Accept quoted arguments as-is 10359 if ( match[3] ) { 10360 match[2] = match[4] || match[5] || ""; 10361 10362 // Strip excess characters from unquoted arguments 10363 } else if ( unquoted && rpseudo.test( unquoted ) && 10364 // Get excess from tokenize (recursively) 10365 (excess = tokenize( unquoted, true )) && 10366 // advance to the next closing parenthesis 10367 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 10368 10369 // excess is a negative index 10370 match[0] = match[0].slice( 0, excess ); 10371 match[2] = unquoted.slice( 0, excess ); 10372 } 10373 10374 // Return only captures needed by the pseudo filter method (type and argument) 10375 return match.slice( 0, 3 ); 10376 } 10377 }, 10378 10379 filter: { 10380 10381 "TAG": function( nodeNameSelector ) { 10382 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 10383 return nodeNameSelector === "*" ? 10384 function() { return true; } : 10385 function( elem ) { 10386 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 10387 }; 10388 }, 10389 10390 "CLASS": function( className ) { 10391 var pattern = classCache[ className + " " ]; 10392 10393 return pattern || 10394 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 10395 classCache( className, function( elem ) { 10396 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); 10397 }); 10398 }, 10399 10400 "ATTR": function( name, operator, check ) { 10401 return function( elem ) { 10402 var result = Sizzle.attr( elem, name ); 10403 10404 if ( result == null ) { 10405 return operator === "!="; 10406 } 10407 if ( !operator ) { 10408 return true; 10409 } 10410 10411 result += ""; 10412 10413 return operator === "=" ? result === check : 10414 operator === "!=" ? result !== check : 10415 operator === "^=" ? check && result.indexOf( check ) === 0 : 10416 operator === "*=" ? check && result.indexOf( check ) > -1 : 10417 operator === "$=" ? check && result.slice( -check.length ) === check : 10418 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 10419 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 10420 false; 10421 }; 10422 }, 10423 10424 "CHILD": function( type, what, argument, first, last ) { 10425 var simple = type.slice( 0, 3 ) !== "nth", 10426 forward = type.slice( -4 ) !== "last", 10427 ofType = what === "of-type"; 10428 10429 return first === 1 && last === 0 ? 10430 10431 // Shortcut for :nth-*(n) 10432 function( elem ) { 10433 return !!elem.parentNode; 10434 } : 10435 10436 function( elem, context, xml ) { 10437 var cache, uniqueCache, outerCache, node, nodeIndex, start, 10438 dir = simple !== forward ? "nextSibling" : "previousSibling", 10439 parent = elem.parentNode, 10440 name = ofType && elem.nodeName.toLowerCase(), 10441 useCache = !xml && !ofType, 10442 diff = false; 10443 10444 if ( parent ) { 10445 10446 // :(first|last|only)-(child|of-type) 10447 if ( simple ) { 10448 while ( dir ) { 10449 node = elem; 10450 while ( (node = node[ dir ]) ) { 10451 if ( ofType ? 10452 node.nodeName.toLowerCase() === name : 10453 node.nodeType === 1 ) { 10454 10455 return false; 10456 } 10457 } 10458 // Reverse direction for :only-* (if we haven't yet done so) 10459 start = dir = type === "only" && !start && "nextSibling"; 10460 } 10461 return true; 10462 } 10463 10464 start = [ forward ? parent.firstChild : parent.lastChild ]; 10465 10466 // non-xml :nth-child(...) stores cache data on `parent` 10467 if ( forward && useCache ) { 10468 10469 // Seek `elem` from a previously-cached index 10470 10471 // ...in a gzip-friendly way 10472 node = parent; 10473 outerCache = node[ expando ] || (node[ expando ] = {}); 10474 10475 // Support: IE <9 only 10476 // Defend against cloned attroperties (jQuery gh-1709) 10477 uniqueCache = outerCache[ node.uniqueID ] || 10478 (outerCache[ node.uniqueID ] = {}); 10479 10480 cache = uniqueCache[ type ] || []; 10481 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 10482 diff = nodeIndex && cache[ 2 ]; 10483 node = nodeIndex && parent.childNodes[ nodeIndex ]; 10484 10485 while ( (node = ++nodeIndex && node && node[ dir ] || 10486 10487 // Fallback to seeking `elem` from the start 10488 (diff = nodeIndex = 0) || start.pop()) ) { 10489 10490 // When found, cache indexes on `parent` and break 10491 if ( node.nodeType === 1 && ++diff && node === elem ) { 10492 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 10493 break; 10494 } 10495 } 10496 10497 } else { 10498 // Use previously-cached element index if available 10499 if ( useCache ) { 10500 // ...in a gzip-friendly way 10501 node = elem; 10502 outerCache = node[ expando ] || (node[ expando ] = {}); 10503 10504 // Support: IE <9 only 10505 // Defend against cloned attroperties (jQuery gh-1709) 10506 uniqueCache = outerCache[ node.uniqueID ] || 10507 (outerCache[ node.uniqueID ] = {}); 10508 10509 cache = uniqueCache[ type ] || []; 10510 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 10511 diff = nodeIndex; 10512 } 10513 10514 // xml :nth-child(...) 10515 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 10516 if ( diff === false ) { 10517 // Use the same loop as above to seek `elem` from the start 10518 while ( (node = ++nodeIndex && node && node[ dir ] || 10519 (diff = nodeIndex = 0) || start.pop()) ) { 10520 10521 if ( ( ofType ? 10522 node.nodeName.toLowerCase() === name : 10523 node.nodeType === 1 ) && 10524 ++diff ) { 10525 10526 // Cache the index of each encountered element 10527 if ( useCache ) { 10528 outerCache = node[ expando ] || (node[ expando ] = {}); 10529 10530 // Support: IE <9 only 10531 // Defend against cloned attroperties (jQuery gh-1709) 10532 uniqueCache = outerCache[ node.uniqueID ] || 10533 (outerCache[ node.uniqueID ] = {}); 10534 10535 uniqueCache[ type ] = [ dirruns, diff ]; 10536 } 10537 10538 if ( node === elem ) { 10539 break; 10540 } 10541 } 10542 } 10543 } 10544 } 10545 10546 // Incorporate the offset, then check against cycle size 10547 diff -= last; 10548 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 10549 } 10550 }; 10551 }, 10552 10553 "PSEUDO": function( pseudo, argument ) { 10554 // pseudo-class names are case-insensitive 10555 // http://www.w3.org/TR/selectors/#pseudo-classes 10556 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 10557 // Remember that setFilters inherits from pseudos 10558 var args, 10559 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 10560 Sizzle.error( "unsupported pseudo: " + pseudo ); 10561 10562 // The user may use createPseudo to indicate that 10563 // arguments are needed to create the filter function 10564 // just as Sizzle does 10565 if ( fn[ expando ] ) { 10566 return fn( argument ); 10567 } 10568 10569 // But maintain support for old signatures 10570 if ( fn.length > 1 ) { 10571 args = [ pseudo, pseudo, "", argument ]; 10572 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 10573 markFunction(function( seed, matches ) { 10574 var idx, 10575 matched = fn( seed, argument ), 10576 i = matched.length; 10577 while ( i-- ) { 10578 idx = indexOf( seed, matched[i] ); 10579 seed[ idx ] = !( matches[ idx ] = matched[i] ); 10580 } 10581 }) : 10582 function( elem ) { 10583 return fn( elem, 0, args ); 10584 }; 10585 } 10586 10587 return fn; 10588 } 10589 }, 10590 10591 pseudos: { 10592 // Potentially complex pseudos 10593 "not": markFunction(function( selector ) { 10594 // Trim the selector passed to compile 10595 // to avoid treating leading and trailing 10596 // spaces as combinators 10597 var input = [], 10598 results = [], 10599 matcher = compile( selector.replace( rtrim, "$1" ) ); 10600 10601 return matcher[ expando ] ? 10602 markFunction(function( seed, matches, context, xml ) { 10603 var elem, 10604 unmatched = matcher( seed, null, xml, [] ), 10605 i = seed.length; 10606 10607 // Match elements unmatched by `matcher` 10608 while ( i-- ) { 10609 if ( (elem = unmatched[i]) ) { 10610 seed[i] = !(matches[i] = elem); 10611 } 10612 } 10613 }) : 10614 function( elem, context, xml ) { 10615 input[0] = elem; 10616 matcher( input, null, xml, results ); 10617 // Don't keep the element (issue #299) 10618 input[0] = null; 10619 return !results.pop(); 10620 }; 10621 }), 10622 10623 "has": markFunction(function( selector ) { 10624 return function( elem ) { 10625 return Sizzle( selector, elem ).length > 0; 10626 }; 10627 }), 10628 10629 "contains": markFunction(function( text ) { 10630 text = text.replace( runescape, funescape ); 10631 return function( elem ) { 10632 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; 10633 }; 10634 }), 10635 10636 // "Whether an element is represented by a :lang() selector 10637 // is based solely on the element's language value 10638 // being equal to the identifier C, 10639 // or beginning with the identifier C immediately followed by "-". 10640 // The matching of C against the element's language value is performed case-insensitively. 10641 // The identifier C does not have to be a valid language name." 10642 // http://www.w3.org/TR/selectors/#lang-pseudo 10643 "lang": markFunction( function( lang ) { 10644 // lang value must be a valid identifier 10645 if ( !ridentifier.test(lang || "") ) { 10646 Sizzle.error( "unsupported lang: " + lang ); 10647 } 10648 lang = lang.replace( runescape, funescape ).toLowerCase(); 10649 return function( elem ) { 10650 var elemLang; 10651 do { 10652 if ( (elemLang = documentIsHTML ? 10653 elem.lang : 10654 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { 10655 10656 elemLang = elemLang.toLowerCase(); 10657 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 10658 } 10659 } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); 10660 return false;
vendor: 23,967 bytes, lines 10661-11532
10661 }; 10662 }), 10663 10664 // Miscellaneous 10665 "target": function( elem ) { 10666 var hash = window.location && window.location.hash; 10667 return hash && hash.slice( 1 ) === elem.id; 10668 }, 10669 10670 "root": function( elem ) { 10671 return elem === docElem; 10672 }, 10673 10674 "focus": function( elem ) { 10675 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 10676 }, 10677 10678 // Boolean properties 10679 "enabled": createDisabledPseudo( false ), 10680 "disabled": createDisabledPseudo( true ), 10681 10682 "checked": function( elem ) { 10683 // In CSS3, :checked should return both checked and selected elements 10684 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 10685 var nodeName = elem.nodeName.toLowerCase(); 10686 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 10687 }, 10688 10689 "selected": function( elem ) { 10690 // Accessing this property makes selected-by-default 10691 // options in Safari work properly 10692 if ( elem.parentNode ) { 10693 elem.parentNode.selectedIndex; 10694 } 10695 10696 return elem.selected === true; 10697 }, 10698 10699 // Contents 10700 "empty": function( elem ) { 10701 // http://www.w3.org/TR/selectors/#empty-pseudo 10702 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 10703 // but not by others (comment: 8; processing instruction: 7; etc.) 10704 // nodeType < 6 works because attributes (2) do not appear as children 10705 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 10706 if ( elem.nodeType < 6 ) { 10707 return false; 10708 } 10709 } 10710 return true; 10711 }, 10712 10713 "parent": function( elem ) { 10714 return !Expr.pseudos["empty"]( elem ); 10715 }, 10716 10717 // Element/input types 10718 "header": function( elem ) { 10719 return rheader.test( elem.nodeName ); 10720 }, 10721 10722 "input": function( elem ) { 10723 return rinputs.test( elem.nodeName ); 10724 }, 10725 10726 "button": function( elem ) { 10727 var name = elem.nodeName.toLowerCase(); 10728 return name === "input" && elem.type === "button" || name === "button"; 10729 }, 10730 10731 "text": function( elem ) { 10732 var attr; 10733 return elem.nodeName.toLowerCase() === "input" && 10734 elem.type === "text" && 10735 10736 // Support: IE<8 10737 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 10738 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); 10739 }, 10740 10741 // Position-in-collection 10742 "first": createPositionalPseudo(function() { 10743 return [ 0 ]; 10744 }), 10745 10746 "last": createPositionalPseudo(function( matchIndexes, length ) { 10747 return [ length - 1 ]; 10748 }), 10749 10750 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 10751 return [ argument < 0 ? argument + length : argument ]; 10752 }), 10753 10754 "even": createPositionalPseudo(function( matchIndexes, length ) { 10755 var i = 0; 10756 for ( ; i < length; i += 2 ) { 10757 matchIndexes.push( i ); 10758 } 10759 return matchIndexes; 10760 }), 10761 10762 "odd": createPositionalPseudo(function( matchIndexes, length ) { 10763 var i = 1; 10764 for ( ; i < length; i += 2 ) { 10765 matchIndexes.push( i ); 10766 } 10767 return matchIndexes; 10768 }), 10769 10770 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 10771 var i = argument < 0 ? argument + length : argument; 10772 for ( ; --i >= 0; ) { 10773 matchIndexes.push( i ); 10774 } 10775 return matchIndexes; 10776 }), 10777 10778 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 10779 var i = argument < 0 ? argument + length : argument; 10780 for ( ; ++i < length; ) { 10781 matchIndexes.push( i ); 10782 } 10783 return matchIndexes; 10784 }) 10785 } 10786}; 10787 10788Expr.pseudos["nth"] = Expr.pseudos["eq"]; 10789 10790// Add button/input type pseudos 10791for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 10792 Expr.pseudos[ i ] = createInputPseudo( i ); 10793} 10794for ( i in { submit: true, reset: true } ) { 10795 Expr.pseudos[ i ] = createButtonPseudo( i ); 10796} 10797 10798// Easy API for creating new setFilters 10799function setFilters() {} 10800setFilters.prototype = Expr.filters = Expr.pseudos; 10801Expr.setFilters = new setFilters(); 10802 10803tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 10804 var matched, match, tokens, type, 10805 soFar, groups, preFilters, 10806 cached = tokenCache[ selector + " " ]; 10807 10808 if ( cached ) { 10809 return parseOnly ? 0 : cached.slice( 0 ); 10810 } 10811 10812 soFar = selector; 10813 groups = []; 10814 preFilters = Expr.preFilter; 10815 10816 while ( soFar ) { 10817 10818 // Comma and first run 10819 if ( !matched || (match = rcomma.exec( soFar )) ) { 10820 if ( match ) { 10821 // Don't consume trailing commas as valid 10822 soFar = soFar.slice( match[0].length ) || soFar; 10823 } 10824 groups.push( (tokens = []) ); 10825 } 10826 10827 matched = false; 10828 10829 // Combinators 10830 if ( (match = rcombinators.exec( soFar )) ) { 10831 matched = match.shift(); 10832 tokens.push({ 10833 value: matched, 10834 // Cast descendant combinators to space 10835 type: match[0].replace( rtrim, " " ) 10836 }); 10837 soFar = soFar.slice( matched.length ); 10838 } 10839 10840 // Filters 10841 for ( type in Expr.filter ) { 10842 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 10843 (match = preFilters[ type ]( match ))) ) { 10844 matched = match.shift(); 10845 tokens.push({ 10846 value: matched, 10847 type: type, 10848 matches: match 10849 }); 10850 soFar = soFar.slice( matched.length ); 10851 } 10852 } 10853 10854 if ( !matched ) { 10855 break; 10856 } 10857 } 10858 10859 // Return the length of the invalid excess 10860 // if we're just parsing 10861 // Otherwise, throw an error or return tokens 10862 return parseOnly ? 10863 soFar.length : 10864 soFar ? 10865 Sizzle.error( selector ) : 10866 // Cache the tokens 10867 tokenCache( selector, groups ).slice( 0 ); 10868}; 10869 10870function toSelector( tokens ) { 10871 var i = 0, 10872 len = tokens.length, 10873 selector = ""; 10874 for ( ; i < len; i++ ) { 10875 selector += tokens[i].value; 10876 } 10877 return selector; 10878} 10879 10880function addCombinator( matcher, combinator, base ) { 10881 var dir = combinator.dir, 10882 skip = combinator.next, 10883 key = skip || dir, 10884 checkNonElements = base && key === "parentNode", 10885 doneName = done++; 10886 10887 return combinator.first ? 10888 // Check against closest ancestor/preceding element 10889 function( elem, context, xml ) { 10890 while ( (elem = elem[ dir ]) ) { 10891 if ( elem.nodeType === 1 || checkNonElements ) { 10892 return matcher( elem, context, xml ); 10893 } 10894 } 10895 return false; 10896 } : 10897 10898 // Check against all ancestor/preceding elements 10899 function( elem, context, xml ) { 10900 var oldCache, uniqueCache, outerCache, 10901 newCache = [ dirruns, doneName ]; 10902 10903 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 10904 if ( xml ) { 10905 while ( (elem = elem[ dir ]) ) { 10906 if ( elem.nodeType === 1 || checkNonElements ) { 10907 if ( matcher( elem, context, xml ) ) { 10908 return true; 10909 } 10910 } 10911 } 10912 } else { 10913 while ( (elem = elem[ dir ]) ) { 10914 if ( elem.nodeType === 1 || checkNonElements ) { 10915 outerCache = elem[ expando ] || (elem[ expando ] = {}); 10916 10917 // Support: IE <9 only 10918 // Defend against cloned attroperties (jQuery gh-1709) 10919 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); 10920 10921 if ( skip && skip === elem.nodeName.toLowerCase() ) { 10922 elem = elem[ dir ] || elem; 10923 } else if ( (oldCache = uniqueCache[ key ]) && 10924 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 10925 10926 // Assign to newCache so results back-propagate to previous elements 10927 return (newCache[ 2 ] = oldCache[ 2 ]); 10928 } else { 10929 // Reuse newcache so results back-propagate to previous elements 10930 uniqueCache[ key ] = newCache; 10931 10932 // A match means we're done; a fail means we have to keep checking 10933 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 10934 return true; 10935 } 10936 } 10937 } 10938 } 10939 } 10940 return false; 10941 }; 10942} 10943 10944function elementMatcher( matchers ) { 10945 return matchers.length > 1 ? 10946 function( elem, context, xml ) { 10947 var i = matchers.length; 10948 while ( i-- ) { 10949 if ( !matchers[i]( elem, context, xml ) ) { 10950 return false; 10951 } 10952 } 10953 return true; 10954 } : 10955 matchers[0]; 10956} 10957 10958function multipleContexts( selector, contexts, results ) { 10959 var i = 0, 10960 len = contexts.length; 10961 for ( ; i < len; i++ ) { 10962 Sizzle( selector, contexts[i], results ); 10963 } 10964 return results; 10965} 10966 10967function condense( unmatched, map, filter, context, xml ) { 10968 var elem, 10969 newUnmatched = [], 10970 i = 0, 10971 len = unmatched.length, 10972 mapped = map != null; 10973 10974 for ( ; i < len; i++ ) { 10975 if ( (elem = unmatched[i]) ) { 10976 if ( !filter || filter( elem, context, xml ) ) { 10977 newUnmatched.push( elem ); 10978 if ( mapped ) { 10979 map.push( i ); 10980 } 10981 } 10982 } 10983 } 10984 10985 return newUnmatched; 10986} 10987 10988function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 10989 if ( postFilter && !postFilter[ expando ] ) { 10990 postFilter = setMatcher( postFilter ); 10991 } 10992 if ( postFinder && !postFinder[ expando ] ) { 10993 postFinder = setMatcher( postFinder, postSelector ); 10994 } 10995 return markFunction(function( seed, results, context, xml ) { 10996 var temp, i, elem, 10997 preMap = [], 10998 postMap = [], 10999 preexisting = results.length, 11000 11001 // Get initial elements from seed or context 11002 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 11003 11004 // Prefilter to get matcher input, preserving a map for seed-results synchronization 11005 matcherIn = preFilter && ( seed || !selector ) ? 11006 condense( elems, preMap, preFilter, context, xml ) : 11007 elems, 11008 11009 matcherOut = matcher ? 11010 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 11011 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 11012 11013 // ...intermediate processing is necessary 11014 [] : 11015 11016 // ...otherwise use results directly 11017 results : 11018 matcherIn; 11019 11020 // Find primary matches 11021 if ( matcher ) { 11022 matcher( matcherIn, matcherOut, context, xml ); 11023 } 11024 11025 // Apply postFilter 11026 if ( postFilter ) { 11027 temp = condense( matcherOut, postMap ); 11028 postFilter( temp, [], context, xml ); 11029 11030 // Un-match failing elements by moving them back to matcherIn 11031 i = temp.length; 11032 while ( i-- ) { 11033 if ( (elem = temp[i]) ) { 11034 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 11035 } 11036 } 11037 } 11038 11039 if ( seed ) { 11040 if ( postFinder || preFilter ) { 11041 if ( postFinder ) { 11042 // Get the final matcherOut by condensing this intermediate into postFinder contexts 11043 temp = []; 11044 i = matcherOut.length; 11045 while ( i-- ) { 11046 if ( (elem = matcherOut[i]) ) { 11047 // Restore matcherIn since elem is not yet a final match 11048 temp.push( (matcherIn[i] = elem) ); 11049 } 11050 } 11051 postFinder( null, (matcherOut = []), temp, xml ); 11052 } 11053 11054 // Move matched elements from seed to results to keep them synchronized 11055 i = matcherOut.length; 11056 while ( i-- ) { 11057 if ( (elem = matcherOut[i]) && 11058 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { 11059 11060 seed[temp] = !(results[temp] = elem); 11061 } 11062 } 11063 } 11064 11065 // Add elements to results, through postFinder if defined 11066 } else { 11067 matcherOut = condense( 11068 matcherOut === results ? 11069 matcherOut.splice( preexisting, matcherOut.length ) : 11070 matcherOut 11071 ); 11072 if ( postFinder ) { 11073 postFinder( null, results, matcherOut, xml ); 11074 } else { 11075 push.apply( results, matcherOut ); 11076 } 11077 } 11078 }); 11079} 11080 11081function matcherFromTokens( tokens ) { 11082 var checkContext, matcher, j, 11083 len = tokens.length, 11084 leadingRelative = Expr.relative[ tokens[0].type ], 11085 implicitRelative = leadingRelative || Expr.relative[" "], 11086 i = leadingRelative ? 1 : 0, 11087 11088 // The foundational matcher ensures that elements are reachable from top-level context(s) 11089 matchContext = addCombinator( function( elem ) { 11090 return elem === checkContext; 11091 }, implicitRelative, true ), 11092 matchAnyContext = addCombinator( function( elem ) { 11093 return indexOf( checkContext, elem ) > -1; 11094 }, implicitRelative, true ), 11095 matchers = [ function( elem, context, xml ) { 11096 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 11097 (checkContext = context).nodeType ? 11098 matchContext( elem, context, xml ) : 11099 matchAnyContext( elem, context, xml ) ); 11100 // Avoid hanging onto element (issue #299) 11101 checkContext = null; 11102 return ret; 11103 } ]; 11104 11105 for ( ; i < len; i++ ) { 11106 if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 11107 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; 11108 } else { 11109 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 11110 11111 // Return special upon seeing a positional matcher 11112 if ( matcher[ expando ] ) { 11113 // Find the next relative operator (if any) for proper handling 11114 j = ++i; 11115 for ( ; j < len; j++ ) { 11116 if ( Expr.relative[ tokens[j].type ] ) { 11117 break; 11118 } 11119 } 11120 return setMatcher( 11121 i > 1 && elementMatcher( matchers ), 11122 i > 1 && toSelector( 11123 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 11124 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) 11125 ).replace( rtrim, "$1" ), 11126 matcher, 11127 i < j && matcherFromTokens( tokens.slice( i, j ) ), 11128 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 11129 j < len && toSelector( tokens ) 11130 ); 11131 } 11132 matchers.push( matcher ); 11133 } 11134 } 11135 11136 return elementMatcher( matchers ); 11137} 11138 11139function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 11140 var bySet = setMatchers.length > 0, 11141 byElement = elementMatchers.length > 0, 11142 superMatcher = function( seed, context, xml, results, outermost ) { 11143 var elem, j, matcher, 11144 matchedCount = 0, 11145 i = "0", 11146 unmatched = seed && [], 11147 setMatched = [], 11148 contextBackup = outermostContext, 11149 // We must always have either seed elements or outermost context 11150 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), 11151 // Use integer dirruns iff this is the outermost matcher 11152 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), 11153 len = elems.length; 11154 11155 if ( outermost ) { 11156 outermostContext = context === document || context || outermost; 11157 } 11158 11159 // Add elements passing elementMatchers directly to results 11160 // Support: IE<9, Safari 11161 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 11162 for ( ; i !== len && (elem = elems[i]) != null; i++ ) { 11163 if ( byElement && elem ) { 11164 j = 0; 11165 if ( !context && elem.ownerDocument !== document ) { 11166 setDocument( elem ); 11167 xml = !documentIsHTML; 11168 } 11169 while ( (matcher = elementMatchers[j++]) ) { 11170 if ( matcher( elem, context || document, xml) ) { 11171 results.push( elem ); 11172 break; 11173 } 11174 } 11175 if ( outermost ) { 11176 dirruns = dirrunsUnique; 11177 } 11178 } 11179 11180 // Track unmatched elements for set filters 11181 if ( bySet ) { 11182 // They will have gone through all possible matchers 11183 if ( (elem = !matcher && elem) ) { 11184 matchedCount--; 11185 } 11186 11187 // Lengthen the array for every element, matched or not 11188 if ( seed ) { 11189 unmatched.push( elem ); 11190 } 11191 } 11192 } 11193 11194 // `i` is now the count of elements visited above, and adding it to `matchedCount` 11195 // makes the latter nonnegative. 11196 matchedCount += i; 11197 11198 // Apply set filters to unmatched elements 11199 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 11200 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 11201 // no element matchers and no seed. 11202 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 11203 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 11204 // numerically zero. 11205 if ( bySet && i !== matchedCount ) { 11206 j = 0; 11207 while ( (matcher = setMatchers[j++]) ) { 11208 matcher( unmatched, setMatched, context, xml ); 11209 } 11210 11211 if ( seed ) { 11212 // Reintegrate element matches to eliminate the need for sorting 11213 if ( matchedCount > 0 ) { 11214 while ( i-- ) { 11215 if ( !(unmatched[i] || setMatched[i]) ) { 11216 setMatched[i] = pop.call( results ); 11217 } 11218 } 11219 } 11220 11221 // Discard index placeholder values to get only actual matches 11222 setMatched = condense( setMatched ); 11223 } 11224 11225 // Add matches to results 11226 push.apply( results, setMatched ); 11227 11228 // Seedless set matches succeeding multiple successful matchers stipulate sorting 11229 if ( outermost && !seed && setMatched.length > 0 && 11230 ( matchedCount + setMatchers.length ) > 1 ) { 11231 11232 Sizzle.uniqueSort( results ); 11233 } 11234 } 11235 11236 // Override manipulation of globals by nested matchers 11237 if ( outermost ) { 11238 dirruns = dirrunsUnique; 11239 outermostContext = contextBackup; 11240 } 11241 11242 return unmatched; 11243 }; 11244 11245 return bySet ? 11246 markFunction( superMatcher ) : 11247 superMatcher; 11248} 11249 11250compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 11251 var i, 11252 setMatchers = [], 11253 elementMatchers = [], 11254 cached = compilerCache[ selector + " " ]; 11255 11256 if ( !cached ) { 11257 // Generate a function of recursive functions that can be used to check each element 11258 if ( !match ) { 11259 match = tokenize( selector ); 11260 } 11261 i = match.length; 11262 while ( i-- ) { 11263 cached = matcherFromTokens( match[i] ); 11264 if ( cached[ expando ] ) { 11265 setMatchers.push( cached ); 11266 } else { 11267 elementMatchers.push( cached ); 11268 } 11269 } 11270 11271 // Cache the compiled function 11272 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 11273 11274 // Save selector and tokenization 11275 cached.selector = selector; 11276 } 11277 return cached; 11278}; 11279 11280/** 11281 * A low-level selection function that works with Sizzle's compiled 11282 * selector functions 11283 * @param {String|Function} selector A selector or a pre-compiled 11284 * selector function built with Sizzle.compile 11285 * @param {Element} context 11286 * @param {Array} [results] 11287 * @param {Array} [seed] A set of elements to match against 11288 */ 11289select = Sizzle.select = function( selector, context, results, seed ) { 11290 var i, tokens, token, type, find, 11291 compiled = typeof selector === "function" && selector, 11292 match = !seed && tokenize( (selector = compiled.selector || selector) ); 11293 11294 results = results || []; 11295 11296 // Try to minimize operations if there is only one selector in the list and no seed 11297 // (the latter of which guarantees us context) 11298 if ( match.length === 1 ) { 11299 11300 // Reduce context if the leading compound selector is an ID 11301 tokens = match[0] = match[0].slice( 0 ); 11302 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 11303 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { 11304 11305 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; 11306 if ( !context ) { 11307 return results; 11308 11309 // Precompiled matchers will still verify ancestry, so step up a level 11310 } else if ( compiled ) { 11311 context = context.parentNode; 11312 } 11313 11314 selector = selector.slice( tokens.shift().value.length ); 11315 } 11316 11317 // Fetch a seed set for right-to-left matching 11318 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; 11319 while ( i-- ) { 11320 token = tokens[i]; 11321 11322 // Abort if we hit a combinator 11323 if ( Expr.relative[ (type = token.type) ] ) { 11324 break; 11325 } 11326 if ( (find = Expr.find[ type ]) ) { 11327 // Search, expanding context for leading sibling combinators 11328 if ( (seed = find( 11329 token.matches[0].replace( runescape, funescape ), 11330 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context 11331 )) ) { 11332 11333 // If seed is empty or no tokens remain, we can return early 11334 tokens.splice( i, 1 ); 11335 selector = seed.length && toSelector( tokens ); 11336 if ( !selector ) { 11337 push.apply( results, seed ); 11338 return results; 11339 } 11340 11341 break; 11342 } 11343 } 11344 } 11345 } 11346 11347 // Compile and execute a filtering function if one is not provided 11348 // Provide `match` to avoid retokenization if we modified the selector above 11349 ( compiled || compile( selector, match ) )( 11350 seed, 11351 context, 11352 !documentIsHTML, 11353 results, 11354 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 11355 ); 11356 return results; 11357}; 11358 11359// One-time assignments 11360 11361// Sort stability 11362support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; 11363 11364// Support: Chrome 14-35+ 11365// Always assume duplicates if they aren't passed to the comparison function 11366support.detectDuplicates = !!hasDuplicate; 11367 11368// Initialize against the default document 11369setDocument(); 11370 11371// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 11372// Detached nodes confoundingly follow *each other* 11373support.sortDetached = assert(function( el ) { 11374 // Should return 1, but returns 4 (following) 11375 return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; 11376}); 11377 11378// Support: IE<8 11379// Prevent attribute/property "interpolation" 11380// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 11381if ( !assert(function( el ) { 11382 el.innerHTML = "<a href='#'></a>"; 11383 return el.firstChild.getAttribute("href") === "#" ; 11384}) ) { 11385 addHandle( "type|href|height|width", function( elem, name, isXML ) { 11386 if ( !isXML ) { 11387 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 11388 } 11389 }); 11390} 11391 11392// Support: IE<9 11393// Use defaultValue in place of getAttribute("value") 11394if ( !support.attributes || !assert(function( el ) { 11395 el.innerHTML = "<input/>"; 11396 el.firstChild.setAttribute( "value", "" ); 11397 return el.firstChild.getAttribute( "value" ) === ""; 11398}) ) { 11399 addHandle( "value", function( elem, name, isXML ) { 11400 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 11401 return elem.defaultValue; 11402 } 11403 }); 11404} 11405 11406// Support: IE<9 11407// Use getAttributeNode to fetch booleans when getAttribute lies 11408if ( !assert(function( el ) { 11409 return el.getAttribute("disabled") == null; 11410}) ) { 11411 addHandle( booleans, function( elem, name, isXML ) { 11412 var val; 11413 if ( !isXML ) { 11414 return elem[ name ] === true ? name.toLowerCase() : 11415 (val = elem.getAttributeNode( name )) && val.specified ? 11416 val.value : 11417 null; 11418 } 11419 }); 11420} 11421 11422return Sizzle; 11423 11424})( window ); 11425 11426 11427 11428jQuery.find = Sizzle; 11429jQuery.expr = Sizzle.selectors; 11430 11431// Deprecated 11432jQuery.expr[ ":" ] = jQuery.expr.pseudos; 11433jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 11434jQuery.text = Sizzle.getText; 11435jQuery.isXMLDoc = Sizzle.isXML; 11436jQuery.contains = Sizzle.contains; 11437jQuery.escapeSelector = Sizzle.escape; 11438 11439 11440 11441 11442var dir = function( elem, dir, until ) { 11443 var matched = [], 11444 truncate = until !== undefined; 11445 11446 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 11447 if ( elem.nodeType === 1 ) { 11448 if ( truncate && jQuery( elem ).is( until ) ) { 11449 break; 11450 } 11451 matched.push( elem ); 11452 } 11453 } 11454 return matched; 11455}; 11456 11457 11458var siblings = function( n, elem ) { 11459 var matched = []; 11460 11461 for ( ; n; n = n.nextSibling ) { 11462 if ( n.nodeType === 1 && n !== elem ) { 11463 matched.push( n ); 11464 } 11465 } 11466 11467 return matched; 11468}; 11469 11470 11471var rneedsContext = jQuery.expr.match.needsContext; 11472 11473 11474 11475function nodeName( elem, name ) { 11476 11477 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 11478 11479}; 11480var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 11481 11482 11483 11484// Implement the identical functionality for filter and not 11485function winnow( elements, qualifier, not ) { 11486 if ( isFunction( qualifier ) ) { 11487 return jQuery.grep( elements, function( elem, i ) { 11488 return !!qualifier.call( elem, i, elem ) !== not; 11489 } ); 11490 } 11491 11492 // Single element 11493 if ( qualifier.nodeType ) { 11494 return jQuery.grep( elements, function( elem ) { 11495 return ( elem === qualifier ) !== not; 11496 } ); 11497 } 11498 11499 // Arraylike of elements (jQuery, arguments, Array) 11500 if ( typeof qualifier !== "string" ) { 11501 return jQuery.grep( elements, function( elem ) { 11502 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 11503 } ); 11504 } 11505 11506 // Filtered directly for both simple and complex selectors 11507 return jQuery.filter( qualifier, elements, not ); 11508} 11509 11510jQuery.filter = function( expr, elems, not ) { 11511 var elem = elems[ 0 ]; 11512 11513 if ( not ) { 11514 expr = ":not(" + expr + ")"; 11515 } 11516 11517 if ( elems.length === 1 && elem.nodeType === 1 ) { 11518 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 11519 } 11520 11521 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 11522 return elem.nodeType === 1; 11523 } ) ); 11524}; 11525 11526jQuery.fn.extend( { 11527 find: function( selector ) { 11528 var i, ret, 11529 len = this.length, 11530 self = this; 11531 11532 if ( typeof selector !== "string" ) {
vendor: 4,662 bytes, lines 11533-11718
11533 return this.pushStack( jQuery( selector ).filter( function() { 11534 for ( i = 0; i < len; i++ ) { 11535 if ( jQuery.contains( self[ i ], this ) ) { 11536 return true; 11537 } 11538 } 11539 } ) ); 11540 } 11541 11542 ret = this.pushStack( [] ); 11543 11544 for ( i = 0; i < len; i++ ) { 11545 jQuery.find( selector, self[ i ], ret ); 11546 } 11547 11548 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 11549 }, 11550 filter: function( selector ) { 11551 return this.pushStack( winnow( this, selector || [], false ) ); 11552 }, 11553 not: function( selector ) { 11554 return this.pushStack( winnow( this, selector || [], true ) ); 11555 }, 11556 is: function( selector ) { 11557 return !!winnow( 11558 this, 11559 11560 // If this is a positional/relative selector, check membership in the returned set 11561 // so $("p:first").is("p:last") won't return true for a doc with two "p". 11562 typeof selector === "string" && rneedsContext.test( selector ) ? 11563 jQuery( selector ) : 11564 selector || [], 11565 false 11566 ).length; 11567 } 11568} ); 11569 11570 11571// Initialize a jQuery object 11572 11573 11574// A central reference to the root jQuery(document) 11575var rootjQuery, 11576 11577 // A simple way to check for HTML strings 11578 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 11579 // Strict HTML recognition (#11290: must start with <) 11580 // Shortcut simple #id case for speed 11581 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 11582 11583 init = jQuery.fn.init = function( selector, context, root ) { 11584 var match, elem; 11585 11586 // HANDLE: $(""), $(null), $(undefined), $(false) 11587 if ( !selector ) { 11588 return this; 11589 } 11590 11591 // Method init() accepts an alternate rootjQuery 11592 // so migrate can support jQuery.sub (gh-2101) 11593 root = root || rootjQuery; 11594 11595 // Handle HTML strings 11596 if ( typeof selector === "string" ) { 11597 if ( selector[ 0 ] === "<" && 11598 selector[ selector.length - 1 ] === ">" && 11599 selector.length >= 3 ) { 11600 11601 // Assume that strings that start and end with <> are HTML and skip the regex check 11602 match = [ null, selector, null ]; 11603 11604 } else { 11605 match = rquickExpr.exec( selector ); 11606 } 11607 11608 // Match html or make sure no context is specified for #id 11609 if ( match && ( match[ 1 ] || !context ) ) { 11610 11611 // HANDLE: $(html) -> $(array) 11612 if ( match[ 1 ] ) { 11613 context = context instanceof jQuery ? context[ 0 ] : context; 11614 11615 // Option to run scripts is true for back-compat 11616 // Intentionally let the error be thrown if parseHTML is not present 11617 jQuery.merge( this, jQuery.parseHTML( 11618 match[ 1 ], 11619 context && context.nodeType ? context.ownerDocument || context : document, 11620 true 11621 ) ); 11622 11623 // HANDLE: $(html, props) 11624 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 11625 for ( match in context ) { 11626 11627 // Properties of context are called as methods if possible 11628 if ( isFunction( this[ match ] ) ) { 11629 this[ match ]( context[ match ] ); 11630 11631 // ...and otherwise set as attributes 11632 } else { 11633 this.attr( match, context[ match ] ); 11634 } 11635 } 11636 } 11637 11638 return this; 11639 11640 // HANDLE: $(#id) 11641 } else { 11642 elem = document.getElementById( match[ 2 ] ); 11643 11644 if ( elem ) { 11645 11646 // Inject the element directly into the jQuery object 11647 this[ 0 ] = elem; 11648 this.length = 1; 11649 } 11650 return this; 11651 } 11652 11653 // HANDLE: $(expr, $(...)) 11654 } else if ( !context || context.jquery ) { 11655 return ( context || root ).find( selector ); 11656 11657 // HANDLE: $(expr, context) 11658 // (which is just equivalent to: $(context).find(expr) 11659 } else { 11660 return this.constructor( context ).find( selector ); 11661 } 11662 11663 // HANDLE: $(DOMElement) 11664 } else if ( selector.nodeType ) { 11665 this[ 0 ] = selector; 11666 this.length = 1; 11667 return this; 11668 11669 // HANDLE: $(function) 11670 // Shortcut for document ready 11671 } else if ( isFunction( selector ) ) { 11672 return root.ready !== undefined ? 11673 root.ready( selector ) : 11674 11675 // Execute immediately if ready is not present 11676 selector( jQuery ); 11677 } 11678 11679 return jQuery.makeArray( selector, this ); 11680 }; 11681 11682// Give the init function the jQuery prototype for later instantiation 11683init.prototype = jQuery.fn; 11684 11685// Initialize central reference 11686rootjQuery = jQuery( document ); 11687 11688 11689var rparentsprev = /^(?:parents|prev(?:Until|All))/, 11690 11691 // Methods guaranteed to produce a unique set when starting from a unique set 11692 guaranteedUnique = { 11693 children: true, 11694 contents: true, 11695 next: true, 11696 prev: true 11697 }; 11698 11699jQuery.fn.extend( { 11700 has: function( target ) { 11701 var targets = jQuery( target, this ), 11702 l = targets.length; 11703 11704 return this.filter( function() { 11705 var i = 0; 11706 for ( ; i < l; i++ ) { 11707 if ( jQuery.contains( this, targets[ i ] ) ) { 11708 return true; 11709 } 11710 } 11711 } ); 11712 }, 11713 11714 closest: function( selectors, context ) { 11715 var cur, 11716 i = 0, 11717 l = this.length, 11718 matched = [],
vendor: 6,003 bytes, lines 11719-11945
11719 targets = typeof selectors !== "string" && jQuery( selectors ); 11720 11721 // Positional selectors never match, since there's no _selection_ context 11722 if ( !rneedsContext.test( selectors ) ) { 11723 for ( ; i < l; i++ ) { 11724 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 11725 11726 // Always skip document fragments 11727 if ( cur.nodeType < 11 && ( targets ? 11728 targets.index( cur ) > -1 : 11729 11730 // Don't pass non-elements to Sizzle 11731 cur.nodeType === 1 && 11732 jQuery.find.matchesSelector( cur, selectors ) ) ) { 11733 11734 matched.push( cur ); 11735 break; 11736 } 11737 } 11738 } 11739 } 11740 11741 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 11742 }, 11743 11744 // Determine the position of an element within the set 11745 index: function( elem ) { 11746 11747 // No argument, return index in parent 11748 if ( !elem ) { 11749 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 11750 } 11751 11752 // Index in selector 11753 if ( typeof elem === "string" ) { 11754 return indexOf.call( jQuery( elem ), this[ 0 ] ); 11755 } 11756 11757 // Locate the position of the desired element 11758 return indexOf.call( this, 11759 11760 // If it receives a jQuery object, the first element is used 11761 elem.jquery ? elem[ 0 ] : elem 11762 ); 11763 }, 11764 11765 add: function( selector, context ) { 11766 return this.pushStack( 11767 jQuery.uniqueSort( 11768 jQuery.merge( this.get(), jQuery( selector, context ) ) 11769 ) 11770 ); 11771 }, 11772 11773 addBack: function( selector ) { 11774 return this.add( selector == null ? 11775 this.prevObject : this.prevObject.filter( selector ) 11776 ); 11777 } 11778} ); 11779 11780function sibling( cur, dir ) { 11781 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 11782 return cur; 11783} 11784 11785jQuery.each( { 11786 parent: function( elem ) { 11787 var parent = elem.parentNode; 11788 return parent && parent.nodeType !== 11 ? parent : null; 11789 }, 11790 parents: function( elem ) { 11791 return dir( elem, "parentNode" ); 11792 }, 11793 parentsUntil: function( elem, i, until ) { 11794 return dir( elem, "parentNode", until ); 11795 }, 11796 next: function( elem ) { 11797 return sibling( elem, "nextSibling" ); 11798 }, 11799 prev: function( elem ) { 11800 return sibling( elem, "previousSibling" ); 11801 }, 11802 nextAll: function( elem ) { 11803 return dir( elem, "nextSibling" ); 11804 }, 11805 prevAll: function( elem ) { 11806 return dir( elem, "previousSibling" ); 11807 }, 11808 nextUntil: function( elem, i, until ) { 11809 return dir( elem, "nextSibling", until ); 11810 }, 11811 prevUntil: function( elem, i, until ) { 11812 return dir( elem, "previousSibling", until ); 11813 }, 11814 siblings: function( elem ) { 11815 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 11816 }, 11817 children: function( elem ) { 11818 return siblings( elem.firstChild ); 11819 }, 11820 contents: function( elem ) { 11821 if ( nodeName( elem, "iframe" ) ) { 11822 return elem.contentDocument; 11823 } 11824 11825 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 11826 // Treat the template element as a regular one in browsers that 11827 // don't support it. 11828 if ( nodeName( elem, "template" ) ) { 11829 elem = elem.content || elem; 11830 } 11831 11832 return jQuery.merge( [], elem.childNodes ); 11833 } 11834}, function( name, fn ) { 11835 jQuery.fn[ name ] = function( until, selector ) { 11836 var matched = jQuery.map( this, fn, until ); 11837 11838 if ( name.slice( -5 ) !== "Until" ) { 11839 selector = until; 11840 } 11841 11842 if ( selector && typeof selector === "string" ) { 11843 matched = jQuery.filter( selector, matched ); 11844 } 11845 11846 if ( this.length > 1 ) { 11847 11848 // Remove duplicates 11849 if ( !guaranteedUnique[ name ] ) { 11850 jQuery.uniqueSort( matched ); 11851 } 11852 11853 // Reverse order for parents* and prev-derivatives 11854 if ( rparentsprev.test( name ) ) { 11855 matched.reverse(); 11856 } 11857 } 11858 11859 return this.pushStack( matched ); 11860 }; 11861} ); 11862var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 11863 11864 11865 11866// Convert String-formatted options into Object-formatted ones 11867function createOptions( options ) { 11868 var object = {}; 11869 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 11870 object[ flag ] = true; 11871 } ); 11872 return object; 11873} 11874 11875/* 11876 * Create a callback list using the following parameters: 11877 * 11878 * options: an optional list of space-separated options that will change how 11879 * the callback list behaves or a more traditional option object 11880 * 11881 * By default a callback list will act like an event callback list and can be 11882 * "fired" multiple times. 11883 * 11884 * Possible options: 11885 * 11886 * once: will ensure the callback list can only be fired once (like a Deferred) 11887 * 11888 * memory: will keep track of previous values and will call any callback added 11889 * after the list has been fired right away with the latest "memorized" 11890 * values (like a Deferred) 11891 * 11892 * unique: will ensure a callback can only be added once (no duplicate in the list) 11893 * 11894 * stopOnFalse: interrupt callings when a callback returns false 11895 * 11896 */ 11897jQuery.Callbacks = function( options ) { 11898 11899 // Convert options from String-formatted to Object-formatted if needed 11900 // (we check in cache first) 11901 options = typeof options === "string" ? 11902 createOptions( options ) : 11903 jQuery.extend( {}, options ); 11904 11905 var // Flag to know if list is currently firing 11906 firing, 11907 11908 // Last fire value for non-forgettable lists 11909 memory, 11910 11911 // Flag to know if list was already fired 11912 fired, 11913 11914 // Flag to prevent firing 11915 locked, 11916 11917 // Actual callback list 11918 list = [], 11919 11920 // Queue of execution data for repeatable lists 11921 queue = [], 11922 11923 // Index of currently firing callback (modified by add/remove as needed) 11924 firingIndex = -1, 11925 11926 // Fire callbacks 11927 fire = function() { 11928 11929 // Enforce single-firing 11930 locked = locked || options.once; 11931 11932 // Execute callbacks for all pending executions, 11933 // respecting firingIndex overrides and runtime changes 11934 fired = firing = true; 11935 for ( ; queue.length; firingIndex = -1 ) { 11936 memory = queue.shift(); 11937 while ( ++firingIndex < list.length ) { 11938 11939 // Run callback and check for early termination 11940 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 11941 options.stopOnFalse ) { 11942 11943 // Jump to end and forget the data so .add doesn't re-fire 11944 firingIndex = list.length; 11945 memory = false;
vendor: 4,918 bytes, lines 11946-12155
11946 } 11947 } 11948 } 11949 11950 // Forget the data if we're done with it 11951 if ( !options.memory ) { 11952 memory = false; 11953 } 11954 11955 firing = false; 11956 11957 // Clean up if we're done firing for good 11958 if ( locked ) { 11959 11960 // Keep an empty list if we have data for future add calls 11961 if ( memory ) { 11962 list = []; 11963 11964 // Otherwise, this object is spent 11965 } else { 11966 list = ""; 11967 } 11968 } 11969 }, 11970 11971 // Actual Callbacks object 11972 self = { 11973 11974 // Add a callback or a collection of callbacks to the list 11975 add: function() { 11976 if ( list ) { 11977 11978 // If we have memory from a past run, we should fire after adding 11979 if ( memory && !firing ) { 11980 firingIndex = list.length - 1; 11981 queue.push( memory ); 11982 } 11983 11984 ( function add( args ) { 11985 jQuery.each( args, function( _, arg ) { 11986 if ( isFunction( arg ) ) { 11987 if ( !options.unique || !self.has( arg ) ) { 11988 list.push( arg ); 11989 } 11990 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 11991 11992 // Inspect recursively 11993 add( arg ); 11994 } 11995 } ); 11996 } )( arguments ); 11997 11998 if ( memory && !firing ) { 11999 fire(); 12000 } 12001 } 12002 return this; 12003 }, 12004 12005 // Remove a callback from the list 12006 remove: function() { 12007 jQuery.each( arguments, function( _, arg ) { 12008 var index; 12009 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 12010 list.splice( index, 1 ); 12011 12012 // Handle firing indexes 12013 if ( index <= firingIndex ) { 12014 firingIndex--; 12015 } 12016 } 12017 } ); 12018 return this; 12019 }, 12020 12021 // Check if a given callback is in the list. 12022 // If no argument is given, return whether or not list has callbacks attached. 12023 has: function( fn ) { 12024 return fn ? 12025 jQuery.inArray( fn, list ) > -1 : 12026 list.length > 0; 12027 }, 12028 12029 // Remove all callbacks from the list 12030 empty: function() { 12031 if ( list ) { 12032 list = []; 12033 } 12034 return this; 12035 }, 12036 12037 // Disable .fire and .add 12038 // Abort any current/pending executions 12039 // Clear all callbacks and values 12040 disable: function() { 12041 locked = queue = []; 12042 list = memory = ""; 12043 return this; 12044 }, 12045 disabled: function() { 12046 return !list; 12047 }, 12048 12049 // Disable .fire 12050 // Also disable .add unless we have memory (since it would have no effect) 12051 // Abort any pending executions 12052 lock: function() { 12053 locked = queue = []; 12054 if ( !memory && !firing ) { 12055 list = memory = ""; 12056 } 12057 return this; 12058 }, 12059 locked: function() { 12060 return !!locked; 12061 }, 12062 12063 // Call all callbacks with the given context and arguments 12064 fireWith: function( context, args ) { 12065 if ( !locked ) { 12066 args = args || []; 12067 args = [ context, args.slice ? args.slice() : args ]; 12068 queue.push( args ); 12069 if ( !firing ) { 12070 fire(); 12071 } 12072 } 12073 return this; 12074 }, 12075 12076 // Call all the callbacks with the given arguments 12077 fire: function() { 12078 self.fireWith( this, arguments ); 12079 return this; 12080 }, 12081 12082 // To know if the callbacks have already been called at least once 12083 fired: function() { 12084 return !!fired; 12085 } 12086 }; 12087 12088 return self; 12089}; 12090 12091 12092function Identity( v ) { 12093 return v; 12094} 12095function Thrower( ex ) { 12096 throw ex; 12097} 12098 12099function adoptValue( value, resolve, reject, noValue ) { 12100 var method; 12101 12102 try { 12103 12104 // Check for promise aspect first to privilege synchronous behavior 12105 if ( value && isFunction( ( method = value.promise ) ) ) { 12106 method.call( value ).done( resolve ).fail( reject ); 12107 12108 // Other thenables 12109 } else if ( value && isFunction( ( method = value.then ) ) ) { 12110 method.call( value, resolve, reject ); 12111 12112 // Other non-thenables 12113 } else { 12114 12115 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 12116 // * false: [ value ].slice( 0 ) => resolve( value ) 12117 // * true: [ value ].slice( 1 ) => resolve() 12118 resolve.apply( undefined, [ value ].slice( noValue ) ); 12119 } 12120 12121 // For Promises/A+, convert exceptions into rejections 12122 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 12123 // Deferred#then to conditionally suppress rejection. 12124 } catch ( value ) { 12125 12126 // Support: Android 4.0 only 12127 // Strict mode functions invoked without .call/.apply get global-object context 12128 reject.apply( undefined, [ value ] ); 12129 } 12130} 12131 12132jQuery.extend( { 12133 12134 Deferred: function( func ) { 12135 var tuples = [ 12136 12137 // action, add listener, callbacks, 12138 // ... .then handlers, argument index, [final state] 12139 [ "notify", "progress", jQuery.Callbacks( "memory" ), 12140 jQuery.Callbacks( "memory" ), 2 ], 12141 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 12142 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 12143 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 12144 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 12145 ], 12146 state = "pending", 12147 promise = { 12148 state: function() { 12149 return state; 12150 }, 12151 always: function() { 12152 deferred.done( arguments ).fail( arguments ); 12153 return this; 12154 }, 12155 "catch": function( fn ) {
vendor: 15,167 bytes, lines 12156-12747
12156 return promise.then( null, fn ); 12157 }, 12158 12159 // Keep pipe for back-compat 12160 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 12161 var fns = arguments; 12162 12163 return jQuery.Deferred( function( newDefer ) { 12164 jQuery.each( tuples, function( i, tuple ) { 12165 12166 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 12167 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 12168 12169 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 12170 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 12171 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 12172 deferred[ tuple[ 1 ] ]( function() { 12173 var returned = fn && fn.apply( this, arguments ); 12174 if ( returned && isFunction( returned.promise ) ) { 12175 returned.promise() 12176 .progress( newDefer.notify ) 12177 .done( newDefer.resolve ) 12178 .fail( newDefer.reject ); 12179 } else { 12180 newDefer[ tuple[ 0 ] + "With" ]( 12181 this, 12182 fn ? [ returned ] : arguments 12183 ); 12184 } 12185 } ); 12186 } ); 12187 fns = null; 12188 } ).promise(); 12189 }, 12190 then: function( onFulfilled, onRejected, onProgress ) { 12191 var maxDepth = 0; 12192 function resolve( depth, deferred, handler, special ) { 12193 return function() { 12194 var that = this, 12195 args = arguments, 12196 mightThrow = function() { 12197 var returned, then; 12198 12199 // Support: Promises/A+ section 2.3.3.3.3 12200 // https://promisesaplus.com/#point-59 12201 // Ignore double-resolution attempts 12202 if ( depth < maxDepth ) { 12203 return; 12204 } 12205 12206 returned = handler.apply( that, args ); 12207 12208 // Support: Promises/A+ section 2.3.1 12209 // https://promisesaplus.com/#point-48 12210 if ( returned === deferred.promise() ) { 12211 throw new TypeError( "Thenable self-resolution" ); 12212 } 12213 12214 // Support: Promises/A+ sections 2.3.3.1, 3.5 12215 // https://promisesaplus.com/#point-54 12216 // https://promisesaplus.com/#point-75 12217 // Retrieve `then` only once 12218 then = returned && 12219 12220 // Support: Promises/A+ section 2.3.4 12221 // https://promisesaplus.com/#point-64 12222 // Only check objects and functions for thenability 12223 ( typeof returned === "object" || 12224 typeof returned === "function" ) && 12225 returned.then; 12226 12227 // Handle a returned thenable 12228 if ( isFunction( then ) ) { 12229 12230 // Special processors (notify) just wait for resolution 12231 if ( special ) { 12232 then.call( 12233 returned, 12234 resolve( maxDepth, deferred, Identity, special ), 12235 resolve( maxDepth, deferred, Thrower, special ) 12236 ); 12237 12238 // Normal processors (resolve) also hook into progress 12239 } else { 12240 12241 // ...and disregard older resolution values 12242 maxDepth++; 12243 12244 then.call( 12245 returned, 12246 resolve( maxDepth, deferred, Identity, special ), 12247 resolve( maxDepth, deferred, Thrower, special ), 12248 resolve( maxDepth, deferred, Identity, 12249 deferred.notifyWith ) 12250 ); 12251 } 12252 12253 // Handle all other returned values 12254 } else { 12255 12256 // Only substitute handlers pass on context 12257 // and multiple values (non-spec behavior) 12258 if ( handler !== Identity ) { 12259 that = undefined; 12260 args = [ returned ]; 12261 } 12262 12263 // Process the value(s) 12264 // Default process is resolve 12265 ( special || deferred.resolveWith )( that, args ); 12266 } 12267 }, 12268 12269 // Only normal processors (resolve) catch and reject exceptions 12270 process = special ? 12271 mightThrow : 12272 function() { 12273 try { 12274 mightThrow(); 12275 } catch ( e ) { 12276 12277 if ( jQuery.Deferred.exceptionHook ) { 12278 jQuery.Deferred.exceptionHook( e, 12279 process.stackTrace ); 12280 } 12281 12282 // Support: Promises/A+ section 2.3.3.3.4.1 12283 // https://promisesaplus.com/#point-61 12284 // Ignore post-resolution exceptions 12285 if ( depth + 1 >= maxDepth ) { 12286 12287 // Only substitute handlers pass on context 12288 // and multiple values (non-spec behavior) 12289 if ( handler !== Thrower ) { 12290 that = undefined; 12291 args = [ e ]; 12292 } 12293 12294 deferred.rejectWith( that, args ); 12295 } 12296 } 12297 }; 12298 12299 // Support: Promises/A+ section 2.3.3.3.1 12300 // https://promisesaplus.com/#point-57 12301 // Re-resolve promises immediately to dodge false rejection from 12302 // subsequent errors 12303 if ( depth ) { 12304 process(); 12305 } else { 12306 12307 // Call an optional hook to record the stack, in case of exception 12308 // since it's otherwise lost when execution goes async 12309 if ( jQuery.Deferred.getStackHook ) { 12310 process.stackTrace = jQuery.Deferred.getStackHook(); 12311 } 12312 window.setTimeout( process ); 12313 } 12314 }; 12315 } 12316 12317 return jQuery.Deferred( function( newDefer ) { 12318 12319 // progress_handlers.add( ... ) 12320 tuples[ 0 ][ 3 ].add( 12321 resolve( 12322 0, 12323 newDefer, 12324 isFunction( onProgress ) ? 12325 onProgress : 12326 Identity, 12327 newDefer.notifyWith 12328 ) 12329 ); 12330 12331 // fulfilled_handlers.add( ... ) 12332 tuples[ 1 ][ 3 ].add( 12333 resolve( 12334 0, 12335 newDefer, 12336 isFunction( onFulfilled ) ? 12337 onFulfilled : 12338 Identity 12339 ) 12340 ); 12341 12342 // rejected_handlers.add( ... ) 12343 tuples[ 2 ][ 3 ].add( 12344 resolve( 12345 0, 12346 newDefer, 12347 isFunction( onRejected ) ? 12348 onRejected : 12349 Thrower 12350 ) 12351 ); 12352 } ).promise(); 12353 }, 12354 12355 // Get a promise for this deferred 12356 // If obj is provided, the promise aspect is added to the object 12357 promise: function( obj ) { 12358 return obj != null ? jQuery.extend( obj, promise ) : promise; 12359 } 12360 }, 12361 deferred = {}; 12362 12363 // Add list-specific methods 12364 jQuery.each( tuples, function( i, tuple ) { 12365 var list = tuple[ 2 ], 12366 stateString = tuple[ 5 ]; 12367 12368 // promise.progress = list.add 12369 // promise.done = list.add 12370 // promise.fail = list.add 12371 promise[ tuple[ 1 ] ] = list.add; 12372 12373 // Handle state 12374 if ( stateString ) { 12375 list.add( 12376 function() { 12377 12378 // state = "resolved" (i.e., fulfilled) 12379 // state = "rejected" 12380 state = stateString; 12381 }, 12382 12383 // rejected_callbacks.disable 12384 // fulfilled_callbacks.disable 12385 tuples[ 3 - i ][ 2 ].disable, 12386 12387 // rejected_handlers.disable 12388 // fulfilled_handlers.disable 12389 tuples[ 3 - i ][ 3 ].disable, 12390 12391 // progress_callbacks.lock 12392 tuples[ 0 ][ 2 ].lock, 12393 12394 // progress_handlers.lock 12395 tuples[ 0 ][ 3 ].lock 12396 ); 12397 } 12398 12399 // progress_handlers.fire 12400 // fulfilled_handlers.fire 12401 // rejected_handlers.fire 12402 list.add( tuple[ 3 ].fire ); 12403 12404 // deferred.notify = function() { deferred.notifyWith(...) } 12405 // deferred.resolve = function() { deferred.resolveWith(...) } 12406 // deferred.reject = function() { deferred.rejectWith(...) } 12407 deferred[ tuple[ 0 ] ] = function() { 12408 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 12409 return this; 12410 }; 12411 12412 // deferred.notifyWith = list.fireWith 12413 // deferred.resolveWith = list.fireWith 12414 // deferred.rejectWith = list.fireWith 12415 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 12416 } ); 12417 12418 // Make the deferred a promise 12419 promise.promise( deferred ); 12420 12421 // Call given func if any 12422 if ( func ) { 12423 func.call( deferred, deferred ); 12424 } 12425 12426 // All done! 12427 return deferred; 12428 }, 12429 12430 // Deferred helper 12431 when: function( singleValue ) { 12432 var 12433 12434 // count of uncompleted subordinates 12435 remaining = arguments.length, 12436 12437 // count of unprocessed arguments 12438 i = remaining, 12439 12440 // subordinate fulfillment data 12441 resolveContexts = Array( i ), 12442 resolveValues = slice.call( arguments ), 12443 12444 // the master Deferred 12445 master = jQuery.Deferred(), 12446 12447 // subordinate callback factory 12448 updateFunc = function( i ) { 12449 return function( value ) { 12450 resolveContexts[ i ] = this; 12451 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 12452 if ( !( --remaining ) ) { 12453 master.resolveWith( resolveContexts, resolveValues ); 12454 } 12455 }; 12456 }; 12457 12458 // Single- and empty arguments are adopted like Promise.resolve 12459 if ( remaining <= 1 ) { 12460 adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, 12461 !remaining ); 12462 12463 // Use .then() to unwrap secondary thenables (cf. gh-3000) 12464 if ( master.state() === "pending" || 12465 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 12466 12467 return master.then(); 12468 } 12469 } 12470 12471 // Multiple arguments are aggregated like Promise.all array elements 12472 while ( i-- ) { 12473 adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); 12474 } 12475 12476 return master.promise(); 12477 } 12478} ); 12479 12480 12481// These usually indicate a programmer mistake during development, 12482// warn about them ASAP rather than swallowing them by default. 12483var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 12484 12485jQuery.Deferred.exceptionHook = function( error, stack ) { 12486 12487 // Support: IE 8 - 9 only 12488 // Console exists when dev tools are open, which can happen at any time 12489 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 12490 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); 12491 } 12492}; 12493 12494 12495 12496 12497jQuery.readyException = function( error ) { 12498 window.setTimeout( function() { 12499 throw error; 12500 } ); 12501}; 12502 12503 12504 12505 12506// The deferred used on DOM ready 12507var readyList = jQuery.Deferred(); 12508 12509jQuery.fn.ready = function( fn ) { 12510 12511 readyList 12512 .then( fn ) 12513 12514 // Wrap jQuery.readyException in a function so that the lookup 12515 // happens at the time of error handling instead of callback 12516 // registration. 12517 .catch( function( error ) { 12518 jQuery.readyException( error ); 12519 } ); 12520 12521 return this; 12522}; 12523 12524jQuery.extend( { 12525 12526 // Is the DOM ready to be used? Set to true once it occurs. 12527 isReady: false, 12528 12529 // A counter to track how many items to wait for before 12530 // the ready event fires. See #6781 12531 readyWait: 1, 12532 12533 // Handle when the DOM is ready 12534 ready: function( wait ) { 12535 12536 // Abort if there are pending holds or we're already ready 12537 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 12538 return; 12539 } 12540 12541 // Remember that the DOM is ready 12542 jQuery.isReady = true; 12543 12544 // If a normal DOM Ready event fired, decrement, and wait if need be 12545 if ( wait !== true && --jQuery.readyWait > 0 ) { 12546 return; 12547 } 12548 12549 // If there are functions bound, to execute 12550 readyList.resolveWith( document, [ jQuery ] ); 12551 } 12552} ); 12553 12554jQuery.ready.then = readyList.then; 12555 12556// The ready event handler and self cleanup method 12557function completed() { 12558 document.removeEventListener( "DOMContentLoaded", completed ); 12559 window.removeEventListener( "load", completed ); 12560 jQuery.ready(); 12561} 12562 12563// Catch cases where $(document).ready() is called 12564// after the browser event has already occurred. 12565// Support: IE <=9 - 10 only 12566// Older IE sometimes signals "interactive" too soon 12567if ( document.readyState === "complete" || 12568 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 12569 12570 // Handle it asynchronously to allow scripts the opportunity to delay ready 12571 window.setTimeout( jQuery.ready ); 12572 12573} else { 12574 12575 // Use the handy event callback 12576 document.addEventListener( "DOMContentLoaded", completed ); 12577 12578 // A fallback to window.onload, that will always work 12579 window.addEventListener( "load", completed ); 12580} 12581 12582 12583 12584 12585// Multifunctional method to get and set values of a collection 12586// The value/s can optionally be executed if it's a function 12587var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 12588 var i = 0, 12589 len = elems.length, 12590 bulk = key == null; 12591 12592 // Sets many values 12593 if ( toType( key ) === "object" ) { 12594 chainable = true; 12595 for ( i in key ) { 12596 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 12597 } 12598 12599 // Sets one value 12600 } else if ( value !== undefined ) { 12601 chainable = true; 12602 12603 if ( !isFunction( value ) ) { 12604 raw = true; 12605 } 12606 12607 if ( bulk ) { 12608 12609 // Bulk operations run against the entire set 12610 if ( raw ) { 12611 fn.call( elems, value ); 12612 fn = null; 12613 12614 // ...except when executing function values 12615 } else { 12616 bulk = fn; 12617 fn = function( elem, key, value ) { 12618 return bulk.call( jQuery( elem ), value ); 12619 }; 12620 } 12621 } 12622 12623 if ( fn ) { 12624 for ( ; i < len; i++ ) { 12625 fn( 12626 elems[ i ], key, raw ? 12627 value : 12628 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 12629 ); 12630 } 12631 } 12632 } 12633 12634 if ( chainable ) { 12635 return elems; 12636 } 12637 12638 // Gets 12639 if ( bulk ) { 12640 return fn.call( elems ); 12641 } 12642 12643 return len ? fn( elems[ 0 ], key ) : emptyGet; 12644}; 12645 12646 12647// Matches dashed string for camelizing 12648var rmsPrefix = /^-ms-/, 12649 rdashAlpha = /-([a-z])/g; 12650 12651// Used by camelCase as callback to replace() 12652function fcamelCase( all, letter ) { 12653 return letter.toUpperCase(); 12654} 12655 12656// Convert dashed to camelCase; used by the css and data modules 12657// Support: IE <=9 - 11, Edge 12 - 15 12658// Microsoft forgot to hump their vendor prefix (#9572) 12659function camelCase( string ) { 12660 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 12661} 12662var acceptData = function( owner ) { 12663 12664 // Accepts only: 12665 // - Node 12666 // - Node.ELEMENT_NODE 12667 // - Node.DOCUMENT_NODE 12668 // - Object 12669 // - Any 12670 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 12671}; 12672 12673 12674 12675 12676function Data() { 12677 this.expando = jQuery.expando + Data.uid++; 12678} 12679 12680Data.uid = 1; 12681 12682Data.prototype = { 12683 12684 cache: function( owner ) { 12685 12686 // Check if the owner object already has a cache 12687 var value = owner[ this.expando ]; 12688 12689 // If not, create one 12690 if ( !value ) { 12691 value = {}; 12692 12693 // We can accept data for non-element nodes in modern browsers, 12694 // but we should not, see #8335. 12695 // Always return an empty object. 12696 if ( acceptData( owner ) ) { 12697 12698 // If it is a node unlikely to be stringify-ed or looped over 12699 // use plain assignment 12700 if ( owner.nodeType ) { 12701 owner[ this.expando ] = value; 12702 12703 // Otherwise secure it in a non-enumerable property 12704 // configurable must be true to allow the property to be 12705 // deleted when data is removed 12706 } else { 12707 Object.defineProperty( owner, this.expando, { 12708 value: value, 12709 configurable: true 12710 } ); 12711 } 12712 } 12713 } 12714 12715 return value; 12716 }, 12717 set: function( owner, data, value ) { 12718 var prop, 12719 cache = this.cache( owner ); 12720 12721 // Handle: [ owner, key, value ] args 12722 // Always use camelCase key (gh-2257) 12723 if ( typeof data === "string" ) { 12724 cache[ camelCase( data ) ] = value; 12725 12726 // Handle: [ owner, { properties } ] args 12727 } else { 12728 12729 // Copy the properties one-by-one to the cache object 12730 for ( prop in data ) { 12731 cache[ camelCase( prop ) ] = data[ prop ]; 12732 } 12733 } 12734 return cache; 12735 }, 12736 get: function( owner, key ) { 12737 return key === undefined ? 12738 this.cache( owner ) : 12739 12740 // Always use camelCase key (gh-2257) 12741 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 12742 }, 12743 access: function( owner, key, value ) { 12744 12745 // In cases where either: 12746 // 12747 // 1. No key was specified
vendor: 8,694 bytes, lines 12748-13106
12748 // 2. A string key was specified, but no value provided 12749 // 12750 // Take the "read" path and allow the get method to determine 12751 // which value to return, respectively either: 12752 // 12753 // 1. The entire cache object 12754 // 2. The data stored at the key 12755 // 12756 if ( key === undefined || 12757 ( ( key && typeof key === "string" ) && value === undefined ) ) { 12758 12759 return this.get( owner, key ); 12760 } 12761 12762 // When the key is not a string, or both a key and value 12763 // are specified, set or extend (existing objects) with either: 12764 // 12765 // 1. An object of properties 12766 // 2. A key and value 12767 // 12768 this.set( owner, key, value ); 12769 12770 // Since the "set" path can have two possible entry points 12771 // return the expected data based on which path was taken[*] 12772 return value !== undefined ? value : key; 12773 }, 12774 remove: function( owner, key ) { 12775 var i, 12776 cache = owner[ this.expando ]; 12777 12778 if ( cache === undefined ) { 12779 return; 12780 } 12781 12782 if ( key !== undefined ) { 12783 12784 // Support array or space separated string of keys 12785 if ( Array.isArray( key ) ) { 12786 12787 // If key is an array of keys... 12788 // We always set camelCase keys, so remove that. 12789 key = key.map( camelCase ); 12790 } else { 12791 key = camelCase( key ); 12792 12793 // If a key with the spaces exists, use it. 12794 // Otherwise, create an array by matching non-whitespace 12795 key = key in cache ? 12796 [ key ] : 12797 ( key.match( rnothtmlwhite ) || [] ); 12798 } 12799 12800 i = key.length; 12801 12802 while ( i-- ) { 12803 delete cache[ key[ i ] ]; 12804 } 12805 } 12806 12807 // Remove the expando if there's no more data 12808 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 12809 12810 // Support: Chrome <=35 - 45 12811 // Webkit & Blink performance suffers when deleting properties 12812 // from DOM nodes, so set to undefined instead 12813 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 12814 if ( owner.nodeType ) { 12815 owner[ this.expando ] = undefined; 12816 } else { 12817 delete owner[ this.expando ]; 12818 } 12819 } 12820 }, 12821 hasData: function( owner ) { 12822 var cache = owner[ this.expando ]; 12823 return cache !== undefined && !jQuery.isEmptyObject( cache ); 12824 } 12825}; 12826var dataPriv = new Data(); 12827 12828var dataUser = new Data(); 12829 12830 12831 12832// Implementation Summary 12833// 12834// 1. Enforce API surface and semantic compatibility with 1.9.x branch 12835// 2. Improve the module's maintainability by reducing the storage 12836// paths to a single mechanism. 12837// 3. Use the same single mechanism to support "private" and "user" data. 12838// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 12839// 5. Avoid exposing implementation details on user objects (eg. expando properties) 12840// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 12841 12842var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 12843 rmultiDash = /[A-Z]/g; 12844 12845function getData( data ) { 12846 if ( data === "true" ) { 12847 return true; 12848 } 12849 12850 if ( data === "false" ) { 12851 return false; 12852 } 12853 12854 if ( data === "null" ) { 12855 return null; 12856 } 12857 12858 // Only convert to a number if it doesn't change the string 12859 if ( data === +data + "" ) { 12860 return +data; 12861 } 12862 12863 if ( rbrace.test( data ) ) { 12864 return JSON.parse( data ); 12865 } 12866 12867 return data; 12868} 12869 12870function dataAttr( elem, key, data ) { 12871 var name; 12872 12873 // If nothing was found internally, try to fetch any 12874 // data from the HTML5 data-* attribute 12875 if ( data === undefined && elem.nodeType === 1 ) { 12876 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 12877 data = elem.getAttribute( name ); 12878 12879 if ( typeof data === "string" ) { 12880 try { 12881 data = getData( data ); 12882 } catch ( e ) {} 12883 12884 // Make sure we set the data so it isn't changed later 12885 dataUser.set( elem, key, data ); 12886 } else { 12887 data = undefined; 12888 } 12889 } 12890 return data; 12891} 12892 12893jQuery.extend( { 12894 hasData: function( elem ) { 12895 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 12896 }, 12897 12898 data: function( elem, name, data ) { 12899 return dataUser.access( elem, name, data ); 12900 }, 12901 12902 removeData: function( elem, name ) { 12903 dataUser.remove( elem, name ); 12904 }, 12905 12906 // TODO: Now that all calls to _data and _removeData have been replaced 12907 // with direct calls to dataPriv methods, these can be deprecated. 12908 _data: function( elem, name, data ) { 12909 return dataPriv.access( elem, name, data ); 12910 }, 12911 12912 _removeData: function( elem, name ) { 12913 dataPriv.remove( elem, name ); 12914 } 12915} ); 12916 12917jQuery.fn.extend( { 12918 data: function( key, value ) { 12919 var i, name, data, 12920 elem = this[ 0 ], 12921 attrs = elem && elem.attributes; 12922 12923 // Gets all values 12924 if ( key === undefined ) { 12925 if ( this.length ) { 12926 data = dataUser.get( elem ); 12927 12928 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 12929 i = attrs.length; 12930 while ( i-- ) { 12931 12932 // Support: IE 11 only 12933 // The attrs elements can be null (#14894) 12934 if ( attrs[ i ] ) { 12935 name = attrs[ i ].name; 12936 if ( name.indexOf( "data-" ) === 0 ) { 12937 name = camelCase( name.slice( 5 ) ); 12938 dataAttr( elem, name, data[ name ] ); 12939 } 12940 } 12941 } 12942 dataPriv.set( elem, "hasDataAttrs", true ); 12943 } 12944 } 12945 12946 return data; 12947 } 12948 12949 // Sets multiple values 12950 if ( typeof key === "object" ) { 12951 return this.each( function() { 12952 dataUser.set( this, key ); 12953 } ); 12954 } 12955 12956 return access( this, function( value ) { 12957 var data; 12958 12959 // The calling jQuery object (element matches) is not empty 12960 // (and therefore has an element appears at this[ 0 ]) and the 12961 // `value` parameter was not undefined. An empty jQuery object 12962 // will result in `undefined` for elem = this[ 0 ] which will 12963 // throw an exception if an attempt to read a data cache is made. 12964 if ( elem && value === undefined ) { 12965 12966 // Attempt to get data from the cache 12967 // The key will always be camelCased in Data 12968 data = dataUser.get( elem, key ); 12969 if ( data !== undefined ) { 12970 return data; 12971 } 12972 12973 // Attempt to "discover" the data in 12974 // HTML5 custom data-* attrs 12975 data = dataAttr( elem, key ); 12976 if ( data !== undefined ) { 12977 return data; 12978 } 12979 12980 // We tried really hard, but the data doesn't exist. 12981 return; 12982 } 12983 12984 // Set the data... 12985 this.each( function() { 12986 12987 // We always store the camelCased key 12988 dataUser.set( this, key, value ); 12989 } ); 12990 }, null, value, arguments.length > 1, null, true ); 12991 }, 12992 12993 removeData: function( key ) { 12994 return this.each( function() { 12995 dataUser.remove( this, key ); 12996 } ); 12997 } 12998} ); 12999 13000 13001jQuery.extend( { 13002 queue: function( elem, type, data ) { 13003 var queue; 13004 13005 if ( elem ) { 13006 type = ( type || "fx" ) + "queue"; 13007 queue = dataPriv.get( elem, type ); 13008 13009 // Speed up dequeue by getting out quickly if this is just a lookup 13010 if ( data ) { 13011 if ( !queue || Array.isArray( data ) ) { 13012 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 13013 } else { 13014 queue.push( data ); 13015 } 13016 } 13017 return queue || []; 13018 } 13019 }, 13020 13021 dequeue: function( elem, type ) { 13022 type = type || "fx"; 13023 13024 var queue = jQuery.queue( elem, type ), 13025 startLength = queue.length, 13026 fn = queue.shift(), 13027 hooks = jQuery._queueHooks( elem, type ), 13028 next = function() { 13029 jQuery.dequeue( elem, type ); 13030 }; 13031 13032 // If the fx queue is dequeued, always remove the progress sentinel 13033 if ( fn === "inprogress" ) { 13034 fn = queue.shift(); 13035 startLength--; 13036 } 13037 13038 if ( fn ) { 13039 13040 // Add a progress sentinel to prevent the fx queue from being 13041 // automatically dequeued 13042 if ( type === "fx" ) { 13043 queue.unshift( "inprogress" ); 13044 } 13045 13046 // Clear up the last queue stop function 13047 delete hooks.stop; 13048 fn.call( elem, next, hooks ); 13049 } 13050 13051 if ( !startLength && hooks ) { 13052 hooks.empty.fire(); 13053 } 13054 }, 13055 13056 // Not public - generate a queueHooks object, or return the current one 13057 _queueHooks: function( elem, type ) { 13058 var key = type + "queueHooks"; 13059 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 13060 empty: jQuery.Callbacks( "once memory" ).add( function() { 13061 dataPriv.remove( elem, [ type + "queue", key ] ); 13062 } ) 13063 } ); 13064 } 13065} ); 13066 13067jQuery.fn.extend( { 13068 queue: function( type, data ) { 13069 var setter = 2; 13070 13071 if ( typeof type !== "string" ) { 13072 data = type; 13073 type = "fx"; 13074 setter--; 13075 } 13076 13077 if ( arguments.length < setter ) { 13078 return jQuery.queue( this[ 0 ], type ); 13079 } 13080 13081 return data === undefined ? 13082 this : 13083 this.each( function() { 13084 var queue = jQuery.queue( this, type, data ); 13085 13086 // Ensure a hooks for this queue 13087 jQuery._queueHooks( this, type ); 13088 13089 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 13090 jQuery.dequeue( this, type ); 13091 } 13092 } ); 13093 }, 13094 dequeue: function( type ) { 13095 return this.each( function() { 13096 jQuery.dequeue( this, type ); 13097 } ); 13098 }, 13099 clearQueue: function( type ) { 13100 return this.queue( type || "fx", [] ); 13101 }, 13102 13103 // Get a promise resolved when queues of a certain type 13104 // are emptied (fx is the type by default) 13105 promise: function( type, obj ) { 13106 var tmp,
vendor: 37,137 bytes, lines 13107-14532
13107 count = 1, 13108 defer = jQuery.Deferred(), 13109 elements = this, 13110 i = this.length, 13111 resolve = function() { 13112 if ( !( --count ) ) { 13113 defer.resolveWith( elements, [ elements ] ); 13114 } 13115 }; 13116 13117 if ( typeof type !== "string" ) { 13118 obj = type; 13119 type = undefined; 13120 } 13121 type = type || "fx"; 13122 13123 while ( i-- ) { 13124 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 13125 if ( tmp && tmp.empty ) { 13126 count++; 13127 tmp.empty.add( resolve ); 13128 } 13129 } 13130 resolve(); 13131 return defer.promise( obj ); 13132 } 13133} ); 13134var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 13135 13136var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 13137 13138 13139var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 13140 13141var isHiddenWithinTree = function( elem, el ) { 13142 13143 // isHiddenWithinTree might be called from jQuery#filter function; 13144 // in that case, element will be second argument 13145 elem = el || elem; 13146 13147 // Inline style trumps all 13148 return elem.style.display === "none" || 13149 elem.style.display === "" && 13150 13151 // Otherwise, check computed style 13152 // Support: Firefox <=43 - 45 13153 // Disconnected elements can have computed display: none, so first confirm that elem is 13154 // in the document. 13155 jQuery.contains( elem.ownerDocument, elem ) && 13156 13157 jQuery.css( elem, "display" ) === "none"; 13158 }; 13159 13160var swap = function( elem, options, callback, args ) { 13161 var ret, name, 13162 old = {}; 13163 13164 // Remember the old values, and insert the new ones 13165 for ( name in options ) { 13166 old[ name ] = elem.style[ name ]; 13167 elem.style[ name ] = options[ name ]; 13168 } 13169 13170 ret = callback.apply( elem, args || [] ); 13171 13172 // Revert the old values 13173 for ( name in options ) { 13174 elem.style[ name ] = old[ name ]; 13175 } 13176 13177 return ret; 13178}; 13179 13180 13181 13182 13183function adjustCSS( elem, prop, valueParts, tween ) { 13184 var adjusted, scale, 13185 maxIterations = 20, 13186 currentValue = tween ? 13187 function() { 13188 return tween.cur(); 13189 } : 13190 function() { 13191 return jQuery.css( elem, prop, "" ); 13192 }, 13193 initial = currentValue(), 13194 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 13195 13196 // Starting value computation is required for potential unit mismatches 13197 initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 13198 rcssNum.exec( jQuery.css( elem, prop ) ); 13199 13200 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 13201 13202 // Support: Firefox <=54 13203 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 13204 initial = initial / 2; 13205 13206 // Trust units reported by jQuery.css 13207 unit = unit || initialInUnit[ 3 ]; 13208 13209 // Iteratively approximate from a nonzero starting point 13210 initialInUnit = +initial || 1; 13211 13212 while ( maxIterations-- ) { 13213 13214 // Evaluate and update our best guess (doubling guesses that zero out). 13215 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 13216 jQuery.style( elem, prop, initialInUnit + unit ); 13217 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 13218 maxIterations = 0; 13219 } 13220 initialInUnit = initialInUnit / scale; 13221 13222 } 13223 13224 initialInUnit = initialInUnit * 2; 13225 jQuery.style( elem, prop, initialInUnit + unit ); 13226 13227 // Make sure we update the tween properties later on 13228 valueParts = valueParts || []; 13229 } 13230 13231 if ( valueParts ) { 13232 initialInUnit = +initialInUnit || +initial || 0; 13233 13234 // Apply relative offset (+=/-=) if specified 13235 adjusted = valueParts[ 1 ] ? 13236 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 13237 +valueParts[ 2 ]; 13238 if ( tween ) { 13239 tween.unit = unit; 13240 tween.start = initialInUnit; 13241 tween.end = adjusted; 13242 } 13243 } 13244 return adjusted; 13245} 13246 13247 13248var defaultDisplayMap = {}; 13249 13250function getDefaultDisplay( elem ) { 13251 var temp, 13252 doc = elem.ownerDocument, 13253 nodeName = elem.nodeName, 13254 display = defaultDisplayMap[ nodeName ]; 13255 13256 if ( display ) { 13257 return display; 13258 } 13259 13260 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 13261 display = jQuery.css( temp, "display" ); 13262 13263 temp.parentNode.removeChild( temp ); 13264 13265 if ( display === "none" ) { 13266 display = "block"; 13267 } 13268 defaultDisplayMap[ nodeName ] = display; 13269 13270 return display; 13271} 13272 13273function showHide( elements, show ) { 13274 var display, elem, 13275 values = [], 13276 index = 0, 13277 length = elements.length; 13278 13279 // Determine new display value for elements that need to change 13280 for ( ; index < length; index++ ) { 13281 elem = elements[ index ]; 13282 if ( !elem.style ) { 13283 continue; 13284 } 13285 13286 display = elem.style.display; 13287 if ( show ) { 13288 13289 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 13290 // check is required in this first loop unless we have a nonempty display value (either 13291 // inline or about-to-be-restored) 13292 if ( display === "none" ) { 13293 values[ index ] = dataPriv.get( elem, "display" ) || null; 13294 if ( !values[ index ] ) { 13295 elem.style.display = ""; 13296 } 13297 } 13298 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 13299 values[ index ] = getDefaultDisplay( elem ); 13300 } 13301 } else { 13302 if ( display !== "none" ) { 13303 values[ index ] = "none"; 13304 13305 // Remember what we're overwriting 13306 dataPriv.set( elem, "display", display ); 13307 } 13308 } 13309 } 13310 13311 // Set the display of the elements in a second loop to avoid constant reflow 13312 for ( index = 0; index < length; index++ ) { 13313 if ( values[ index ] != null ) { 13314 elements[ index ].style.display = values[ index ]; 13315 } 13316 } 13317 13318 return elements; 13319} 13320 13321jQuery.fn.extend( { 13322 show: function() { 13323 return showHide( this, true ); 13324 }, 13325 hide: function() { 13326 return showHide( this ); 13327 }, 13328 toggle: function( state ) { 13329 if ( typeof state === "boolean" ) { 13330 return state ? this.show() : this.hide(); 13331 } 13332 13333 return this.each( function() { 13334 if ( isHiddenWithinTree( this ) ) { 13335 jQuery( this ).show(); 13336 } else { 13337 jQuery( this ).hide(); 13338 } 13339 } ); 13340 } 13341} ); 13342var rcheckableType = ( /^(?:checkbox|radio)$/i ); 13343 13344var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); 13345 13346var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 13347 13348 13349 13350// We have to close these tags to support XHTML (#13200) 13351var wrapMap = { 13352 13353 // Support: IE <=9 only 13354 option: [ 1, "<select multiple='multiple'>", "</select>" ], 13355 13356 // XHTML parsers do not magically insert elements in the 13357 // same way that tag soup parsers do. So we cannot shorten 13358 // this by omitting <tbody> or other required elements. 13359 thead: [ 1, "<table>", "</table>" ], 13360 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 13361 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 13362 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 13363 13364 _default: [ 0, "", "" ] 13365}; 13366 13367// Support: IE <=9 only 13368wrapMap.optgroup = wrapMap.option; 13369 13370wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 13371wrapMap.th = wrapMap.td; 13372 13373 13374function getAll( context, tag ) { 13375 13376 // Support: IE <=9 - 11 only 13377 // Use typeof to avoid zero-argument method invocation on host objects (#15151) 13378 var ret; 13379 13380 if ( typeof context.getElementsByTagName !== "undefined" ) { 13381 ret = context.getElementsByTagName( tag || "*" ); 13382 13383 } else if ( typeof context.querySelectorAll !== "undefined" ) { 13384 ret = context.querySelectorAll( tag || "*" ); 13385 13386 } else { 13387 ret = []; 13388 } 13389 13390 if ( tag === undefined || tag && nodeName( context, tag ) ) { 13391 return jQuery.merge( [ context ], ret ); 13392 } 13393 13394 return ret; 13395} 13396 13397 13398// Mark scripts as having already been evaluated 13399function setGlobalEval( elems, refElements ) { 13400 var i = 0, 13401 l = elems.length; 13402 13403 for ( ; i < l; i++ ) { 13404 dataPriv.set( 13405 elems[ i ], 13406 "globalEval", 13407 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 13408 ); 13409 } 13410} 13411 13412 13413var rhtml = /<|&#?\w+;/; 13414 13415function buildFragment( elems, context, scripts, selection, ignored ) { 13416 var elem, tmp, tag, wrap, contains, j, 13417 fragment = context.createDocumentFragment(), 13418 nodes = [], 13419 i = 0, 13420 l = elems.length; 13421 13422 for ( ; i < l; i++ ) { 13423 elem = elems[ i ]; 13424 13425 if ( elem || elem === 0 ) { 13426 13427 // Add nodes directly 13428 if ( toType( elem ) === "object" ) { 13429 13430 // Support: Android <=4.0 only, PhantomJS 1 only 13431 // push.apply(_, arraylike) throws on ancient WebKit 13432 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 13433 13434 // Convert non-html into a text node 13435 } else if ( !rhtml.test( elem ) ) { 13436 nodes.push( context.createTextNode( elem ) ); 13437 13438 // Convert html into DOM nodes 13439 } else { 13440 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 13441 13442 // Deserialize a standard representation 13443 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 13444 wrap = wrapMap[ tag ] || wrapMap._default; 13445 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 13446 13447 // Descend through wrappers to the right content 13448 j = wrap[ 0 ]; 13449 while ( j-- ) { 13450 tmp = tmp.lastChild; 13451 } 13452 13453 // Support: Android <=4.0 only, PhantomJS 1 only 13454 // push.apply(_, arraylike) throws on ancient WebKit 13455 jQuery.merge( nodes, tmp.childNodes ); 13456 13457 // Remember the top-level container 13458 tmp = fragment.firstChild; 13459 13460 // Ensure the created nodes are orphaned (#12392) 13461 tmp.textContent = ""; 13462 } 13463 } 13464 } 13465 13466 // Remove wrapper from fragment 13467 fragment.textContent = ""; 13468 13469 i = 0; 13470 while ( ( elem = nodes[ i++ ] ) ) { 13471 13472 // Skip elements already in the context collection (trac-4087) 13473 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 13474 if ( ignored ) { 13475 ignored.push( elem ); 13476 } 13477 continue; 13478 } 13479 13480 contains = jQuery.contains( elem.ownerDocument, elem ); 13481 13482 // Append to fragment 13483 tmp = getAll( fragment.appendChild( elem ), "script" ); 13484 13485 // Preserve script evaluation history 13486 if ( contains ) { 13487 setGlobalEval( tmp ); 13488 } 13489 13490 // Capture executables 13491 if ( scripts ) { 13492 j = 0; 13493 while ( ( elem = tmp[ j++ ] ) ) { 13494 if ( rscriptType.test( elem.type || "" ) ) { 13495 scripts.push( elem ); 13496 } 13497 } 13498 } 13499 } 13500 13501 return fragment; 13502} 13503 13504 13505( function() { 13506 var fragment = document.createDocumentFragment(), 13507 div = fragment.appendChild( document.createElement( "div" ) ), 13508 input = document.createElement( "input" ); 13509 13510 // Support: Android 4.0 - 4.3 only 13511 // Check state lost if the name is set (#11217) 13512 // Support: Windows Web Apps (WWA) 13513 // `name` and `type` must use .setAttribute for WWA (#14901) 13514 input.setAttribute( "type", "radio" ); 13515 input.setAttribute( "checked", "checked" ); 13516 input.setAttribute( "name", "t" ); 13517 13518 div.appendChild( input ); 13519 13520 // Support: Android <=4.1 only 13521 // Older WebKit doesn't clone checked state correctly in fragments 13522 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 13523 13524 // Support: IE <=11 only 13525 // Make sure textarea (and checkbox) defaultValue is properly cloned 13526 div.innerHTML = "<textarea>x</textarea>"; 13527 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 13528} )(); 13529var documentElement = document.documentElement; 13530 13531 13532 13533var 13534 rkeyEvent = /^key/, 13535 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, 13536 rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 13537 13538function returnTrue() { 13539 return true; 13540} 13541 13542function returnFalse() { 13543 return false; 13544} 13545 13546// Support: IE <=9 only 13547// See #13393 for more info 13548function safeActiveElement() { 13549 try { 13550 return document.activeElement; 13551 } catch ( err ) { } 13552} 13553 13554function on( elem, types, selector, data, fn, one ) { 13555 var origFn, type; 13556 13557 // Types can be a map of types/handlers 13558 if ( typeof types === "object" ) { 13559 13560 // ( types-Object, selector, data ) 13561 if ( typeof selector !== "string" ) { 13562 13563 // ( types-Object, data ) 13564 data = data || selector; 13565 selector = undefined; 13566 } 13567 for ( type in types ) { 13568 on( elem, type, selector, data, types[ type ], one ); 13569 } 13570 return elem; 13571 } 13572 13573 if ( data == null && fn == null ) { 13574 13575 // ( types, fn ) 13576 fn = selector; 13577 data = selector = undefined; 13578 } else if ( fn == null ) { 13579 if ( typeof selector === "string" ) { 13580 13581 // ( types, selector, fn ) 13582 fn = data; 13583 data = undefined; 13584 } else { 13585 13586 // ( types, data, fn ) 13587 fn = data; 13588 data = selector; 13589 selector = undefined; 13590 } 13591 } 13592 if ( fn === false ) { 13593 fn = returnFalse; 13594 } else if ( !fn ) { 13595 return elem; 13596 } 13597 13598 if ( one === 1 ) { 13599 origFn = fn; 13600 fn = function( event ) { 13601 13602 // Can use an empty set, since event contains the info 13603 jQuery().off( event ); 13604 return origFn.apply( this, arguments ); 13605 }; 13606 13607 // Use same guid so caller can remove using origFn 13608 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 13609 } 13610 return elem.each( function() { 13611 jQuery.event.add( this, types, fn, data, selector ); 13612 } ); 13613} 13614 13615/* 13616 * Helper functions for managing events -- not part of the public interface. 13617 * Props to Dean Edwards' addEvent library for many of the ideas. 13618 */ 13619jQuery.event = { 13620 13621 global: {}, 13622 13623 add: function( elem, types, handler, data, selector ) { 13624 13625 var handleObjIn, eventHandle, tmp, 13626 events, t, handleObj, 13627 special, handlers, type, namespaces, origType, 13628 elemData = dataPriv.get( elem ); 13629 13630 // Don't attach events to noData or text/comment nodes (but allow plain objects) 13631 if ( !elemData ) { 13632 return; 13633 } 13634 13635 // Caller can pass in an object of custom data in lieu of the handler 13636 if ( handler.handler ) { 13637 handleObjIn = handler; 13638 handler = handleObjIn.handler; 13639 selector = handleObjIn.selector; 13640 } 13641 13642 // Ensure that invalid selectors throw exceptions at attach time 13643 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 13644 if ( selector ) { 13645 jQuery.find.matchesSelector( documentElement, selector ); 13646 } 13647 13648 // Make sure that the handler has a unique ID, used to find/remove it later 13649 if ( !handler.guid ) { 13650 handler.guid = jQuery.guid++; 13651 } 13652 13653 // Init the element's event structure and main handler, if this is the first 13654 if ( !( events = elemData.events ) ) { 13655 events = elemData.events = {}; 13656 } 13657 if ( !( eventHandle = elemData.handle ) ) { 13658 eventHandle = elemData.handle = function( e ) { 13659 13660 // Discard the second event of a jQuery.event.trigger() and 13661 // when an event is called after a page has unloaded 13662 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 13663 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 13664 }; 13665 } 13666 13667 // Handle multiple events separated by a space 13668 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 13669 t = types.length; 13670 while ( t-- ) { 13671 tmp = rtypenamespace.exec( types[ t ] ) || []; 13672 type = origType = tmp[ 1 ]; 13673 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 13674 13675 // There *must* be a type, no attaching namespace-only handlers 13676 if ( !type ) { 13677 continue; 13678 } 13679 13680 // If event changes its type, use the special event handlers for the changed type 13681 special = jQuery.event.special[ type ] || {}; 13682 13683 // If selector defined, determine special event api type, otherwise given type 13684 type = ( selector ? special.delegateType : special.bindType ) || type; 13685 13686 // Update special based on newly reset type 13687 special = jQuery.event.special[ type ] || {}; 13688 13689 // handleObj is passed to all event handlers 13690 handleObj = jQuery.extend( { 13691 type: type, 13692 origType: origType, 13693 data: data, 13694 handler: handler, 13695 guid: handler.guid, 13696 selector: selector, 13697 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 13698 namespace: namespaces.join( "." ) 13699 }, handleObjIn ); 13700 13701 // Init the event handler queue if we're the first 13702 if ( !( handlers = events[ type ] ) ) { 13703 handlers = events[ type ] = []; 13704 handlers.delegateCount = 0; 13705 13706 // Only use addEventListener if the special events handler returns false 13707 if ( !special.setup || 13708 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 13709 13710 if ( elem.addEventListener ) { 13711 elem.addEventListener( type, eventHandle ); 13712 } 13713 } 13714 } 13715 13716 if ( special.add ) { 13717 special.add.call( elem, handleObj ); 13718 13719 if ( !handleObj.handler.guid ) { 13720 handleObj.handler.guid = handler.guid; 13721 } 13722 } 13723 13724 // Add to the element's handler list, delegates in front 13725 if ( selector ) { 13726 handlers.splice( handlers.delegateCount++, 0, handleObj ); 13727 } else { 13728 handlers.push( handleObj ); 13729 } 13730 13731 // Keep track of which events have ever been used, for event optimization 13732 jQuery.event.global[ type ] = true; 13733 } 13734 13735 }, 13736 13737 // Detach an event or set of events from an element 13738 remove: function( elem, types, handler, selector, mappedTypes ) { 13739 13740 var j, origCount, tmp, 13741 events, t, handleObj, 13742 special, handlers, type, namespaces, origType, 13743 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 13744 13745 if ( !elemData || !( events = elemData.events ) ) { 13746 return; 13747 } 13748 13749 // Once for each type.namespace in types; type may be omitted 13750 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 13751 t = types.length; 13752 while ( t-- ) { 13753 tmp = rtypenamespace.exec( types[ t ] ) || []; 13754 type = origType = tmp[ 1 ]; 13755 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 13756 13757 // Unbind all events (on this namespace, if provided) for the element 13758 if ( !type ) { 13759 for ( type in events ) { 13760 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 13761 } 13762 continue; 13763 } 13764 13765 special = jQuery.event.special[ type ] || {}; 13766 type = ( selector ? special.delegateType : special.bindType ) || type; 13767 handlers = events[ type ] || []; 13768 tmp = tmp[ 2 ] && 13769 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 13770 13771 // Remove matching events 13772 origCount = j = handlers.length; 13773 while ( j-- ) { 13774 handleObj = handlers[ j ]; 13775 13776 if ( ( mappedTypes || origType === handleObj.origType ) && 13777 ( !handler || handler.guid === handleObj.guid ) && 13778 ( !tmp || tmp.test( handleObj.namespace ) ) && 13779 ( !selector || selector === handleObj.selector || 13780 selector === "**" && handleObj.selector ) ) { 13781 handlers.splice( j, 1 ); 13782 13783 if ( handleObj.selector ) { 13784 handlers.delegateCount--; 13785 } 13786 if ( special.remove ) { 13787 special.remove.call( elem, handleObj ); 13788 } 13789 } 13790 } 13791 13792 // Remove generic event handler if we removed something and no more handlers exist 13793 // (avoids potential for endless recursion during removal of special event handlers) 13794 if ( origCount && !handlers.length ) { 13795 if ( !special.teardown || 13796 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 13797 13798 jQuery.removeEvent( elem, type, elemData.handle ); 13799 } 13800 13801 delete events[ type ]; 13802 } 13803 } 13804 13805 // Remove data and the expando if it's no longer used 13806 if ( jQuery.isEmptyObject( events ) ) { 13807 dataPriv.remove( elem, "handle events" ); 13808 } 13809 }, 13810 13811 dispatch: function( nativeEvent ) { 13812 13813 // Make a writable jQuery.Event from the native event object 13814 var event = jQuery.event.fix( nativeEvent ); 13815 13816 var i, j, ret, matched, handleObj, handlerQueue, 13817 args = new Array( arguments.length ), 13818 handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], 13819 special = jQuery.event.special[ event.type ] || {}; 13820 13821 // Use the fix-ed jQuery.Event rather than the (read-only) native event 13822 args[ 0 ] = event; 13823 13824 for ( i = 1; i < arguments.length; i++ ) { 13825 args[ i ] = arguments[ i ]; 13826 } 13827 13828 event.delegateTarget = this; 13829 13830 // Call the preDispatch hook for the mapped type, and let it bail if desired 13831 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 13832 return; 13833 } 13834 13835 // Determine handlers 13836 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 13837 13838 // Run delegates first; they may want to stop propagation beneath us 13839 i = 0; 13840 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 13841 event.currentTarget = matched.elem; 13842 13843 j = 0; 13844 while ( ( handleObj = matched.handlers[ j++ ] ) && 13845 !event.isImmediatePropagationStopped() ) { 13846 13847 // Triggered event must either 1) have no namespace, or 2) have namespace(s) 13848 // a subset or equal to those in the bound event (both can have no namespace). 13849 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { 13850 13851 event.handleObj = handleObj; 13852 event.data = handleObj.data; 13853 13854 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 13855 handleObj.handler ).apply( matched.elem, args ); 13856 13857 if ( ret !== undefined ) { 13858 if ( ( event.result = ret ) === false ) { 13859 event.preventDefault(); 13860 event.stopPropagation(); 13861 } 13862 } 13863 } 13864 } 13865 } 13866 13867 // Call the postDispatch hook for the mapped type 13868 if ( special.postDispatch ) { 13869 special.postDispatch.call( this, event ); 13870 } 13871 13872 return event.result; 13873 }, 13874 13875 handlers: function( event, handlers ) { 13876 var i, handleObj, sel, matchedHandlers, matchedSelectors, 13877 handlerQueue = [], 13878 delegateCount = handlers.delegateCount, 13879 cur = event.target; 13880 13881 // Find delegate handlers 13882 if ( delegateCount && 13883 13884 // Support: IE <=9 13885 // Black-hole SVG <use> instance trees (trac-13180) 13886 cur.nodeType && 13887 13888 // Support: Firefox <=42 13889 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 13890 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 13891 // Support: IE 11 only 13892 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 13893 !( event.type === "click" && event.button >= 1 ) ) { 13894 13895 for ( ; cur !== this; cur = cur.parentNode || this ) { 13896 13897 // Don't check non-elements (#13208) 13898 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 13899 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 13900 matchedHandlers = []; 13901 matchedSelectors = {}; 13902 for ( i = 0; i < delegateCount; i++ ) { 13903 handleObj = handlers[ i ]; 13904 13905 // Don't conflict with Object.prototype properties (#13203) 13906 sel = handleObj.selector + " "; 13907 13908 if ( matchedSelectors[ sel ] === undefined ) { 13909 matchedSelectors[ sel ] = handleObj.needsContext ? 13910 jQuery( sel, this ).index( cur ) > -1 : 13911 jQuery.find( sel, this, null, [ cur ] ).length; 13912 } 13913 if ( matchedSelectors[ sel ] ) { 13914 matchedHandlers.push( handleObj ); 13915 } 13916 } 13917 if ( matchedHandlers.length ) { 13918 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 13919 } 13920 } 13921 } 13922 } 13923 13924 // Add the remaining (directly-bound) handlers 13925 cur = this; 13926 if ( delegateCount < handlers.length ) { 13927 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 13928 } 13929 13930 return handlerQueue; 13931 }, 13932 13933 addProp: function( name, hook ) { 13934 Object.defineProperty( jQuery.Event.prototype, name, { 13935 enumerable: true, 13936 configurable: true, 13937 13938 get: isFunction( hook ) ? 13939 function() { 13940 if ( this.originalEvent ) { 13941 return hook( this.originalEvent ); 13942 } 13943 } : 13944 function() { 13945 if ( this.originalEvent ) { 13946 return this.originalEvent[ name ]; 13947 } 13948 }, 13949 13950 set: function( value ) { 13951 Object.defineProperty( this, name, { 13952 enumerable: true, 13953 configurable: true, 13954 writable: true, 13955 value: value 13956 } ); 13957 } 13958 } ); 13959 }, 13960 13961 fix: function( originalEvent ) { 13962 return originalEvent[ jQuery.expando ] ? 13963 originalEvent : 13964 new jQuery.Event( originalEvent ); 13965 }, 13966 13967 special: { 13968 load: { 13969 13970 // Prevent triggered image.load events from bubbling to window.load 13971 noBubble: true 13972 }, 13973 focus: { 13974 13975 // Fire native event if possible so blur/focus sequence is correct 13976 trigger: function() { 13977 if ( this !== safeActiveElement() && this.focus ) { 13978 this.focus(); 13979 return false; 13980 } 13981 }, 13982 delegateType: "focusin" 13983 }, 13984 blur: { 13985 trigger: function() { 13986 if ( this === safeActiveElement() && this.blur ) { 13987 this.blur(); 13988 return false; 13989 } 13990 }, 13991 delegateType: "focusout" 13992 }, 13993 click: { 13994 13995 // For checkbox, fire native event so checked state will be right 13996 trigger: function() { 13997 if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { 13998 this.click(); 13999 return false; 14000 } 14001 }, 14002 14003 // For cross-browser consistency, don't fire native .click() on links 14004 _default: function( event ) { 14005 return nodeName( event.target, "a" ); 14006 } 14007 }, 14008 14009 beforeunload: { 14010 postDispatch: function( event ) { 14011 14012 // Support: Firefox 20+ 14013 // Firefox doesn't alert if the returnValue field is not set. 14014 if ( event.result !== undefined && event.originalEvent ) { 14015 event.originalEvent.returnValue = event.result; 14016 } 14017 } 14018 } 14019 } 14020}; 14021 14022jQuery.removeEvent = function( elem, type, handle ) { 14023 14024 // This "if" is needed for plain objects 14025 if ( elem.removeEventListener ) { 14026 elem.removeEventListener( type, handle ); 14027 } 14028}; 14029 14030jQuery.Event = function( src, props ) { 14031 14032 // Allow instantiation without the 'new' keyword 14033 if ( !( this instanceof jQuery.Event ) ) { 14034 return new jQuery.Event( src, props ); 14035 } 14036 14037 // Event object 14038 if ( src && src.type ) { 14039 this.originalEvent = src; 14040 this.type = src.type; 14041 14042 // Events bubbling up the document may have been marked as prevented 14043 // by a handler lower down the tree; reflect the correct value. 14044 this.isDefaultPrevented = src.defaultPrevented || 14045 src.defaultPrevented === undefined && 14046 14047 // Support: Android <=2.3 only 14048 src.returnValue === false ? 14049 returnTrue : 14050 returnFalse; 14051 14052 // Create target properties 14053 // Support: Safari <=6 - 7 only 14054 // Target should not be a text node (#504, #13143) 14055 this.target = ( src.target && src.target.nodeType === 3 ) ? 14056 src.target.parentNode : 14057 src.target; 14058 14059 this.currentTarget = src.currentTarget; 14060 this.relatedTarget = src.relatedTarget; 14061 14062 // Event type 14063 } else { 14064 this.type = src; 14065 } 14066 14067 // Put explicitly provided properties onto the event object 14068 if ( props ) { 14069 jQuery.extend( this, props ); 14070 } 14071 14072 // Create a timestamp if incoming event doesn't have one 14073 this.timeStamp = src && src.timeStamp || Date.now(); 14074 14075 // Mark it as fixed 14076 this[ jQuery.expando ] = true; 14077}; 14078 14079// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 14080// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 14081jQuery.Event.prototype = { 14082 constructor: jQuery.Event, 14083 isDefaultPrevented: returnFalse, 14084 isPropagationStopped: returnFalse, 14085 isImmediatePropagationStopped: returnFalse, 14086 isSimulated: false, 14087 14088 preventDefault: function() { 14089 var e = this.originalEvent; 14090 14091 this.isDefaultPrevented = returnTrue; 14092 14093 if ( e && !this.isSimulated ) { 14094 e.preventDefault(); 14095 } 14096 }, 14097 stopPropagation: function() { 14098 var e = this.originalEvent; 14099 14100 this.isPropagationStopped = returnTrue; 14101 14102 if ( e && !this.isSimulated ) { 14103 e.stopPropagation(); 14104 } 14105 }, 14106 stopImmediatePropagation: function() { 14107 var e = this.originalEvent; 14108 14109 this.isImmediatePropagationStopped = returnTrue; 14110 14111 if ( e && !this.isSimulated ) { 14112 e.stopImmediatePropagation(); 14113 } 14114 14115 this.stopPropagation(); 14116 } 14117}; 14118 14119// Includes all common event props including KeyEvent and MouseEvent specific props 14120jQuery.each( { 14121 altKey: true, 14122 bubbles: true, 14123 cancelable: true, 14124 changedTouches: true, 14125 ctrlKey: true, 14126 detail: true, 14127 eventPhase: true, 14128 metaKey: true, 14129 pageX: true, 14130 pageY: true, 14131 shiftKey: true, 14132 view: true, 14133 "char": true, 14134 charCode: true, 14135 key: true, 14136 keyCode: true, 14137 button: true, 14138 buttons: true, 14139 clientX: true, 14140 clientY: true, 14141 offsetX: true, 14142 offsetY: true, 14143 pointerId: true, 14144 pointerType: true, 14145 screenX: true, 14146 screenY: true, 14147 targetTouches: true, 14148 toElement: true, 14149 touches: true, 14150 14151 which: function( event ) { 14152 var button = event.button; 14153 14154 // Add which for key events 14155 if ( event.which == null && rkeyEvent.test( event.type ) ) { 14156 return event.charCode != null ? event.charCode : event.keyCode; 14157 } 14158 14159 // Add which for click: 1 === left; 2 === middle; 3 === right 14160 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { 14161 if ( button & 1 ) { 14162 return 1; 14163 } 14164 14165 if ( button & 2 ) { 14166 return 3; 14167 } 14168 14169 if ( button & 4 ) { 14170 return 2; 14171 } 14172 14173 return 0; 14174 } 14175 14176 return event.which; 14177 } 14178}, jQuery.event.addProp ); 14179 14180// Create mouseenter/leave events using mouseover/out and event-time checks 14181// so that event delegation works in jQuery. 14182// Do the same for pointerenter/pointerleave and pointerover/pointerout 14183// 14184// Support: Safari 7 only 14185// Safari sends mouseenter too often; see: 14186// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 14187// for the description of the bug (it existed in older Chrome versions as well). 14188jQuery.each( { 14189 mouseenter: "mouseover", 14190 mouseleave: "mouseout", 14191 pointerenter: "pointerover", 14192 pointerleave: "pointerout" 14193}, function( orig, fix ) { 14194 jQuery.event.special[ orig ] = { 14195 delegateType: fix, 14196 bindType: fix, 14197 14198 handle: function( event ) { 14199 var ret, 14200 target = this, 14201 related = event.relatedTarget, 14202 handleObj = event.handleObj; 14203 14204 // For mouseenter/leave call the handler if related is outside the target. 14205 // NB: No relatedTarget if the mouse left/entered the browser window 14206 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 14207 event.type = handleObj.origType; 14208 ret = handleObj.handler.apply( this, arguments ); 14209 event.type = fix; 14210 } 14211 return ret; 14212 } 14213 }; 14214} ); 14215 14216jQuery.fn.extend( { 14217 14218 on: function( types, selector, data, fn ) { 14219 return on( this, types, selector, data, fn ); 14220 }, 14221 one: function( types, selector, data, fn ) { 14222 return on( this, types, selector, data, fn, 1 ); 14223 }, 14224 off: function( types, selector, fn ) { 14225 var handleObj, type; 14226 if ( types && types.preventDefault && types.handleObj ) { 14227 14228 // ( event ) dispatched jQuery.Event 14229 handleObj = types.handleObj; 14230 jQuery( types.delegateTarget ).off( 14231 handleObj.namespace ? 14232 handleObj.origType + "." + handleObj.namespace : 14233 handleObj.origType, 14234 handleObj.selector, 14235 handleObj.handler 14236 ); 14237 return this; 14238 } 14239 if ( typeof types === "object" ) { 14240 14241 // ( types-object [, selector] ) 14242 for ( type in types ) { 14243 this.off( type, selector, types[ type ] ); 14244 } 14245 return this; 14246 } 14247 if ( selector === false || typeof selector === "function" ) { 14248 14249 // ( types [, fn] ) 14250 fn = selector; 14251 selector = undefined; 14252 } 14253 if ( fn === false ) { 14254 fn = returnFalse; 14255 } 14256 return this.each( function() { 14257 jQuery.event.remove( this, types, fn, selector ); 14258 } ); 14259 } 14260} ); 14261 14262 14263var 14264 14265 /* eslint-disable max-len */ 14266 14267 // See https://github.com/eslint/eslint/issues/3229 14268 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, 14269 14270 /* eslint-enable */ 14271 14272 // Support: IE <=10 - 11, Edge 12 - 13 only 14273 // In IE/Edge using regex groups here causes severe slowdowns. 14274 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 14275 rnoInnerhtml = /<script|<style|<link/i, 14276 14277 // checked="checked" or checked 14278 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 14279 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; 14280 14281// Prefer a tbody over its parent table for containing new rows 14282function manipulationTarget( elem, content ) { 14283 if ( nodeName( elem, "table" ) && 14284 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 14285 14286 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 14287 } 14288 14289 return elem; 14290} 14291 14292// Replace/restore the type attribute of script elements for safe DOM manipulation 14293function disableScript( elem ) { 14294 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 14295 return elem; 14296} 14297function restoreScript( elem ) { 14298 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 14299 elem.type = elem.type.slice( 5 ); 14300 } else { 14301 elem.removeAttribute( "type" ); 14302 } 14303 14304 return elem; 14305} 14306 14307function cloneCopyEvent( src, dest ) { 14308 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; 14309 14310 if ( dest.nodeType !== 1 ) { 14311 return; 14312 } 14313 14314 // 1. Copy private data: events, handlers, etc. 14315 if ( dataPriv.hasData( src ) ) { 14316 pdataOld = dataPriv.access( src ); 14317 pdataCur = dataPriv.set( dest, pdataOld ); 14318 events = pdataOld.events; 14319 14320 if ( events ) { 14321 delete pdataCur.handle; 14322 pdataCur.events = {}; 14323 14324 for ( type in events ) { 14325 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 14326 jQuery.event.add( dest, type, events[ type ][ i ] ); 14327 } 14328 } 14329 } 14330 } 14331 14332 // 2. Copy user data 14333 if ( dataUser.hasData( src ) ) { 14334 udataOld = dataUser.access( src ); 14335 udataCur = jQuery.extend( {}, udataOld ); 14336 14337 dataUser.set( dest, udataCur ); 14338 } 14339} 14340 14341// Fix IE bugs, see support tests 14342function fixInput( src, dest ) { 14343 var nodeName = dest.nodeName.toLowerCase(); 14344 14345 // Fails to persist the checked state of a cloned checkbox or radio button. 14346 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 14347 dest.checked = src.checked; 14348 14349 // Fails to return the selected option to the default selected state when cloning options 14350 } else if ( nodeName === "input" || nodeName === "textarea" ) { 14351 dest.defaultValue = src.defaultValue; 14352 } 14353} 14354 14355function domManip( collection, args, callback, ignored ) { 14356 14357 // Flatten any nested arrays 14358 args = concat.apply( [], args ); 14359 14360 var fragment, first, scripts, hasScripts, node, doc, 14361 i = 0, 14362 l = collection.length, 14363 iNoClone = l - 1, 14364 value = args[ 0 ], 14365 valueIsFunction = isFunction( value ); 14366 14367 // We can't cloneNode fragments that contain checked, in WebKit 14368 if ( valueIsFunction || 14369 ( l > 1 && typeof value === "string" && 14370 !support.checkClone && rchecked.test( value ) ) ) { 14371 return collection.each( function( index ) { 14372 var self = collection.eq( index ); 14373 if ( valueIsFunction ) { 14374 args[ 0 ] = value.call( this, index, self.html() ); 14375 } 14376 domManip( self, args, callback, ignored ); 14377 } ); 14378 } 14379 14380 if ( l ) { 14381 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 14382 first = fragment.firstChild; 14383 14384 if ( fragment.childNodes.length === 1 ) { 14385 fragment = first; 14386 } 14387 14388 // Require either new content or an interest in ignored elements to invoke the callback 14389 if ( first || ignored ) { 14390 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 14391 hasScripts = scripts.length; 14392 14393 // Use the original fragment for the last item 14394 // instead of the first because it can end up 14395 // being emptied incorrectly in certain situations (#8070). 14396 for ( ; i < l; i++ ) { 14397 node = fragment; 14398 14399 if ( i !== iNoClone ) { 14400 node = jQuery.clone( node, true, true ); 14401 14402 // Keep references to cloned scripts for later restoration 14403 if ( hasScripts ) { 14404 14405 // Support: Android <=4.0 only, PhantomJS 1 only 14406 // push.apply(_, arraylike) throws on ancient WebKit 14407 jQuery.merge( scripts, getAll( node, "script" ) ); 14408 } 14409 } 14410 14411 callback.call( collection[ i ], node, i ); 14412 } 14413 14414 if ( hasScripts ) { 14415 doc = scripts[ scripts.length - 1 ].ownerDocument; 14416 14417 // Reenable scripts 14418 jQuery.map( scripts, restoreScript ); 14419 14420 // Evaluate executable scripts on first document insertion 14421 for ( i = 0; i < hasScripts; i++ ) { 14422 node = scripts[ i ]; 14423 if ( rscriptType.test( node.type || "" ) && 14424 !dataPriv.access( node, "globalEval" ) && 14425 jQuery.contains( doc, node ) ) { 14426 14427 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 14428 14429 // Optional AJAX dependency, but won't run scripts if not present 14430 if ( jQuery._evalUrl ) { 14431 jQuery._evalUrl( node.src ); 14432 } 14433 } else { 14434 DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node ); 14435 } 14436 } 14437 } 14438 } 14439 } 14440 } 14441 14442 return collection; 14443} 14444 14445function remove( elem, selector, keepData ) { 14446 var node, 14447 nodes = selector ? jQuery.filter( selector, elem ) : elem, 14448 i = 0; 14449 14450 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 14451 if ( !keepData && node.nodeType === 1 ) { 14452 jQuery.cleanData( getAll( node ) ); 14453 } 14454 14455 if ( node.parentNode ) { 14456 if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { 14457 setGlobalEval( getAll( node, "script" ) ); 14458 } 14459 node.parentNode.removeChild( node ); 14460 } 14461 } 14462 14463 return elem; 14464} 14465 14466jQuery.extend( { 14467 htmlPrefilter: function( html ) { 14468 return html.replace( rxhtmlTag, "<$1></$2>" ); 14469 }, 14470 14471 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 14472 var i, l, srcElements, destElements, 14473 clone = elem.cloneNode( true ), 14474 inPage = jQuery.contains( elem.ownerDocument, elem ); 14475 14476 // Fix IE cloning issues 14477 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 14478 !jQuery.isXMLDoc( elem ) ) { 14479 14480 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 14481 destElements = getAll( clone ); 14482 srcElements = getAll( elem ); 14483 14484 for ( i = 0, l = srcElements.length; i < l; i++ ) { 14485 fixInput( srcElements[ i ], destElements[ i ] ); 14486 } 14487 } 14488 14489 // Copy the events from the original to the clone 14490 if ( dataAndEvents ) { 14491 if ( deepDataAndEvents ) { 14492 srcElements = srcElements || getAll( elem ); 14493 destElements = destElements || getAll( clone ); 14494 14495 for ( i = 0, l = srcElements.length; i < l; i++ ) { 14496 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 14497 } 14498 } else { 14499 cloneCopyEvent( elem, clone ); 14500 } 14501 } 14502 14503 // Preserve script evaluation history 14504 destElements = getAll( clone, "script" ); 14505 if ( destElements.length > 0 ) { 14506 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 14507 } 14508 14509 // Return the cloned set 14510 return clone; 14511 }, 14512 14513 cleanData: function( elems ) { 14514 var data, elem, type, 14515 special = jQuery.event.special, 14516 i = 0; 14517 14518 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 14519 if ( acceptData( elem ) ) { 14520 if ( ( data = elem[ dataPriv.expando ] ) ) { 14521 if ( data.events ) { 14522 for ( type in data.events ) { 14523 if ( special[ type ] ) { 14524 jQuery.event.remove( elem, type ); 14525 14526 // This is a shortcut to avoid jQuery.event.remove's overhead 14527 } else { 14528 jQuery.removeEvent( elem, type, data.handle ); 14529 } 14530 } 14531 } 14532
vendor: 1,119 bytes, lines 14533-14577
14533 // Support: Chrome <=35 - 45+ 14534 // Assign undefined instead of using delete, see Data#remove 14535 elem[ dataPriv.expando ] = undefined; 14536 } 14537 if ( elem[ dataUser.expando ] ) { 14538 14539 // Support: Chrome <=35 - 45+ 14540 // Assign undefined instead of using delete, see Data#remove 14541 elem[ dataUser.expando ] = undefined; 14542 } 14543 } 14544 } 14545 } 14546} ); 14547 14548jQuery.fn.extend( { 14549 detach: function( selector ) { 14550 return remove( this, selector, true ); 14551 }, 14552 14553 remove: function( selector ) { 14554 return remove( this, selector ); 14555 }, 14556 14557 text: function( value ) { 14558 return access( this, function( value ) { 14559 return value === undefined ? 14560 jQuery.text( this ) : 14561 this.empty().each( function() { 14562 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 14563 this.textContent = value; 14564 } 14565 } ); 14566 }, null, value, arguments.length ); 14567 }, 14568 14569 append: function() { 14570 return domManip( this, arguments, function( elem ) { 14571 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 14572 var target = manipulationTarget( this, elem ); 14573 target.appendChild( elem ); 14574 } 14575 } ); 14576 }, 14577
vendor: 52,786 bytes, lines 14578-16632
14578 prepend: function() { 14579 return domManip( this, arguments, function( elem ) { 14580 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 14581 var target = manipulationTarget( this, elem ); 14582 target.insertBefore( elem, target.firstChild ); 14583 } 14584 } ); 14585 }, 14586 14587 before: function() { 14588 return domManip( this, arguments, function( elem ) { 14589 if ( this.parentNode ) { 14590 this.parentNode.insertBefore( elem, this ); 14591 } 14592 } ); 14593 }, 14594 14595 after: function() { 14596 return domManip( this, arguments, function( elem ) { 14597 if ( this.parentNode ) { 14598 this.parentNode.insertBefore( elem, this.nextSibling ); 14599 } 14600 } ); 14601 }, 14602 14603 empty: function() { 14604 var elem, 14605 i = 0; 14606 14607 for ( ; ( elem = this[ i ] ) != null; i++ ) { 14608 if ( elem.nodeType === 1 ) { 14609 14610 // Prevent memory leaks 14611 jQuery.cleanData( getAll( elem, false ) ); 14612 14613 // Remove any remaining nodes 14614 elem.textContent = ""; 14615 } 14616 } 14617 14618 return this; 14619 }, 14620 14621 clone: function( dataAndEvents, deepDataAndEvents ) { 14622 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 14623 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 14624 14625 return this.map( function() { 14626 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 14627 } ); 14628 }, 14629 14630 html: function( value ) { 14631 return access( this, function( value ) { 14632 var elem = this[ 0 ] || {}, 14633 i = 0, 14634 l = this.length; 14635 14636 if ( value === undefined && elem.nodeType === 1 ) { 14637 return elem.innerHTML; 14638 } 14639 14640 // See if we can take a shortcut and just use innerHTML 14641 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 14642 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 14643 14644 value = jQuery.htmlPrefilter( value ); 14645 14646 try { 14647 for ( ; i < l; i++ ) { 14648 elem = this[ i ] || {}; 14649 14650 // Remove element nodes and prevent memory leaks 14651 if ( elem.nodeType === 1 ) { 14652 jQuery.cleanData( getAll( elem, false ) ); 14653 elem.innerHTML = value; 14654 } 14655 } 14656 14657 elem = 0; 14658 14659 // If using innerHTML throws an exception, use the fallback method 14660 } catch ( e ) {} 14661 } 14662 14663 if ( elem ) { 14664 this.empty().append( value ); 14665 } 14666 }, null, value, arguments.length ); 14667 }, 14668 14669 replaceWith: function() { 14670 var ignored = []; 14671 14672 // Make the changes, replacing each non-ignored context element with the new content 14673 return domManip( this, arguments, function( elem ) { 14674 var parent = this.parentNode; 14675 14676 if ( jQuery.inArray( this, ignored ) < 0 ) { 14677 jQuery.cleanData( getAll( this ) ); 14678 if ( parent ) { 14679 parent.replaceChild( elem, this ); 14680 } 14681 } 14682 14683 // Force callback invocation 14684 }, ignored ); 14685 } 14686} ); 14687 14688jQuery.each( { 14689 appendTo: "append", 14690 prependTo: "prepend", 14691 insertBefore: "before", 14692 insertAfter: "after", 14693 replaceAll: "replaceWith" 14694}, function( name, original ) { 14695 jQuery.fn[ name ] = function( selector ) { 14696 var elems, 14697 ret = [], 14698 insert = jQuery( selector ), 14699 last = insert.length - 1, 14700 i = 0; 14701 14702 for ( ; i <= last; i++ ) { 14703 elems = i === last ? this : this.clone( true ); 14704 jQuery( insert[ i ] )[ original ]( elems ); 14705 14706 // Support: Android <=4.0 only, PhantomJS 1 only 14707 // .get() because push.apply(_, arraylike) throws on ancient WebKit 14708 push.apply( ret, elems.get() ); 14709 } 14710 14711 return this.pushStack( ret ); 14712 }; 14713} ); 14714var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 14715 14716var getStyles = function( elem ) { 14717 14718 // Support: IE <=11 only, Firefox <=30 (#15098, #14150) 14719 // IE throws on elements created in popups 14720 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 14721 var view = elem.ownerDocument.defaultView; 14722 14723 if ( !view || !view.opener ) { 14724 view = window; 14725 } 14726 14727 return view.getComputedStyle( elem ); 14728 }; 14729 14730var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 14731 14732 14733 14734( function() { 14735 14736 // Executing both pixelPosition & boxSizingReliable tests require only one layout 14737 // so they're executed at the same time to save the second computation. 14738 function computeStyleTests() { 14739 14740 // This is a singleton, we need to execute it only once 14741 if ( !div ) { 14742 return; 14743 } 14744 14745 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 14746 "margin-top:1px;padding:0;border:0"; 14747 div.style.cssText = 14748 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 14749 "margin:auto;border:1px;padding:1px;" + 14750 "width:60%;top:1%"; 14751 documentElement.appendChild( container ).appendChild( div ); 14752 14753 var divStyle = window.getComputedStyle( div ); 14754 pixelPositionVal = divStyle.top !== "1%"; 14755 14756 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 14757 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 14758 14759 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 14760 // Some styles come back with percentage values, even though they shouldn't 14761 div.style.right = "60%"; 14762 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 14763 14764 // Support: IE 9 - 11 only 14765 // Detect misreporting of content dimensions for box-sizing:border-box elements 14766 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 14767 14768 // Support: IE 9 only 14769 // Detect overflow:scroll screwiness (gh-3699) 14770 div.style.position = "absolute"; 14771 scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; 14772 14773 documentElement.removeChild( container ); 14774 14775 // Nullify the div so it wouldn't be stored in the memory and 14776 // it will also be a sign that checks already performed 14777 div = null; 14778 } 14779 14780 function roundPixelMeasures( measure ) { 14781 return Math.round( parseFloat( measure ) ); 14782 } 14783 14784 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 14785 reliableMarginLeftVal, 14786 container = document.createElement( "div" ), 14787 div = document.createElement( "div" ); 14788 14789 // Finish early in limited (non-browser) environments 14790 if ( !div.style ) { 14791 return; 14792 } 14793 14794 // Support: IE <=9 - 11 only 14795 // Style of cloned element affects source element cloned (#8908) 14796 div.style.backgroundClip = "content-box"; 14797 div.cloneNode( true ).style.backgroundClip = ""; 14798 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 14799 14800 jQuery.extend( support, { 14801 boxSizingReliable: function() { 14802 computeStyleTests(); 14803 return boxSizingReliableVal; 14804 }, 14805 pixelBoxStyles: function() { 14806 computeStyleTests(); 14807 return pixelBoxStylesVal; 14808 }, 14809 pixelPosition: function() { 14810 computeStyleTests(); 14811 return pixelPositionVal; 14812 }, 14813 reliableMarginLeft: function() { 14814 computeStyleTests(); 14815 return reliableMarginLeftVal; 14816 }, 14817 scrollboxSize: function() { 14818 computeStyleTests(); 14819 return scrollboxSizeVal; 14820 } 14821 } ); 14822} )(); 14823 14824 14825function curCSS( elem, name, computed ) { 14826 var width, minWidth, maxWidth, ret, 14827 14828 // Support: Firefox 51+ 14829 // Retrieving style before computed somehow 14830 // fixes an issue with getting wrong values 14831 // on detached elements 14832 style = elem.style; 14833 14834 computed = computed || getStyles( elem ); 14835 14836 // getPropertyValue is needed for: 14837 // .css('filter') (IE 9 only, #12537) 14838 // .css('--customProperty) (#3144) 14839 if ( computed ) { 14840 ret = computed.getPropertyValue( name ) || computed[ name ]; 14841 14842 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { 14843 ret = jQuery.style( elem, name ); 14844 } 14845 14846 // A tribute to the "awesome hack by Dean Edwards" 14847 // Android Browser returns percentage for some values, 14848 // but width seems to be reliably pixels. 14849 // This is against the CSSOM draft spec: 14850 // https://drafts.csswg.org/cssom/#resolved-values 14851 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 14852 14853 // Remember the original values 14854 width = style.width; 14855 minWidth = style.minWidth; 14856 maxWidth = style.maxWidth; 14857 14858 // Put in the new values to get a computed value out 14859 style.minWidth = style.maxWidth = style.width = ret; 14860 ret = computed.width; 14861 14862 // Revert the changed values 14863 style.width = width; 14864 style.minWidth = minWidth; 14865 style.maxWidth = maxWidth; 14866 } 14867 } 14868 14869 return ret !== undefined ? 14870 14871 // Support: IE <=9 - 11 only 14872 // IE returns zIndex value as an integer. 14873 ret + "" : 14874 ret; 14875} 14876 14877 14878function addGetHookIf( conditionFn, hookFn ) { 14879 14880 // Define the hook, we'll check on the first run if it's really needed. 14881 return { 14882 get: function() { 14883 if ( conditionFn() ) { 14884 14885 // Hook not needed (or it's not possible to use it due 14886 // to missing dependency), remove it. 14887 delete this.get; 14888 return; 14889 } 14890 14891 // Hook needed; redefine it so that the support test is not executed again. 14892 return ( this.get = hookFn ).apply( this, arguments ); 14893 } 14894 }; 14895} 14896 14897 14898var 14899 14900 // Swappable if display is none or starts with table 14901 // except "table", "table-cell", or "table-caption" 14902 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 14903 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 14904 rcustomProp = /^--/, 14905 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 14906 cssNormalTransform = { 14907 letterSpacing: "0", 14908 fontWeight: "400" 14909 }, 14910 14911 cssPrefixes = [ "Webkit", "Moz", "ms" ], 14912 emptyStyle = document.createElement( "div" ).style; 14913 14914// Return a css property mapped to a potentially vendor prefixed property 14915function vendorPropName( name ) { 14916 14917 // Shortcut for names that are not vendor prefixed 14918 if ( name in emptyStyle ) { 14919 return name; 14920 } 14921 14922 // Check for vendor prefixed names 14923 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 14924 i = cssPrefixes.length; 14925 14926 while ( i-- ) { 14927 name = cssPrefixes[ i ] + capName; 14928 if ( name in emptyStyle ) { 14929 return name; 14930 } 14931 } 14932} 14933 14934// Return a property mapped along what jQuery.cssProps suggests or to 14935// a vendor prefixed property. 14936function finalPropName( name ) { 14937 var ret = jQuery.cssProps[ name ]; 14938 if ( !ret ) { 14939 ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; 14940 } 14941 return ret; 14942} 14943 14944function setPositiveNumber( elem, value, subtract ) { 14945 14946 // Any relative (+/-) values have already been 14947 // normalized at this point 14948 var matches = rcssNum.exec( value ); 14949 return matches ? 14950 14951 // Guard against undefined "subtract", e.g., when used as in cssHooks 14952 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 14953 value; 14954} 14955 14956function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 14957 var i = dimension === "width" ? 1 : 0, 14958 extra = 0, 14959 delta = 0; 14960 14961 // Adjustment may not be necessary 14962 if ( box === ( isBorderBox ? "border" : "content" ) ) { 14963 return 0; 14964 } 14965 14966 for ( ; i < 4; i += 2 ) { 14967 14968 // Both box models exclude margin 14969 if ( box === "margin" ) { 14970 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 14971 } 14972 14973 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 14974 if ( !isBorderBox ) { 14975 14976 // Add padding 14977 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 14978 14979 // For "border" or "margin", add border 14980 if ( box !== "padding" ) { 14981 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 14982 14983 // But still keep track of it otherwise 14984 } else { 14985 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 14986 } 14987 14988 // If we get here with a border-box (content + padding + border), we're seeking "content" or 14989 // "padding" or "margin" 14990 } else { 14991 14992 // For "content", subtract padding 14993 if ( box === "content" ) { 14994 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 14995 } 14996 14997 // For "content" or "padding", subtract border 14998 if ( box !== "margin" ) { 14999 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 15000 } 15001 } 15002 } 15003 15004 // Account for positive content-box scroll gutter when requested by providing computedVal 15005 if ( !isBorderBox && computedVal >= 0 ) { 15006 15007 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 15008 // Assuming integer scroll gutter, subtract the rest and round down 15009 delta += Math.max( 0, Math.ceil( 15010 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 15011 computedVal - 15012 delta - 15013 extra - 15014 0.5 15015 ) ); 15016 } 15017 15018 return delta; 15019} 15020 15021function getWidthOrHeight( elem, dimension, extra ) { 15022 15023 // Start with computed style 15024 var styles = getStyles( elem ), 15025 val = curCSS( elem, dimension, styles ), 15026 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 15027 valueIsBorderBox = isBorderBox; 15028 15029 // Support: Firefox <=54 15030 // Return a confounding non-pixel value or feign ignorance, as appropriate. 15031 if ( rnumnonpx.test( val ) ) { 15032 if ( !extra ) { 15033 return val; 15034 } 15035 val = "auto"; 15036 } 15037 15038 // Check for style in case a browser which returns unreliable values 15039 // for getComputedStyle silently falls back to the reliable elem.style 15040 valueIsBorderBox = valueIsBorderBox && 15041 ( support.boxSizingReliable() || val === elem.style[ dimension ] ); 15042 15043 // Fall back to offsetWidth/offsetHeight when value is "auto" 15044 // This happens for inline elements with no explicit setting (gh-3571) 15045 // Support: Android <=4.1 - 4.3 only 15046 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 15047 if ( val === "auto" || 15048 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) { 15049 15050 val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ]; 15051 15052 // offsetWidth/offsetHeight provide border-box values 15053 valueIsBorderBox = true; 15054 } 15055 15056 // Normalize "" and auto 15057 val = parseFloat( val ) || 0; 15058 15059 // Adjust for the element's box model 15060 return ( val + 15061 boxModelAdjustment( 15062 elem, 15063 dimension, 15064 extra || ( isBorderBox ? "border" : "content" ), 15065 valueIsBorderBox, 15066 styles, 15067 15068 // Provide the current computed size to request scroll gutter calculation (gh-3589) 15069 val 15070 ) 15071 ) + "px"; 15072} 15073 15074jQuery.extend( { 15075 15076 // Add in style property hooks for overriding the default 15077 // behavior of getting and setting a style property 15078 cssHooks: { 15079 opacity: { 15080 get: function( elem, computed ) { 15081 if ( computed ) { 15082 15083 // We should always get a number back from opacity 15084 var ret = curCSS( elem, "opacity" ); 15085 return ret === "" ? "1" : ret; 15086 } 15087 } 15088 } 15089 }, 15090 15091 // Don't automatically add "px" to these possibly-unitless properties 15092 cssNumber: { 15093 "animationIterationCount": true, 15094 "columnCount": true, 15095 "fillOpacity": true, 15096 "flexGrow": true, 15097 "flexShrink": true, 15098 "fontWeight": true, 15099 "lineHeight": true, 15100 "opacity": true, 15101 "order": true, 15102 "orphans": true, 15103 "widows": true, 15104 "zIndex": true, 15105 "zoom": true 15106 }, 15107 15108 // Add in properties whose names you wish to fix before 15109 // setting or getting the value 15110 cssProps: {}, 15111 15112 // Get and set the style property on a DOM Node 15113 style: function( elem, name, value, extra ) { 15114 15115 // Don't set styles on text and comment nodes 15116 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 15117 return; 15118 } 15119 15120 // Make sure that we're working with the right name 15121 var ret, type, hooks, 15122 origName = camelCase( name ), 15123 isCustomProp = rcustomProp.test( name ), 15124 style = elem.style; 15125 15126 // Make sure that we're working with the right name. We don't 15127 // want to query the value if it is a CSS custom property 15128 // since they are user-defined. 15129 if ( !isCustomProp ) { 15130 name = finalPropName( origName ); 15131 } 15132 15133 // Gets hook for the prefixed version, then unprefixed version 15134 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 15135 15136 // Check if we're setting a value 15137 if ( value !== undefined ) { 15138 type = typeof value; 15139 15140 // Convert "+=" or "-=" to relative numbers (#7345) 15141 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 15142 value = adjustCSS( elem, name, ret ); 15143 15144 // Fixes bug #9237 15145 type = "number"; 15146 } 15147 15148 // Make sure that null and NaN values aren't set (#7116) 15149 if ( value == null || value !== value ) { 15150 return; 15151 } 15152 15153 // If a number was passed in, add the unit (except for certain CSS properties) 15154 if ( type === "number" ) { 15155 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 15156 } 15157 15158 // background-* props affect original clone's values 15159 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 15160 style[ name ] = "inherit"; 15161 } 15162 15163 // If a hook was provided, use that value, otherwise just set the specified value 15164 if ( !hooks || !( "set" in hooks ) || 15165 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 15166 15167 if ( isCustomProp ) { 15168 style.setProperty( name, value ); 15169 } else { 15170 style[ name ] = value; 15171 } 15172 } 15173 15174 } else { 15175 15176 // If a hook was provided get the non-computed value from there 15177 if ( hooks && "get" in hooks && 15178 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 15179 15180 return ret; 15181 } 15182 15183 // Otherwise just get the value from the style object 15184 return style[ name ]; 15185 } 15186 }, 15187 15188 css: function( elem, name, extra, styles ) { 15189 var val, num, hooks, 15190 origName = camelCase( name ), 15191 isCustomProp = rcustomProp.test( name ); 15192 15193 // Make sure that we're working with the right name. We don't 15194 // want to modify the value if it is a CSS custom property 15195 // since they are user-defined. 15196 if ( !isCustomProp ) { 15197 name = finalPropName( origName ); 15198 } 15199 15200 // Try prefixed name followed by the unprefixed name 15201 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 15202 15203 // If a hook was provided get the computed value from there 15204 if ( hooks && "get" in hooks ) { 15205 val = hooks.get( elem, true, extra ); 15206 } 15207 15208 // Otherwise, if a way to get the computed value exists, use that 15209 if ( val === undefined ) { 15210 val = curCSS( elem, name, styles ); 15211 } 15212 15213 // Convert "normal" to computed value 15214 if ( val === "normal" && name in cssNormalTransform ) { 15215 val = cssNormalTransform[ name ]; 15216 } 15217 15218 // Make numeric if forced or a qualifier was provided and val looks numeric 15219 if ( extra === "" || extra ) { 15220 num = parseFloat( val ); 15221 return extra === true || isFinite( num ) ? num || 0 : val; 15222 } 15223 15224 return val; 15225 } 15226} ); 15227 15228jQuery.each( [ "height", "width" ], function( i, dimension ) { 15229 jQuery.cssHooks[ dimension ] = { 15230 get: function( elem, computed, extra ) { 15231 if ( computed ) { 15232 15233 // Certain elements can have dimension info if we invisibly show them 15234 // but it must have a current display style that would benefit 15235 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 15236 15237 // Support: Safari 8+ 15238 // Table columns in Safari have non-zero offsetWidth & zero 15239 // getBoundingClientRect().width unless display is changed. 15240 // Support: IE <=11 only 15241 // Running getBoundingClientRect on a disconnected node 15242 // in IE throws an error. 15243 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 15244 swap( elem, cssShow, function() { 15245 return getWidthOrHeight( elem, dimension, extra ); 15246 } ) : 15247 getWidthOrHeight( elem, dimension, extra ); 15248 } 15249 }, 15250 15251 set: function( elem, value, extra ) { 15252 var matches, 15253 styles = getStyles( elem ), 15254 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 15255 subtract = extra && boxModelAdjustment( 15256 elem, 15257 dimension, 15258 extra, 15259 isBorderBox, 15260 styles 15261 ); 15262 15263 // Account for unreliable border-box dimensions by comparing offset* to computed and 15264 // faking a content-box to get border and padding (gh-3699) 15265 if ( isBorderBox && support.scrollboxSize() === styles.position ) { 15266 subtract -= Math.ceil( 15267 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 15268 parseFloat( styles[ dimension ] ) - 15269 boxModelAdjustment( elem, dimension, "border", false, styles ) - 15270 0.5 15271 ); 15272 } 15273 15274 // Convert to pixels if value adjustment is needed 15275 if ( subtract && ( matches = rcssNum.exec( value ) ) && 15276 ( matches[ 3 ] || "px" ) !== "px" ) { 15277 15278 elem.style[ dimension ] = value; 15279 value = jQuery.css( elem, dimension ); 15280 } 15281 15282 return setPositiveNumber( elem, value, subtract ); 15283 } 15284 }; 15285} ); 15286 15287jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 15288 function( elem, computed ) { 15289 if ( computed ) { 15290 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 15291 elem.getBoundingClientRect().left - 15292 swap( elem, { marginLeft: 0 }, function() { 15293 return elem.getBoundingClientRect().left; 15294 } ) 15295 ) + "px"; 15296 } 15297 } 15298); 15299 15300// These hooks are used by animate to expand properties 15301jQuery.each( { 15302 margin: "", 15303 padding: "", 15304 border: "Width" 15305}, function( prefix, suffix ) { 15306 jQuery.cssHooks[ prefix + suffix ] = { 15307 expand: function( value ) { 15308 var i = 0, 15309 expanded = {}, 15310 15311 // Assumes a single number if not a string 15312 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 15313 15314 for ( ; i < 4; i++ ) { 15315 expanded[ prefix + cssExpand[ i ] + suffix ] = 15316 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 15317 } 15318 15319 return expanded; 15320 } 15321 }; 15322 15323 if ( prefix !== "margin" ) { 15324 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 15325 } 15326} ); 15327 15328jQuery.fn.extend( { 15329 css: function( name, value ) { 15330 return access( this, function( elem, name, value ) { 15331 var styles, len, 15332 map = {}, 15333 i = 0; 15334 15335 if ( Array.isArray( name ) ) { 15336 styles = getStyles( elem ); 15337 len = name.length; 15338 15339 for ( ; i < len; i++ ) { 15340 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 15341 } 15342 15343 return map; 15344 } 15345 15346 return value !== undefined ? 15347 jQuery.style( elem, name, value ) : 15348 jQuery.css( elem, name ); 15349 }, name, value, arguments.length > 1 ); 15350 } 15351} ); 15352 15353 15354function Tween( elem, options, prop, end, easing ) { 15355 return new Tween.prototype.init( elem, options, prop, end, easing ); 15356} 15357jQuery.Tween = Tween; 15358 15359Tween.prototype = { 15360 constructor: Tween, 15361 init: function( elem, options, prop, end, easing, unit ) { 15362 this.elem = elem; 15363 this.prop = prop; 15364 this.easing = easing || jQuery.easing._default; 15365 this.options = options; 15366 this.start = this.now = this.cur(); 15367 this.end = end; 15368 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 15369 }, 15370 cur: function() { 15371 var hooks = Tween.propHooks[ this.prop ]; 15372 15373 return hooks && hooks.get ? 15374 hooks.get( this ) : 15375 Tween.propHooks._default.get( this ); 15376 }, 15377 run: function( percent ) { 15378 var eased, 15379 hooks = Tween.propHooks[ this.prop ]; 15380 15381 if ( this.options.duration ) { 15382 this.pos = eased = jQuery.easing[ this.easing ]( 15383 percent, this.options.duration * percent, 0, 1, this.options.duration 15384 ); 15385 } else { 15386 this.pos = eased = percent; 15387 } 15388 this.now = ( this.end - this.start ) * eased + this.start; 15389 15390 if ( this.options.step ) { 15391 this.options.step.call( this.elem, this.now, this ); 15392 } 15393 15394 if ( hooks && hooks.set ) { 15395 hooks.set( this ); 15396 } else { 15397 Tween.propHooks._default.set( this ); 15398 } 15399 return this; 15400 } 15401}; 15402 15403Tween.prototype.init.prototype = Tween.prototype; 15404 15405Tween.propHooks = { 15406 _default: { 15407 get: function( tween ) { 15408 var result; 15409 15410 // Use a property on the element directly when it is not a DOM element, 15411 // or when there is no matching style property that exists. 15412 if ( tween.elem.nodeType !== 1 || 15413 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 15414 return tween.elem[ tween.prop ]; 15415 } 15416 15417 // Passing an empty string as a 3rd parameter to .css will automatically 15418 // attempt a parseFloat and fallback to a string if the parse fails. 15419 // Simple values such as "10px" are parsed to Float; 15420 // complex values such as "rotate(1rad)" are returned as-is. 15421 result = jQuery.css( tween.elem, tween.prop, "" ); 15422 15423 // Empty strings, null, undefined and "auto" are converted to 0. 15424 return !result || result === "auto" ? 0 : result; 15425 }, 15426 set: function( tween ) { 15427 15428 // Use step hook for back compat. 15429 // Use cssHook if its there. 15430 // Use .style if available and use plain properties where available. 15431 if ( jQuery.fx.step[ tween.prop ] ) { 15432 jQuery.fx.step[ tween.prop ]( tween ); 15433 } else if ( tween.elem.nodeType === 1 && 15434 ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || 15435 jQuery.cssHooks[ tween.prop ] ) ) { 15436 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 15437 } else { 15438 tween.elem[ tween.prop ] = tween.now; 15439 } 15440 } 15441 } 15442}; 15443 15444// Support: IE <=9 only 15445// Panic based approach to setting things on disconnected nodes 15446Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 15447 set: function( tween ) { 15448 if ( tween.elem.nodeType && tween.elem.parentNode ) { 15449 tween.elem[ tween.prop ] = tween.now; 15450 } 15451 } 15452}; 15453 15454jQuery.easing = { 15455 linear: function( p ) { 15456 return p; 15457 }, 15458 swing: function( p ) { 15459 return 0.5 - Math.cos( p * Math.PI ) / 2; 15460 }, 15461 _default: "swing" 15462}; 15463 15464jQuery.fx = Tween.prototype.init; 15465 15466// Back compat <1.8 extension point 15467jQuery.fx.step = {}; 15468 15469 15470 15471 15472var 15473 fxNow, inProgress, 15474 rfxtypes = /^(?:toggle|show|hide)$/, 15475 rrun = /queueHooks$/; 15476 15477function schedule() { 15478 if ( inProgress ) { 15479 if ( document.hidden === false && window.requestAnimationFrame ) { 15480 window.requestAnimationFrame( schedule ); 15481 } else { 15482 window.setTimeout( schedule, jQuery.fx.interval ); 15483 } 15484 15485 jQuery.fx.tick(); 15486 } 15487} 15488 15489// Animations created synchronously will run synchronously 15490function createFxNow() { 15491 window.setTimeout( function() { 15492 fxNow = undefined; 15493 } ); 15494 return ( fxNow = Date.now() ); 15495} 15496 15497// Generate parameters to create a standard animation 15498function genFx( type, includeWidth ) { 15499 var which, 15500 i = 0, 15501 attrs = { height: type }; 15502 15503 // If we include width, step value is 1 to do all cssExpand values, 15504 // otherwise step value is 2 to skip over Left and Right 15505 includeWidth = includeWidth ? 1 : 0; 15506 for ( ; i < 4; i += 2 - includeWidth ) { 15507 which = cssExpand[ i ]; 15508 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 15509 } 15510 15511 if ( includeWidth ) { 15512 attrs.opacity = attrs.width = type; 15513 } 15514 15515 return attrs; 15516} 15517 15518function createTween( value, prop, animation ) { 15519 var tween, 15520 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 15521 index = 0, 15522 length = collection.length; 15523 for ( ; index < length; index++ ) { 15524 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 15525 15526 // We're done with this property 15527 return tween; 15528 } 15529 } 15530} 15531 15532function defaultPrefilter( elem, props, opts ) { 15533 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 15534 isBox = "width" in props || "height" in props, 15535 anim = this, 15536 orig = {}, 15537 style = elem.style, 15538 hidden = elem.nodeType && isHiddenWithinTree( elem ), 15539 dataShow = dataPriv.get( elem, "fxshow" ); 15540 15541 // Queue-skipping animations hijack the fx hooks 15542 if ( !opts.queue ) { 15543 hooks = jQuery._queueHooks( elem, "fx" ); 15544 if ( hooks.unqueued == null ) { 15545 hooks.unqueued = 0; 15546 oldfire = hooks.empty.fire; 15547 hooks.empty.fire = function() { 15548 if ( !hooks.unqueued ) { 15549 oldfire(); 15550 } 15551 }; 15552 } 15553 hooks.unqueued++; 15554 15555 anim.always( function() { 15556 15557 // Ensure the complete handler is called before this completes 15558 anim.always( function() { 15559 hooks.unqueued--; 15560 if ( !jQuery.queue( elem, "fx" ).length ) { 15561 hooks.empty.fire(); 15562 } 15563 } ); 15564 } ); 15565 } 15566 15567 // Detect show/hide animations 15568 for ( prop in props ) { 15569 value = props[ prop ]; 15570 if ( rfxtypes.test( value ) ) { 15571 delete props[ prop ]; 15572 toggle = toggle || value === "toggle"; 15573 if ( value === ( hidden ? "hide" : "show" ) ) { 15574 15575 // Pretend to be hidden if this is a "show" and 15576 // there is still data from a stopped show/hide 15577 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 15578 hidden = true; 15579 15580 // Ignore all other no-op show/hide data 15581 } else { 15582 continue; 15583 } 15584 } 15585 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 15586 } 15587 } 15588 15589 // Bail out if this is a no-op like .hide().hide() 15590 propTween = !jQuery.isEmptyObject( props ); 15591 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 15592 return; 15593 } 15594 15595 // Restrict "overflow" and "display" styles during box animations 15596 if ( isBox && elem.nodeType === 1 ) { 15597 15598 // Support: IE <=9 - 11, Edge 12 - 15 15599 // Record all 3 overflow attributes because IE does not infer the shorthand 15600 // from identically-valued overflowX and overflowY and Edge just mirrors 15601 // the overflowX value there. 15602 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 15603 15604 // Identify a display type, preferring old show/hide data over the CSS cascade 15605 restoreDisplay = dataShow && dataShow.display; 15606 if ( restoreDisplay == null ) { 15607 restoreDisplay = dataPriv.get( elem, "display" ); 15608 } 15609 display = jQuery.css( elem, "display" ); 15610 if ( display === "none" ) { 15611 if ( restoreDisplay ) { 15612 display = restoreDisplay; 15613 } else { 15614 15615 // Get nonempty value(s) by temporarily forcing visibility 15616 showHide( [ elem ], true ); 15617 restoreDisplay = elem.style.display || restoreDisplay; 15618 display = jQuery.css( elem, "display" ); 15619 showHide( [ elem ] ); 15620 } 15621 } 15622 15623 // Animate inline elements as inline-block 15624 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 15625 if ( jQuery.css( elem, "float" ) === "none" ) { 15626 15627 // Restore the original display value at the end of pure show/hide animations 15628 if ( !propTween ) { 15629 anim.done( function() { 15630 style.display = restoreDisplay; 15631 } ); 15632 if ( restoreDisplay == null ) { 15633 display = style.display; 15634 restoreDisplay = display === "none" ? "" : display; 15635 } 15636 } 15637 style.display = "inline-block"; 15638 } 15639 } 15640 } 15641 15642 if ( opts.overflow ) { 15643 style.overflow = "hidden"; 15644 anim.always( function() { 15645 style.overflow = opts.overflow[ 0 ]; 15646 style.overflowX = opts.overflow[ 1 ]; 15647 style.overflowY = opts.overflow[ 2 ]; 15648 } ); 15649 } 15650 15651 // Implement show/hide animations 15652 propTween = false; 15653 for ( prop in orig ) { 15654 15655 // General show/hide setup for this element animation 15656 if ( !propTween ) { 15657 if ( dataShow ) { 15658 if ( "hidden" in dataShow ) { 15659 hidden = dataShow.hidden; 15660 } 15661 } else { 15662 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 15663 } 15664 15665 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 15666 if ( toggle ) { 15667 dataShow.hidden = !hidden; 15668 } 15669 15670 // Show elements before animating them 15671 if ( hidden ) { 15672 showHide( [ elem ], true ); 15673 } 15674 15675 /* eslint-disable no-loop-func */ 15676 15677 anim.done( function() { 15678 15679 /* eslint-enable no-loop-func */ 15680 15681 // The final step of a "hide" animation is actually hiding the element 15682 if ( !hidden ) { 15683 showHide( [ elem ] ); 15684 } 15685 dataPriv.remove( elem, "fxshow" ); 15686 for ( prop in orig ) { 15687 jQuery.style( elem, prop, orig[ prop ] ); 15688 } 15689 } ); 15690 } 15691 15692 // Per-property setup 15693 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 15694 if ( !( prop in dataShow ) ) { 15695 dataShow[ prop ] = propTween.start; 15696 if ( hidden ) { 15697 propTween.end = propTween.start; 15698 propTween.start = 0; 15699 } 15700 } 15701 } 15702} 15703 15704function propFilter( props, specialEasing ) { 15705 var index, name, easing, value, hooks; 15706 15707 // camelCase, specialEasing and expand cssHook pass 15708 for ( index in props ) { 15709 name = camelCase( index ); 15710 easing = specialEasing[ name ]; 15711 value = props[ index ]; 15712 if ( Array.isArray( value ) ) { 15713 easing = value[ 1 ]; 15714 value = props[ index ] = value[ 0 ]; 15715 } 15716 15717 if ( index !== name ) { 15718 props[ name ] = value; 15719 delete props[ index ]; 15720 } 15721 15722 hooks = jQuery.cssHooks[ name ]; 15723 if ( hooks && "expand" in hooks ) { 15724 value = hooks.expand( value ); 15725 delete props[ name ]; 15726 15727 // Not quite $.extend, this won't overwrite existing keys. 15728 // Reusing 'index' because we have the correct "name" 15729 for ( index in value ) { 15730 if ( !( index in props ) ) { 15731 props[ index ] = value[ index ]; 15732 specialEasing[ index ] = easing; 15733 } 15734 } 15735 } else { 15736 specialEasing[ name ] = easing; 15737 } 15738 } 15739} 15740 15741function Animation( elem, properties, options ) { 15742 var result, 15743 stopped, 15744 index = 0, 15745 length = Animation.prefilters.length, 15746 deferred = jQuery.Deferred().always( function() { 15747 15748 // Don't match elem in the :animated selector 15749 delete tick.elem; 15750 } ), 15751 tick = function() { 15752 if ( stopped ) { 15753 return false; 15754 } 15755 var currentTime = fxNow || createFxNow(), 15756 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 15757 15758 // Support: Android 2.3 only 15759 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 15760 temp = remaining / animation.duration || 0, 15761 percent = 1 - temp, 15762 index = 0, 15763 length = animation.tweens.length; 15764 15765 for ( ; index < length; index++ ) { 15766 animation.tweens[ index ].run( percent ); 15767 } 15768 15769 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 15770 15771 // If there's more to do, yield 15772 if ( percent < 1 && length ) { 15773 return remaining; 15774 } 15775 15776 // If this was an empty animation, synthesize a final progress notification 15777 if ( !length ) { 15778 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 15779 } 15780 15781 // Resolve the animation and report its conclusion 15782 deferred.resolveWith( elem, [ animation ] ); 15783 return false; 15784 }, 15785 animation = deferred.promise( { 15786 elem: elem, 15787 props: jQuery.extend( {}, properties ), 15788 opts: jQuery.extend( true, { 15789 specialEasing: {}, 15790 easing: jQuery.easing._default 15791 }, options ), 15792 originalProperties: properties, 15793 originalOptions: options, 15794 startTime: fxNow || createFxNow(), 15795 duration: options.duration, 15796 tweens: [], 15797 createTween: function( prop, end ) { 15798 var tween = jQuery.Tween( elem, animation.opts, prop, end, 15799 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 15800 animation.tweens.push( tween ); 15801 return tween; 15802 }, 15803 stop: function( gotoEnd ) { 15804 var index = 0, 15805 15806 // If we are going to the end, we want to run all the tweens 15807 // otherwise we skip this part 15808 length = gotoEnd ? animation.tweens.length : 0; 15809 if ( stopped ) { 15810 return this; 15811 } 15812 stopped = true; 15813 for ( ; index < length; index++ ) { 15814 animation.tweens[ index ].run( 1 ); 15815 } 15816 15817 // Resolve when we played the last frame; otherwise, reject 15818 if ( gotoEnd ) { 15819 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 15820 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 15821 } else { 15822 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 15823 } 15824 return this; 15825 } 15826 } ), 15827 props = animation.props; 15828 15829 propFilter( props, animation.opts.specialEasing ); 15830 15831 for ( ; index < length; index++ ) { 15832 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 15833 if ( result ) { 15834 if ( isFunction( result.stop ) ) { 15835 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 15836 result.stop.bind( result ); 15837 } 15838 return result; 15839 } 15840 } 15841 15842 jQuery.map( props, createTween, animation ); 15843 15844 if ( isFunction( animation.opts.start ) ) { 15845 animation.opts.start.call( elem, animation ); 15846 } 15847 15848 // Attach callbacks from options 15849 animation 15850 .progress( animation.opts.progress ) 15851 .done( animation.opts.done, animation.opts.complete ) 15852 .fail( animation.opts.fail ) 15853 .always( animation.opts.always ); 15854 15855 jQuery.fx.timer( 15856 jQuery.extend( tick, { 15857 elem: elem, 15858 anim: animation, 15859 queue: animation.opts.queue 15860 } ) 15861 ); 15862 15863 return animation; 15864} 15865 15866jQuery.Animation = jQuery.extend( Animation, { 15867 15868 tweeners: { 15869 "*": [ function( prop, value ) { 15870 var tween = this.createTween( prop, value ); 15871 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 15872 return tween; 15873 } ] 15874 }, 15875 15876 tweener: function( props, callback ) { 15877 if ( isFunction( props ) ) { 15878 callback = props; 15879 props = [ "*" ]; 15880 } else { 15881 props = props.match( rnothtmlwhite ); 15882 } 15883 15884 var prop, 15885 index = 0, 15886 length = props.length; 15887 15888 for ( ; index < length; index++ ) { 15889 prop = props[ index ]; 15890 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 15891 Animation.tweeners[ prop ].unshift( callback ); 15892 } 15893 }, 15894 15895 prefilters: [ defaultPrefilter ], 15896 15897 prefilter: function( callback, prepend ) { 15898 if ( prepend ) { 15899 Animation.prefilters.unshift( callback ); 15900 } else { 15901 Animation.prefilters.push( callback ); 15902 } 15903 } 15904} ); 15905 15906jQuery.speed = function( speed, easing, fn ) { 15907 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 15908 complete: fn || !fn && easing || 15909 isFunction( speed ) && speed, 15910 duration: speed, 15911 easing: fn && easing || easing && !isFunction( easing ) && easing 15912 }; 15913 15914 // Go to the end state if fx are off 15915 if ( jQuery.fx.off ) { 15916 opt.duration = 0; 15917 15918 } else { 15919 if ( typeof opt.duration !== "number" ) { 15920 if ( opt.duration in jQuery.fx.speeds ) { 15921 opt.duration = jQuery.fx.speeds[ opt.duration ]; 15922 15923 } else { 15924 opt.duration = jQuery.fx.speeds._default; 15925 } 15926 } 15927 } 15928 15929 // Normalize opt.queue - true/undefined/null -> "fx" 15930 if ( opt.queue == null || opt.queue === true ) { 15931 opt.queue = "fx"; 15932 } 15933 15934 // Queueing 15935 opt.old = opt.complete; 15936 15937 opt.complete = function() { 15938 if ( isFunction( opt.old ) ) { 15939 opt.old.call( this ); 15940 } 15941 15942 if ( opt.queue ) { 15943 jQuery.dequeue( this, opt.queue ); 15944 } 15945 }; 15946 15947 return opt; 15948}; 15949 15950jQuery.fn.extend( { 15951 fadeTo: function( speed, to, easing, callback ) { 15952 15953 // Show any hidden elements after setting opacity to 0 15954 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 15955 15956 // Animate to the value specified 15957 .end().animate( { opacity: to }, speed, easing, callback ); 15958 }, 15959 animate: function( prop, speed, easing, callback ) { 15960 var empty = jQuery.isEmptyObject( prop ), 15961 optall = jQuery.speed( speed, easing, callback ), 15962 doAnimation = function() { 15963 15964 // Operate on a copy of prop so per-property easing won't be lost 15965 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 15966 15967 // Empty animations, or finishing resolves immediately 15968 if ( empty || dataPriv.get( this, "finish" ) ) { 15969 anim.stop( true ); 15970 } 15971 }; 15972 doAnimation.finish = doAnimation; 15973 15974 return empty || optall.queue === false ? 15975 this.each( doAnimation ) : 15976 this.queue( optall.queue, doAnimation ); 15977 }, 15978 stop: function( type, clearQueue, gotoEnd ) { 15979 var stopQueue = function( hooks ) { 15980 var stop = hooks.stop; 15981 delete hooks.stop; 15982 stop( gotoEnd ); 15983 }; 15984 15985 if ( typeof type !== "string" ) { 15986 gotoEnd = clearQueue; 15987 clearQueue = type; 15988 type = undefined; 15989 } 15990 if ( clearQueue && type !== false ) { 15991 this.queue( type || "fx", [] ); 15992 } 15993 15994 return this.each( function() { 15995 var dequeue = true, 15996 index = type != null && type + "queueHooks", 15997 timers = jQuery.timers, 15998 data = dataPriv.get( this ); 15999 16000 if ( index ) { 16001 if ( data[ index ] && data[ index ].stop ) { 16002 stopQueue( data[ index ] ); 16003 } 16004 } else { 16005 for ( index in data ) { 16006 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 16007 stopQueue( data[ index ] ); 16008 } 16009 } 16010 } 16011 16012 for ( index = timers.length; index--; ) { 16013 if ( timers[ index ].elem === this && 16014 ( type == null || timers[ index ].queue === type ) ) { 16015 16016 timers[ index ].anim.stop( gotoEnd ); 16017 dequeue = false; 16018 timers.splice( index, 1 ); 16019 } 16020 } 16021 16022 // Start the next in the queue if the last step wasn't forced. 16023 // Timers currently will call their complete callbacks, which 16024 // will dequeue but only if they were gotoEnd. 16025 if ( dequeue || !gotoEnd ) { 16026 jQuery.dequeue( this, type ); 16027 } 16028 } ); 16029 }, 16030 finish: function( type ) { 16031 if ( type !== false ) { 16032 type = type || "fx"; 16033 } 16034 return this.each( function() { 16035 var index, 16036 data = dataPriv.get( this ), 16037 queue = data[ type + "queue" ], 16038 hooks = data[ type + "queueHooks" ], 16039 timers = jQuery.timers, 16040 length = queue ? queue.length : 0; 16041 16042 // Enable finishing flag on private data 16043 data.finish = true; 16044 16045 // Empty the queue first 16046 jQuery.queue( this, type, [] ); 16047 16048 if ( hooks && hooks.stop ) { 16049 hooks.stop.call( this, true ); 16050 } 16051 16052 // Look for any active animations, and finish them 16053 for ( index = timers.length; index--; ) { 16054 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 16055 timers[ index ].anim.stop( true ); 16056 timers.splice( index, 1 ); 16057 } 16058 } 16059 16060 // Look for any animations in the old queue and finish them 16061 for ( index = 0; index < length; index++ ) { 16062 if ( queue[ index ] && queue[ index ].finish ) { 16063 queue[ index ].finish.call( this ); 16064 } 16065 } 16066 16067 // Turn off finishing flag 16068 delete data.finish; 16069 } ); 16070 } 16071} ); 16072 16073jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { 16074 var cssFn = jQuery.fn[ name ]; 16075 jQuery.fn[ name ] = function( speed, easing, callback ) { 16076 return speed == null || typeof speed === "boolean" ? 16077 cssFn.apply( this, arguments ) : 16078 this.animate( genFx( name, true ), speed, easing, callback ); 16079 }; 16080} ); 16081 16082// Generate shortcuts for custom animations 16083jQuery.each( { 16084 slideDown: genFx( "show" ), 16085 slideUp: genFx( "hide" ), 16086 slideToggle: genFx( "toggle" ), 16087 fadeIn: { opacity: "show" }, 16088 fadeOut: { opacity: "hide" }, 16089 fadeToggle: { opacity: "toggle" } 16090}, function( name, props ) { 16091 jQuery.fn[ name ] = function( speed, easing, callback ) { 16092 return this.animate( props, speed, easing, callback ); 16093 }; 16094} ); 16095 16096jQuery.timers = []; 16097jQuery.fx.tick = function() { 16098 var timer, 16099 i = 0, 16100 timers = jQuery.timers; 16101 16102 fxNow = Date.now(); 16103 16104 for ( ; i < timers.length; i++ ) { 16105 timer = timers[ i ]; 16106 16107 // Run the timer and safely remove it when done (allowing for external removal) 16108 if ( !timer() && timers[ i ] === timer ) { 16109 timers.splice( i--, 1 ); 16110 } 16111 } 16112 16113 if ( !timers.length ) { 16114 jQuery.fx.stop(); 16115 } 16116 fxNow = undefined; 16117}; 16118 16119jQuery.fx.timer = function( timer ) { 16120 jQuery.timers.push( timer ); 16121 jQuery.fx.start(); 16122}; 16123 16124jQuery.fx.interval = 13; 16125jQuery.fx.start = function() { 16126 if ( inProgress ) { 16127 return; 16128 } 16129 16130 inProgress = true; 16131 schedule(); 16132}; 16133 16134jQuery.fx.stop = function() { 16135 inProgress = null; 16136}; 16137 16138jQuery.fx.speeds = { 16139 slow: 600, 16140 fast: 200, 16141 16142 // Default speed 16143 _default: 400 16144}; 16145 16146 16147// Based off of the plugin by Clint Helfers, with permission. 16148// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ 16149jQuery.fn.delay = function( time, type ) { 16150 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 16151 type = type || "fx"; 16152 16153 return this.queue( type, function( next, hooks ) { 16154 var timeout = window.setTimeout( next, time ); 16155 hooks.stop = function() { 16156 window.clearTimeout( timeout ); 16157 }; 16158 } ); 16159}; 16160 16161 16162( function() { 16163 var input = document.createElement( "input" ), 16164 select = document.createElement( "select" ), 16165 opt = select.appendChild( document.createElement( "option" ) ); 16166 16167 input.type = "checkbox"; 16168 16169 // Support: Android <=4.3 only 16170 // Default value for a checkbox should be "on" 16171 support.checkOn = input.value !== ""; 16172 16173 // Support: IE <=11 only 16174 // Must access selectedIndex to make default options select 16175 support.optSelected = opt.selected; 16176 16177 // Support: IE <=11 only 16178 // An input loses its value after becoming a radio 16179 input = document.createElement( "input" ); 16180 input.value = "t"; 16181 input.type = "radio"; 16182 support.radioValue = input.value === "t"; 16183} )(); 16184 16185 16186var boolHook, 16187 attrHandle = jQuery.expr.attrHandle; 16188 16189jQuery.fn.extend( { 16190 attr: function( name, value ) { 16191 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 16192 }, 16193 16194 removeAttr: function( name ) { 16195 return this.each( function() { 16196 jQuery.removeAttr( this, name ); 16197 } ); 16198 } 16199} ); 16200 16201jQuery.extend( { 16202 attr: function( elem, name, value ) { 16203 var ret, hooks, 16204 nType = elem.nodeType; 16205 16206 // Don't get/set attributes on text, comment and attribute nodes 16207 if ( nType === 3 || nType === 8 || nType === 2 ) { 16208 return; 16209 } 16210 16211 // Fallback to prop when attributes are not supported 16212 if ( typeof elem.getAttribute === "undefined" ) { 16213 return jQuery.prop( elem, name, value ); 16214 } 16215 16216 // Attribute hooks are determined by the lowercase version 16217 // Grab necessary hook if one is defined 16218 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 16219 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 16220 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 16221 } 16222 16223 if ( value !== undefined ) { 16224 if ( value === null ) { 16225 jQuery.removeAttr( elem, name ); 16226 return; 16227 } 16228 16229 if ( hooks && "set" in hooks && 16230 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 16231 return ret; 16232 } 16233 16234 elem.setAttribute( name, value + "" ); 16235 return value; 16236 } 16237 16238 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 16239 return ret; 16240 } 16241 16242 ret = jQuery.find.attr( elem, name ); 16243 16244 // Non-existent attributes return null, we normalize to undefined 16245 return ret == null ? undefined : ret; 16246 }, 16247 16248 attrHooks: { 16249 type: { 16250 set: function( elem, value ) { 16251 if ( !support.radioValue && value === "radio" && 16252 nodeName( elem, "input" ) ) { 16253 var val = elem.value; 16254 elem.setAttribute( "type", value ); 16255 if ( val ) { 16256 elem.value = val; 16257 } 16258 return value; 16259 } 16260 } 16261 } 16262 }, 16263 16264 removeAttr: function( elem, value ) { 16265 var name, 16266 i = 0, 16267 16268 // Attribute names can contain non-HTML whitespace characters 16269 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 16270 attrNames = value && value.match( rnothtmlwhite ); 16271 16272 if ( attrNames && elem.nodeType === 1 ) { 16273 while ( ( name = attrNames[ i++ ] ) ) { 16274 elem.removeAttribute( name ); 16275 } 16276 } 16277 } 16278} ); 16279 16280// Hooks for boolean attributes 16281boolHook = { 16282 set: function( elem, value, name ) { 16283 if ( value === false ) { 16284 16285 // Remove boolean attributes when set to false 16286 jQuery.removeAttr( elem, name ); 16287 } else { 16288 elem.setAttribute( name, name ); 16289 } 16290 return name; 16291 } 16292}; 16293 16294jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { 16295 var getter = attrHandle[ name ] || jQuery.find.attr; 16296 16297 attrHandle[ name ] = function( elem, name, isXML ) { 16298 var ret, handle, 16299 lowercaseName = name.toLowerCase(); 16300 16301 if ( !isXML ) { 16302 16303 // Avoid an infinite loop by temporarily removing this function from the getter 16304 handle = attrHandle[ lowercaseName ]; 16305 attrHandle[ lowercaseName ] = ret; 16306 ret = getter( elem, name, isXML ) != null ? 16307 lowercaseName : 16308 null; 16309 attrHandle[ lowercaseName ] = handle; 16310 } 16311 return ret; 16312 }; 16313} ); 16314 16315 16316 16317 16318var rfocusable = /^(?:input|select|textarea|button)$/i, 16319 rclickable = /^(?:a|area)$/i; 16320 16321jQuery.fn.extend( { 16322 prop: function( name, value ) { 16323 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 16324 }, 16325 16326 removeProp: function( name ) { 16327 return this.each( function() { 16328 delete this[ jQuery.propFix[ name ] || name ]; 16329 } ); 16330 } 16331} ); 16332 16333jQuery.extend( { 16334 prop: function( elem, name, value ) { 16335 var ret, hooks, 16336 nType = elem.nodeType; 16337 16338 // Don't get/set properties on text, comment and attribute nodes 16339 if ( nType === 3 || nType === 8 || nType === 2 ) { 16340 return; 16341 } 16342 16343 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 16344 16345 // Fix name and attach hooks 16346 name = jQuery.propFix[ name ] || name; 16347 hooks = jQuery.propHooks[ name ]; 16348 } 16349 16350 if ( value !== undefined ) { 16351 if ( hooks && "set" in hooks && 16352 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 16353 return ret; 16354 } 16355 16356 return ( elem[ name ] = value ); 16357 } 16358 16359 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 16360 return ret; 16361 } 16362 16363 return elem[ name ]; 16364 }, 16365 16366 propHooks: { 16367 tabIndex: { 16368 get: function( elem ) { 16369 16370 // Support: IE <=9 - 11 only 16371 // elem.tabIndex doesn't always return the 16372 // correct value when it hasn't been explicitly set 16373 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 16374 // Use proper attribute retrieval(#12072) 16375 var tabindex = jQuery.find.attr( elem, "tabindex" ); 16376 16377 if ( tabindex ) { 16378 return parseInt( tabindex, 10 ); 16379 } 16380 16381 if ( 16382 rfocusable.test( elem.nodeName ) || 16383 rclickable.test( elem.nodeName ) && 16384 elem.href 16385 ) { 16386 return 0; 16387 } 16388 16389 return -1; 16390 } 16391 } 16392 }, 16393 16394 propFix: { 16395 "for": "htmlFor", 16396 "class": "className" 16397 } 16398} ); 16399 16400// Support: IE <=11 only 16401// Accessing the selectedIndex property 16402// forces the browser to respect setting selected 16403// on the option 16404// The getter ensures a default option is selected 16405// when in an optgroup 16406// eslint rule "no-unused-expressions" is disabled for this code 16407// since it considers such accessions noop 16408if ( !support.optSelected ) { 16409 jQuery.propHooks.selected = { 16410 get: function( elem ) { 16411 16412 /* eslint no-unused-expressions: "off" */ 16413 16414 var parent = elem.parentNode; 16415 if ( parent && parent.parentNode ) { 16416 parent.parentNode.selectedIndex; 16417 } 16418 return null; 16419 }, 16420 set: function( elem ) { 16421 16422 /* eslint no-unused-expressions: "off" */ 16423 16424 var parent = elem.parentNode; 16425 if ( parent ) { 16426 parent.selectedIndex; 16427 16428 if ( parent.parentNode ) { 16429 parent.parentNode.selectedIndex; 16430 } 16431 } 16432 } 16433 }; 16434} 16435 16436jQuery.each( [ 16437 "tabIndex", 16438 "readOnly", 16439 "maxLength", 16440 "cellSpacing", 16441 "cellPadding", 16442 "rowSpan", 16443 "colSpan", 16444 "useMap", 16445 "frameBorder", 16446 "contentEditable" 16447], function() { 16448 jQuery.propFix[ this.toLowerCase() ] = this; 16449} ); 16450 16451 16452 16453 16454 // Strip and collapse whitespace according to HTML spec 16455 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 16456 function stripAndCollapse( value ) { 16457 var tokens = value.match( rnothtmlwhite ) || []; 16458 return tokens.join( " " ); 16459 } 16460 16461 16462function getClass( elem ) { 16463 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 16464} 16465 16466function classesToArray( value ) { 16467 if ( Array.isArray( value ) ) { 16468 return value; 16469 } 16470 if ( typeof value === "string" ) { 16471 return value.match( rnothtmlwhite ) || []; 16472 } 16473 return []; 16474} 16475 16476jQuery.fn.extend( { 16477 addClass: function( value ) { 16478 var classes, elem, cur, curValue, clazz, j, finalValue, 16479 i = 0; 16480 16481 if ( isFunction( value ) ) { 16482 return this.each( function( j ) { 16483 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 16484 } ); 16485 } 16486 16487 classes = classesToArray( value ); 16488 16489 if ( classes.length ) { 16490 while ( ( elem = this[ i++ ] ) ) { 16491 curValue = getClass( elem ); 16492 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 16493 16494 if ( cur ) { 16495 j = 0; 16496 while ( ( clazz = classes[ j++ ] ) ) { 16497 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 16498 cur += clazz + " "; 16499 } 16500 } 16501 16502 // Only assign if different to avoid unneeded rendering. 16503 finalValue = stripAndCollapse( cur ); 16504 if ( curValue !== finalValue ) { 16505 elem.setAttribute( "class", finalValue ); 16506 } 16507 } 16508 } 16509 } 16510 16511 return this; 16512 }, 16513 16514 removeClass: function( value ) { 16515 var classes, elem, cur, curValue, clazz, j, finalValue, 16516 i = 0; 16517 16518 if ( isFunction( value ) ) { 16519 return this.each( function( j ) { 16520 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 16521 } ); 16522 } 16523 16524 if ( !arguments.length ) { 16525 return this.attr( "class", "" ); 16526 } 16527 16528 classes = classesToArray( value ); 16529 16530 if ( classes.length ) { 16531 while ( ( elem = this[ i++ ] ) ) { 16532 curValue = getClass( elem ); 16533 16534 // This expression is here for better compressibility (see addClass) 16535 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 16536 16537 if ( cur ) { 16538 j = 0; 16539 while ( ( clazz = classes[ j++ ] ) ) { 16540 16541 // Remove *all* instances 16542 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 16543 cur = cur.replace( " " + clazz + " ", " " ); 16544 } 16545 } 16546 16547 // Only assign if different to avoid unneeded rendering. 16548 finalValue = stripAndCollapse( cur ); 16549 if ( curValue !== finalValue ) { 16550 elem.setAttribute( "class", finalValue ); 16551 } 16552 } 16553 } 16554 } 16555 16556 return this; 16557 }, 16558 16559 toggleClass: function( value, stateVal ) { 16560 var type = typeof value, 16561 isValidValue = type === "string" || Array.isArray( value ); 16562 16563 if ( typeof stateVal === "boolean" && isValidValue ) { 16564 return stateVal ? this.addClass( value ) : this.removeClass( value ); 16565 } 16566 16567 if ( isFunction( value ) ) { 16568 return this.each( function( i ) { 16569 jQuery( this ).toggleClass( 16570 value.call( this, i, getClass( this ), stateVal ), 16571 stateVal 16572 ); 16573 } ); 16574 } 16575 16576 return this.each( function() { 16577 var className, i, self, classNames; 16578 16579 if ( isValidValue ) { 16580 16581 // Toggle individual class names 16582 i = 0; 16583 self = jQuery( this ); 16584 classNames = classesToArray( value ); 16585 16586 while ( ( className = classNames[ i++ ] ) ) { 16587 16588 // Check each className given, space separated list 16589 if ( self.hasClass( className ) ) { 16590 self.removeClass( className ); 16591 } else { 16592 self.addClass( className ); 16593 } 16594 } 16595 16596 // Toggle whole class name 16597 } else if ( value === undefined || type === "boolean" ) { 16598 className = getClass( this ); 16599 if ( className ) { 16600 16601 // Store className if set 16602 dataPriv.set( this, "__className__", className ); 16603 } 16604 16605 // If the element has a class name or if we're passed `false`, 16606 // then remove the whole classname (if there was one, the above saved it). 16607 // Otherwise bring back whatever was previously saved (if anything), 16608 // falling back to the empty string if nothing was stored. 16609 if ( this.setAttribute ) { 16610 this.setAttribute( "class", 16611 className || value === false ? 16612 "" : 16613 dataPriv.get( this, "__className__" ) || "" 16614 ); 16615 } 16616 } 16617 } ); 16618 }, 16619 16620 hasClass: function( selector ) { 16621 var className, elem, 16622 i = 0; 16623 16624 className = " " + selector + " "; 16625 while ( ( elem = this[ i++ ] ) ) { 16626 if ( elem.nodeType === 1 && 16627 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 16628 return true; 16629 } 16630 } 16631 16632 return false;
vendor: 5,544 bytes, lines 16633-16868
16633 } 16634} ); 16635 16636 16637 16638 16639var rreturn = /\r/g; 16640 16641jQuery.fn.extend( { 16642 val: function( value ) { 16643 var hooks, ret, valueIsFunction, 16644 elem = this[ 0 ]; 16645 16646 if ( !arguments.length ) { 16647 if ( elem ) { 16648 hooks = jQuery.valHooks[ elem.type ] || 16649 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 16650 16651 if ( hooks && 16652 "get" in hooks && 16653 ( ret = hooks.get( elem, "value" ) ) !== undefined 16654 ) { 16655 return ret; 16656 } 16657 16658 ret = elem.value; 16659 16660 // Handle most common string cases 16661 if ( typeof ret === "string" ) { 16662 return ret.replace( rreturn, "" ); 16663 } 16664 16665 // Handle cases where value is null/undef or number 16666 return ret == null ? "" : ret; 16667 } 16668 16669 return; 16670 } 16671 16672 valueIsFunction = isFunction( value ); 16673 16674 return this.each( function( i ) { 16675 var val; 16676 16677 if ( this.nodeType !== 1 ) { 16678 return; 16679 } 16680 16681 if ( valueIsFunction ) { 16682 val = value.call( this, i, jQuery( this ).val() ); 16683 } else { 16684 val = value; 16685 } 16686 16687 // Treat null/undefined as ""; convert numbers to string 16688 if ( val == null ) { 16689 val = ""; 16690 16691 } else if ( typeof val === "number" ) { 16692 val += ""; 16693 16694 } else if ( Array.isArray( val ) ) { 16695 val = jQuery.map( val, function( value ) { 16696 return value == null ? "" : value + ""; 16697 } ); 16698 } 16699 16700 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 16701 16702 // If set returns undefined, fall back to normal setting 16703 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 16704 this.value = val; 16705 } 16706 } ); 16707 } 16708} ); 16709 16710jQuery.extend( { 16711 valHooks: { 16712 option: { 16713 get: function( elem ) { 16714 16715 var val = jQuery.find.attr( elem, "value" ); 16716 return val != null ? 16717 val : 16718 16719 // Support: IE <=10 - 11 only 16720 // option.text throws exceptions (#14686, #14858) 16721 // Strip and collapse whitespace 16722 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 16723 stripAndCollapse( jQuery.text( elem ) ); 16724 } 16725 }, 16726 select: { 16727 get: function( elem ) { 16728 var value, option, i, 16729 options = elem.options, 16730 index = elem.selectedIndex, 16731 one = elem.type === "select-one", 16732 values = one ? null : [], 16733 max = one ? index + 1 : options.length; 16734 16735 if ( index < 0 ) { 16736 i = max; 16737 16738 } else { 16739 i = one ? index : 0; 16740 } 16741 16742 // Loop through all the selected options 16743 for ( ; i < max; i++ ) { 16744 option = options[ i ]; 16745 16746 // Support: IE <=9 only 16747 // IE8-9 doesn't update selected after form reset (#2551) 16748 if ( ( option.selected || i === index ) && 16749 16750 // Don't return options that are disabled or in a disabled optgroup 16751 !option.disabled && 16752 ( !option.parentNode.disabled || 16753 !nodeName( option.parentNode, "optgroup" ) ) ) { 16754 16755 // Get the specific value for the option 16756 value = jQuery( option ).val(); 16757 16758 // We don't need an array for one selects 16759 if ( one ) { 16760 return value; 16761 } 16762 16763 // Multi-Selects return an array 16764 values.push( value ); 16765 } 16766 } 16767 16768 return values; 16769 }, 16770 16771 set: function( elem, value ) { 16772 var optionSet, option, 16773 options = elem.options, 16774 values = jQuery.makeArray( value ), 16775 i = options.length; 16776 16777 while ( i-- ) { 16778 option = options[ i ]; 16779 16780 /* eslint-disable no-cond-assign */ 16781 16782 if ( option.selected = 16783 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 16784 ) { 16785 optionSet = true; 16786 } 16787 16788 /* eslint-enable no-cond-assign */ 16789 } 16790 16791 // Force browsers to behave consistently when non-matching value is set 16792 if ( !optionSet ) { 16793 elem.selectedIndex = -1; 16794 } 16795 return values; 16796 } 16797 } 16798 } 16799} ); 16800 16801// Radios and checkboxes getter/setter 16802jQuery.each( [ "radio", "checkbox" ], function() { 16803 jQuery.valHooks[ this ] = { 16804 set: function( elem, value ) { 16805 if ( Array.isArray( value ) ) { 16806 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 16807 } 16808 } 16809 }; 16810 if ( !support.checkOn ) { 16811 jQuery.valHooks[ this ].get = function( elem ) { 16812 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 16813 }; 16814 } 16815} ); 16816 16817 16818 16819 16820// Return jQuery for attributes-only inclusion 16821 16822 16823support.focusin = "onfocusin" in window; 16824 16825 16826var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 16827 stopPropagationCallback = function( e ) { 16828 e.stopPropagation(); 16829 }; 16830 16831jQuery.extend( jQuery.event, { 16832 16833 trigger: function( event, data, elem, onlyHandlers ) { 16834 16835 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 16836 eventPath = [ elem || document ], 16837 type = hasOwn.call( event, "type" ) ? event.type : event, 16838 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 16839 16840 cur = lastElement = tmp = elem = elem || document; 16841 16842 // Don't do events on text and comment nodes 16843 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 16844 return; 16845 } 16846 16847 // focus/blur morphs to focusin/out; ensure we're not firing them right now 16848 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 16849 return; 16850 } 16851 16852 if ( type.indexOf( "." ) > -1 ) { 16853 16854 // Namespaced trigger; create a regexp to match event type in handle() 16855 namespaces = type.split( "." ); 16856 type = namespaces.shift(); 16857 namespaces.sort(); 16858 } 16859 ontype = type.indexOf( ":" ) < 0 && "on" + type; 16860 16861 // Caller can pass in a jQuery.Event object, Object, or just an event type string 16862 event = event[ jQuery.expando ] ? 16863 event : 16864 new jQuery.Event( type, typeof event === "object" && event ); 16865 16866 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 16867 event.isTrigger = onlyHandlers ? 2 : 3; 16868 event.namespace = namespaces.join( "." );
vendor: 32,532 bytes, lines 16869-18140
16869 event.rnamespace = event.namespace ? 16870 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 16871 null; 16872 16873 // Clean up the event in case it is being reused 16874 event.result = undefined; 16875 if ( !event.target ) { 16876 event.target = elem; 16877 } 16878 16879 // Clone any incoming data and prepend the event, creating the handler arg list 16880 data = data == null ? 16881 [ event ] : 16882 jQuery.makeArray( data, [ event ] ); 16883 16884 // Allow special events to draw outside the lines 16885 special = jQuery.event.special[ type ] || {}; 16886 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 16887 return; 16888 } 16889 16890 // Determine event propagation path in advance, per W3C events spec (#9951) 16891 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 16892 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 16893 16894 bubbleType = special.delegateType || type; 16895 if ( !rfocusMorph.test( bubbleType + type ) ) { 16896 cur = cur.parentNode; 16897 } 16898 for ( ; cur; cur = cur.parentNode ) { 16899 eventPath.push( cur ); 16900 tmp = cur; 16901 } 16902 16903 // Only add window if we got to document (e.g., not plain obj or detached DOM) 16904 if ( tmp === ( elem.ownerDocument || document ) ) { 16905 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 16906 } 16907 } 16908 16909 // Fire handlers on the event path 16910 i = 0; 16911 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 16912 lastElement = cur; 16913 event.type = i > 1 ? 16914 bubbleType : 16915 special.bindType || type; 16916 16917 // jQuery handler 16918 handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && 16919 dataPriv.get( cur, "handle" ); 16920 if ( handle ) { 16921 handle.apply( cur, data ); 16922 } 16923 16924 // Native handler 16925 handle = ontype && cur[ ontype ]; 16926 if ( handle && handle.apply && acceptData( cur ) ) { 16927 event.result = handle.apply( cur, data ); 16928 if ( event.result === false ) { 16929 event.preventDefault(); 16930 } 16931 } 16932 } 16933 event.type = type; 16934 16935 // If nobody prevented the default action, do it now 16936 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 16937 16938 if ( ( !special._default || 16939 special._default.apply( eventPath.pop(), data ) === false ) && 16940 acceptData( elem ) ) { 16941 16942 // Call a native DOM method on the target with the same name as the event. 16943 // Don't do default actions on window, that's where global variables be (#6170) 16944 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 16945 16946 // Don't re-trigger an onFOO event when we call its FOO() method 16947 tmp = elem[ ontype ]; 16948 16949 if ( tmp ) { 16950 elem[ ontype ] = null; 16951 } 16952 16953 // Prevent re-triggering of the same event, since we already bubbled it above 16954 jQuery.event.triggered = type; 16955 16956 if ( event.isPropagationStopped() ) { 16957 lastElement.addEventListener( type, stopPropagationCallback ); 16958 } 16959 16960 elem[ type ](); 16961 16962 if ( event.isPropagationStopped() ) { 16963 lastElement.removeEventListener( type, stopPropagationCallback ); 16964 } 16965 16966 jQuery.event.triggered = undefined; 16967 16968 if ( tmp ) { 16969 elem[ ontype ] = tmp; 16970 } 16971 } 16972 } 16973 } 16974 16975 return event.result; 16976 }, 16977 16978 // Piggyback on a donor event to simulate a different one 16979 // Used only for `focus(in | out)` events 16980 simulate: function( type, elem, event ) { 16981 var e = jQuery.extend( 16982 new jQuery.Event(), 16983 event, 16984 { 16985 type: type, 16986 isSimulated: true 16987 } 16988 ); 16989 16990 jQuery.event.trigger( e, null, elem ); 16991 } 16992 16993} ); 16994 16995jQuery.fn.extend( { 16996 16997 trigger: function( type, data ) { 16998 return this.each( function() { 16999 jQuery.event.trigger( type, data, this ); 17000 } ); 17001 }, 17002 triggerHandler: function( type, data ) { 17003 var elem = this[ 0 ]; 17004 if ( elem ) { 17005 return jQuery.event.trigger( type, data, elem, true ); 17006 } 17007 } 17008} ); 17009 17010 17011// Support: Firefox <=44 17012// Firefox doesn't have focus(in | out) events 17013// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 17014// 17015// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 17016// focus(in | out) events fire after focus & blur events, 17017// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 17018// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 17019if ( !support.focusin ) { 17020 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 17021 17022 // Attach a single capturing handler on the document while someone wants focusin/focusout 17023 var handler = function( event ) { 17024 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 17025 }; 17026 17027 jQuery.event.special[ fix ] = { 17028 setup: function() { 17029 var doc = this.ownerDocument || this, 17030 attaches = dataPriv.access( doc, fix ); 17031 17032 if ( !attaches ) { 17033 doc.addEventListener( orig, handler, true ); 17034 } 17035 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 17036 }, 17037 teardown: function() { 17038 var doc = this.ownerDocument || this, 17039 attaches = dataPriv.access( doc, fix ) - 1; 17040 17041 if ( !attaches ) { 17042 doc.removeEventListener( orig, handler, true ); 17043 dataPriv.remove( doc, fix ); 17044 17045 } else { 17046 dataPriv.access( doc, fix, attaches ); 17047 } 17048 } 17049 }; 17050 } ); 17051} 17052var location = window.location; 17053 17054var nonce = Date.now(); 17055 17056var rquery = ( /\?/ ); 17057 17058 17059 17060// Cross-browser xml parsing 17061jQuery.parseXML = function( data ) { 17062 var xml; 17063 if ( !data || typeof data !== "string" ) { 17064 return null; 17065 } 17066 17067 // Support: IE 9 - 11 only 17068 // IE throws on parseFromString with invalid input. 17069 try { 17070 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 17071 } catch ( e ) { 17072 xml = undefined; 17073 } 17074 17075 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { 17076 jQuery.error( "Invalid XML: " + data ); 17077 } 17078 return xml; 17079}; 17080 17081 17082var 17083 rbracket = /\[\]$/, 17084 rCRLF = /\r?\n/g, 17085 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 17086 rsubmittable = /^(?:input|select|textarea|keygen)/i; 17087 17088function buildParams( prefix, obj, traditional, add ) { 17089 var name; 17090 17091 if ( Array.isArray( obj ) ) { 17092 17093 // Serialize array item. 17094 jQuery.each( obj, function( i, v ) { 17095 if ( traditional || rbracket.test( prefix ) ) { 17096 17097 // Treat each array item as a scalar. 17098 add( prefix, v ); 17099 17100 } else { 17101 17102 // Item is non-scalar (array or object), encode its numeric index. 17103 buildParams( 17104 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 17105 v, 17106 traditional, 17107 add 17108 ); 17109 } 17110 } ); 17111 17112 } else if ( !traditional && toType( obj ) === "object" ) { 17113 17114 // Serialize object item. 17115 for ( name in obj ) { 17116 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 17117 } 17118 17119 } else { 17120 17121 // Serialize scalar item. 17122 add( prefix, obj ); 17123 } 17124} 17125 17126// Serialize an array of form elements or a set of 17127// key/values into a query string 17128jQuery.param = function( a, traditional ) { 17129 var prefix, 17130 s = [], 17131 add = function( key, valueOrFunction ) { 17132 17133 // If value is a function, invoke it and use its return value 17134 var value = isFunction( valueOrFunction ) ? 17135 valueOrFunction() : 17136 valueOrFunction; 17137 17138 s[ s.length ] = encodeURIComponent( key ) + "=" + 17139 encodeURIComponent( value == null ? "" : value ); 17140 }; 17141 17142 // If an array was passed in, assume that it is an array of form elements. 17143 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 17144 17145 // Serialize the form elements 17146 jQuery.each( a, function() { 17147 add( this.name, this.value ); 17148 } ); 17149 17150 } else { 17151 17152 // If traditional, encode the "old" way (the way 1.3.2 or older 17153 // did it), otherwise encode params recursively. 17154 for ( prefix in a ) { 17155 buildParams( prefix, a[ prefix ], traditional, add ); 17156 } 17157 } 17158 17159 // Return the resulting serialization 17160 return s.join( "&" ); 17161}; 17162 17163jQuery.fn.extend( { 17164 serialize: function() { 17165 return jQuery.param( this.serializeArray() ); 17166 }, 17167 serializeArray: function() { 17168 return this.map( function() { 17169 17170 // Can add propHook for "elements" to filter or add form elements 17171 var elements = jQuery.prop( this, "elements" ); 17172 return elements ? jQuery.makeArray( elements ) : this; 17173 } ) 17174 .filter( function() { 17175 var type = this.type; 17176 17177 // Use .is( ":disabled" ) so that fieldset[disabled] works 17178 return this.name && !jQuery( this ).is( ":disabled" ) && 17179 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 17180 ( this.checked || !rcheckableType.test( type ) ); 17181 } ) 17182 .map( function( i, elem ) { 17183 var val = jQuery( this ).val(); 17184 17185 if ( val == null ) { 17186 return null; 17187 } 17188 17189 if ( Array.isArray( val ) ) { 17190 return jQuery.map( val, function( val ) { 17191 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 17192 } ); 17193 } 17194 17195 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 17196 } ).get(); 17197 } 17198} ); 17199 17200 17201var 17202 r20 = /%20/g, 17203 rhash = /#.*$/, 17204 rantiCache = /([?&])_=[^&]*/, 17205 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 17206 17207 // #7653, #8125, #8152: local protocol detection 17208 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 17209 rnoContent = /^(?:GET|HEAD)$/, 17210 rprotocol = /^\/\//, 17211 17212 /* Prefilters 17213 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 17214 * 2) These are called: 17215 * - BEFORE asking for a transport 17216 * - AFTER param serialization (s.data is a string if s.processData is true) 17217 * 3) key is the dataType 17218 * 4) the catchall symbol "*" can be used 17219 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 17220 */ 17221 prefilters = {}, 17222 17223 /* Transports bindings 17224 * 1) key is the dataType 17225 * 2) the catchall symbol "*" can be used 17226 * 3) selection will start with transport dataType and THEN go to "*" if needed 17227 */ 17228 transports = {}, 17229 17230 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 17231 allTypes = "*/".concat( "*" ), 17232 17233 // Anchor tag for parsing the document origin 17234 originAnchor = document.createElement( "a" ); 17235 originAnchor.href = location.href; 17236 17237// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 17238function addToPrefiltersOrTransports( structure ) { 17239 17240 // dataTypeExpression is optional and defaults to "*" 17241 return function( dataTypeExpression, func ) { 17242 17243 if ( typeof dataTypeExpression !== "string" ) { 17244 func = dataTypeExpression; 17245 dataTypeExpression = "*"; 17246 } 17247 17248 var dataType, 17249 i = 0, 17250 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 17251 17252 if ( isFunction( func ) ) { 17253 17254 // For each dataType in the dataTypeExpression 17255 while ( ( dataType = dataTypes[ i++ ] ) ) { 17256 17257 // Prepend if requested 17258 if ( dataType[ 0 ] === "+" ) { 17259 dataType = dataType.slice( 1 ) || "*"; 17260 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 17261 17262 // Otherwise append 17263 } else { 17264 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 17265 } 17266 } 17267 } 17268 }; 17269} 17270 17271// Base inspection function for prefilters and transports 17272function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 17273 17274 var inspected = {}, 17275 seekingTransport = ( structure === transports ); 17276 17277 function inspect( dataType ) { 17278 var selected; 17279 inspected[ dataType ] = true; 17280 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 17281 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 17282 if ( typeof dataTypeOrTransport === "string" && 17283 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 17284 17285 options.dataTypes.unshift( dataTypeOrTransport ); 17286 inspect( dataTypeOrTransport ); 17287 return false; 17288 } else if ( seekingTransport ) { 17289 return !( selected = dataTypeOrTransport ); 17290 } 17291 } ); 17292 return selected; 17293 } 17294 17295 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 17296} 17297 17298// A special extend for ajax options 17299// that takes "flat" options (not to be deep extended) 17300// Fixes #9887 17301function ajaxExtend( target, src ) { 17302 var key, deep, 17303 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 17304 17305 for ( key in src ) { 17306 if ( src[ key ] !== undefined ) { 17307 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 17308 } 17309 } 17310 if ( deep ) { 17311 jQuery.extend( true, target, deep ); 17312 } 17313 17314 return target; 17315} 17316 17317/* Handles responses to an ajax request: 17318 * - finds the right dataType (mediates between content-type and expected dataType) 17319 * - returns the corresponding response 17320 */ 17321function ajaxHandleResponses( s, jqXHR, responses ) { 17322 17323 var ct, type, finalDataType, firstDataType, 17324 contents = s.contents, 17325 dataTypes = s.dataTypes; 17326 17327 // Remove auto dataType and get content-type in the process 17328 while ( dataTypes[ 0 ] === "*" ) { 17329 dataTypes.shift(); 17330 if ( ct === undefined ) { 17331 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 17332 } 17333 } 17334 17335 // Check if we're dealing with a known content-type 17336 if ( ct ) { 17337 for ( type in contents ) { 17338 if ( contents[ type ] && contents[ type ].test( ct ) ) { 17339 dataTypes.unshift( type ); 17340 break; 17341 } 17342 } 17343 } 17344 17345 // Check to see if we have a response for the expected dataType 17346 if ( dataTypes[ 0 ] in responses ) { 17347 finalDataType = dataTypes[ 0 ]; 17348 } else { 17349 17350 // Try convertible dataTypes 17351 for ( type in responses ) { 17352 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 17353 finalDataType = type; 17354 break; 17355 } 17356 if ( !firstDataType ) { 17357 firstDataType = type; 17358 } 17359 } 17360 17361 // Or just use first one 17362 finalDataType = finalDataType || firstDataType; 17363 } 17364 17365 // If we found a dataType 17366 // We add the dataType to the list if needed 17367 // and return the corresponding response 17368 if ( finalDataType ) { 17369 if ( finalDataType !== dataTypes[ 0 ] ) { 17370 dataTypes.unshift( finalDataType ); 17371 } 17372 return responses[ finalDataType ]; 17373 } 17374} 17375 17376/* Chain conversions given the request and the original response 17377 * Also sets the responseXXX fields on the jqXHR instance 17378 */ 17379function ajaxConvert( s, response, jqXHR, isSuccess ) { 17380 var conv2, current, conv, tmp, prev, 17381 converters = {}, 17382 17383 // Work with a copy of dataTypes in case we need to modify it for conversion 17384 dataTypes = s.dataTypes.slice(); 17385 17386 // Create converters map with lowercased keys 17387 if ( dataTypes[ 1 ] ) { 17388 for ( conv in s.converters ) { 17389 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 17390 } 17391 } 17392 17393 current = dataTypes.shift(); 17394 17395 // Convert to each sequential dataType 17396 while ( current ) { 17397 17398 if ( s.responseFields[ current ] ) { 17399 jqXHR[ s.responseFields[ current ] ] = response; 17400 } 17401 17402 // Apply the dataFilter if provided 17403 if ( !prev && isSuccess && s.dataFilter ) { 17404 response = s.dataFilter( response, s.dataType ); 17405 } 17406 17407 prev = current; 17408 current = dataTypes.shift(); 17409 17410 if ( current ) { 17411 17412 // There's only work to do if current dataType is non-auto 17413 if ( current === "*" ) { 17414 17415 current = prev; 17416 17417 // Convert response if prev dataType is non-auto and differs from current 17418 } else if ( prev !== "*" && prev !== current ) { 17419 17420 // Seek a direct converter 17421 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 17422 17423 // If none found, seek a pair 17424 if ( !conv ) { 17425 for ( conv2 in converters ) { 17426 17427 // If conv2 outputs current 17428 tmp = conv2.split( " " ); 17429 if ( tmp[ 1 ] === current ) { 17430 17431 // If prev can be converted to accepted input 17432 conv = converters[ prev + " " + tmp[ 0 ] ] || 17433 converters[ "* " + tmp[ 0 ] ]; 17434 if ( conv ) { 17435 17436 // Condense equivalence converters 17437 if ( conv === true ) { 17438 conv = converters[ conv2 ]; 17439 17440 // Otherwise, insert the intermediate dataType 17441 } else if ( converters[ conv2 ] !== true ) { 17442 current = tmp[ 0 ]; 17443 dataTypes.unshift( tmp[ 1 ] ); 17444 } 17445 break; 17446 } 17447 } 17448 } 17449 } 17450 17451 // Apply converter (if not an equivalence) 17452 if ( conv !== true ) { 17453 17454 // Unless errors are allowed to bubble, catch and return them 17455 if ( conv && s.throws ) { 17456 response = conv( response ); 17457 } else { 17458 try { 17459 response = conv( response ); 17460 } catch ( e ) { 17461 return { 17462 state: "parsererror", 17463 error: conv ? e : "No conversion from " + prev + " to " + current 17464 }; 17465 } 17466 } 17467 } 17468 } 17469 } 17470 } 17471 17472 return { state: "success", data: response }; 17473} 17474 17475jQuery.extend( { 17476 17477 // Counter for holding the number of active queries 17478 active: 0, 17479 17480 // Last-Modified header cache for next request 17481 lastModified: {}, 17482 etag: {}, 17483 17484 ajaxSettings: { 17485 url: location.href, 17486 type: "GET", 17487 isLocal: rlocalProtocol.test( location.protocol ), 17488 global: true, 17489 processData: true, 17490 async: true, 17491 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 17492 17493 /* 17494 timeout: 0, 17495 data: null, 17496 dataType: null, 17497 username: null, 17498 password: null, 17499 cache: null, 17500 throws: false, 17501 traditional: false, 17502 headers: {}, 17503 */ 17504 17505 accepts: { 17506 "*": allTypes, 17507 text: "text/plain", 17508 html: "text/html", 17509 xml: "application/xml, text/xml", 17510 json: "application/json, text/javascript" 17511 }, 17512 17513 contents: { 17514 xml: /\bxml\b/, 17515 html: /\bhtml/, 17516 json: /\bjson\b/ 17517 }, 17518 17519 responseFields: { 17520 xml: "responseXML", 17521 text: "responseText", 17522 json: "responseJSON" 17523 }, 17524 17525 // Data converters 17526 // Keys separate source (or catchall "*") and destination types with a single space 17527 converters: { 17528 17529 // Convert anything to text 17530 "* text": String, 17531 17532 // Text to html (true = no transformation) 17533 "text html": true, 17534 17535 // Evaluate text as a json expression 17536 "text json": JSON.parse, 17537 17538 // Parse text as xml 17539 "text xml": jQuery.parseXML 17540 }, 17541 17542 // For options that shouldn't be deep extended: 17543 // you can add your own custom options here if 17544 // and when you create one that shouldn't be 17545 // deep extended (see ajaxExtend) 17546 flatOptions: { 17547 url: true, 17548 context: true 17549 } 17550 }, 17551 17552 // Creates a full fledged settings object into target 17553 // with both ajaxSettings and settings fields. 17554 // If target is omitted, writes into ajaxSettings. 17555 ajaxSetup: function( target, settings ) { 17556 return settings ? 17557 17558 // Building a settings object 17559 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 17560 17561 // Extending ajaxSettings 17562 ajaxExtend( jQuery.ajaxSettings, target ); 17563 }, 17564 17565 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 17566 ajaxTransport: addToPrefiltersOrTransports( transports ), 17567 17568 // Main method 17569 ajax: function( url, options ) { 17570 17571 // If url is an object, simulate pre-1.5 signature 17572 if ( typeof url === "object" ) { 17573 options = url; 17574 url = undefined; 17575 } 17576 17577 // Force options to be an object 17578 options = options || {}; 17579 17580 var transport, 17581 17582 // URL without anti-cache param 17583 cacheURL, 17584 17585 // Response headers 17586 responseHeadersString, 17587 responseHeaders, 17588 17589 // timeout handle 17590 timeoutTimer, 17591 17592 // Url cleanup var 17593 urlAnchor, 17594 17595 // Request state (becomes false upon send and true upon completion) 17596 completed, 17597 17598 // To know if global events are to be dispatched 17599 fireGlobals, 17600 17601 // Loop variable 17602 i, 17603 17604 // uncached part of the url 17605 uncached, 17606 17607 // Create the final options object 17608 s = jQuery.ajaxSetup( {}, options ), 17609 17610 // Callbacks context 17611 callbackContext = s.context || s, 17612 17613 // Context for global events is callbackContext if it is a DOM node or jQuery collection 17614 globalEventContext = s.context && 17615 ( callbackContext.nodeType || callbackContext.jquery ) ? 17616 jQuery( callbackContext ) : 17617 jQuery.event, 17618 17619 // Deferreds 17620 deferred = jQuery.Deferred(), 17621 completeDeferred = jQuery.Callbacks( "once memory" ), 17622 17623 // Status-dependent callbacks 17624 statusCode = s.statusCode || {}, 17625 17626 // Headers (they are sent all at once) 17627 requestHeaders = {}, 17628 requestHeadersNames = {}, 17629 17630 // Default abort message 17631 strAbort = "canceled", 17632 17633 // Fake xhr 17634 jqXHR = { 17635 readyState: 0, 17636 17637 // Builds headers hashtable if needed 17638 getResponseHeader: function( key ) { 17639 var match; 17640 if ( completed ) { 17641 if ( !responseHeaders ) { 17642 responseHeaders = {}; 17643 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 17644 responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; 17645 } 17646 } 17647 match = responseHeaders[ key.toLowerCase() ]; 17648 } 17649 return match == null ? null : match; 17650 }, 17651 17652 // Raw string 17653 getAllResponseHeaders: function() { 17654 return completed ? responseHeadersString : null; 17655 }, 17656 17657 // Caches the header 17658 setRequestHeader: function( name, value ) { 17659 if ( completed == null ) { 17660 name = requestHeadersNames[ name.toLowerCase() ] = 17661 requestHeadersNames[ name.toLowerCase() ] || name; 17662 requestHeaders[ name ] = value; 17663 } 17664 return this; 17665 }, 17666 17667 // Overrides response content-type header 17668 overrideMimeType: function( type ) { 17669 if ( completed == null ) { 17670 s.mimeType = type; 17671 } 17672 return this; 17673 }, 17674 17675 // Status-dependent callbacks 17676 statusCode: function( map ) { 17677 var code; 17678 if ( map ) { 17679 if ( completed ) { 17680 17681 // Execute the appropriate callbacks 17682 jqXHR.always( map[ jqXHR.status ] ); 17683 } else { 17684 17685 // Lazy-add the new callbacks in a way that preserves old ones 17686 for ( code in map ) { 17687 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 17688 } 17689 } 17690 } 17691 return this; 17692 }, 17693 17694 // Cancel the request 17695 abort: function( statusText ) { 17696 var finalText = statusText || strAbort; 17697 if ( transport ) { 17698 transport.abort( finalText ); 17699 } 17700 done( 0, finalText ); 17701 return this; 17702 } 17703 }; 17704 17705 // Attach deferreds 17706 deferred.promise( jqXHR ); 17707 17708 // Add protocol if not provided (prefilters might expect it) 17709 // Handle falsy url in the settings object (#10093: consistency with old signature) 17710 // We also use the url parameter if available 17711 s.url = ( ( url || s.url || location.href ) + "" ) 17712 .replace( rprotocol, location.protocol + "//" ); 17713 17714 // Alias method option to type as per ticket #12004 17715 s.type = options.method || options.type || s.method || s.type; 17716 17717 // Extract dataTypes list 17718 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 17719 17720 // A cross-domain request is in order when the origin doesn't match the current origin. 17721 if ( s.crossDomain == null ) { 17722 urlAnchor = document.createElement( "a" ); 17723 17724 // Support: IE <=8 - 11, Edge 12 - 15 17725 // IE throws exception on accessing the href property if url is malformed, 17726 // e.g. http://example.com:80x/ 17727 try { 17728 urlAnchor.href = s.url; 17729 17730 // Support: IE <=8 - 11 only 17731 // Anchor's host property isn't correctly set when s.url is relative 17732 urlAnchor.href = urlAnchor.href; 17733 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 17734 urlAnchor.protocol + "//" + urlAnchor.host; 17735 } catch ( e ) { 17736 17737 // If there is an error parsing the URL, assume it is crossDomain, 17738 // it can be rejected by the transport if it is invalid 17739 s.crossDomain = true; 17740 } 17741 } 17742 17743 // Convert data if not already a string 17744 if ( s.data && s.processData && typeof s.data !== "string" ) { 17745 s.data = jQuery.param( s.data, s.traditional ); 17746 } 17747 17748 // Apply prefilters 17749 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 17750 17751 // If request was aborted inside a prefilter, stop there 17752 if ( completed ) { 17753 return jqXHR; 17754 } 17755 17756 // We can fire global events as of now if asked to 17757 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 17758 fireGlobals = jQuery.event && s.global; 17759 17760 // Watch for a new set of requests 17761 if ( fireGlobals && jQuery.active++ === 0 ) { 17762 jQuery.event.trigger( "ajaxStart" ); 17763 } 17764 17765 // Uppercase the type 17766 s.type = s.type.toUpperCase(); 17767 17768 // Determine if request has content 17769 s.hasContent = !rnoContent.test( s.type ); 17770 17771 // Save the URL in case we're toying with the If-Modified-Since 17772 // and/or If-None-Match header later on 17773 // Remove hash to simplify url manipulation 17774 cacheURL = s.url.replace( rhash, "" ); 17775 17776 // More options handling for requests with no content 17777 if ( !s.hasContent ) { 17778 17779 // Remember the hash so we can put it back 17780 uncached = s.url.slice( cacheURL.length ); 17781 17782 // If data is available and should be processed, append data to url 17783 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 17784 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 17785 17786 // #9682: remove data so that it's not used in an eventual retry 17787 delete s.data; 17788 } 17789 17790 // Add or update anti-cache param if needed 17791 if ( s.cache === false ) { 17792 cacheURL = cacheURL.replace( rantiCache, "$1" ); 17793 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; 17794 } 17795 17796 // Put hash and anti-cache on the URL that will be requested (gh-1732) 17797 s.url = cacheURL + uncached; 17798 17799 // Change '%20' to '+' if this is encoded form body content (gh-2658) 17800 } else if ( s.data && s.processData && 17801 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 17802 s.data = s.data.replace( r20, "+" ); 17803 } 17804 17805 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 17806 if ( s.ifModified ) { 17807 if ( jQuery.lastModified[ cacheURL ] ) { 17808 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 17809 } 17810 if ( jQuery.etag[ cacheURL ] ) { 17811 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 17812 } 17813 } 17814 17815 // Set the correct header, if data is being sent 17816 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 17817 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 17818 } 17819 17820 // Set the Accepts header for the server, depending on the dataType 17821 jqXHR.setRequestHeader( 17822 "Accept", 17823 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 17824 s.accepts[ s.dataTypes[ 0 ] ] + 17825 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 17826 s.accepts[ "*" ] 17827 ); 17828 17829 // Check for headers option 17830 for ( i in s.headers ) { 17831 jqXHR.setRequestHeader( i, s.headers[ i ] ); 17832 } 17833 17834 // Allow custom headers/mimetypes and early abort 17835 if ( s.beforeSend && 17836 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 17837 17838 // Abort if not done already and return 17839 return jqXHR.abort(); 17840 } 17841 17842 // Aborting is no longer a cancellation 17843 strAbort = "abort"; 17844 17845 // Install callbacks on deferreds 17846 completeDeferred.add( s.complete ); 17847 jqXHR.done( s.success ); 17848 jqXHR.fail( s.error ); 17849 17850 // Get transport 17851 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 17852 17853 // If no transport, we auto-abort 17854 if ( !transport ) { 17855 done( -1, "No Transport" ); 17856 } else { 17857 jqXHR.readyState = 1; 17858 17859 // Send global event 17860 if ( fireGlobals ) { 17861 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 17862 } 17863 17864 // If request was aborted inside ajaxSend, stop there 17865 if ( completed ) { 17866 return jqXHR; 17867 } 17868 17869 // Timeout 17870 if ( s.async && s.timeout > 0 ) { 17871 timeoutTimer = window.setTimeout( function() { 17872 jqXHR.abort( "timeout" ); 17873 }, s.timeout ); 17874 } 17875 17876 try { 17877 completed = false; 17878 transport.send( requestHeaders, done ); 17879 } catch ( e ) { 17880 17881 // Rethrow post-completion exceptions 17882 if ( completed ) { 17883 throw e; 17884 } 17885 17886 // Propagate others as results 17887 done( -1, e ); 17888 } 17889 } 17890 17891 // Callback for when everything is done 17892 function done( status, nativeStatusText, responses, headers ) { 17893 var isSuccess, success, error, response, modified, 17894 statusText = nativeStatusText; 17895 17896 // Ignore repeat invocations 17897 if ( completed ) { 17898 return; 17899 } 17900 17901 completed = true; 17902 17903 // Clear timeout if it exists 17904 if ( timeoutTimer ) { 17905 window.clearTimeout( timeoutTimer ); 17906 } 17907 17908 // Dereference transport for early garbage collection 17909 // (no matter how long the jqXHR object will be used) 17910 transport = undefined; 17911 17912 // Cache response headers 17913 responseHeadersString = headers || ""; 17914 17915 // Set readyState 17916 jqXHR.readyState = status > 0 ? 4 : 0; 17917 17918 // Determine if successful 17919 isSuccess = status >= 200 && status < 300 || status === 304; 17920 17921 // Get response data 17922 if ( responses ) { 17923 response = ajaxHandleResponses( s, jqXHR, responses ); 17924 } 17925 17926 // Convert no matter what (that way responseXXX fields are always set) 17927 response = ajaxConvert( s, response, jqXHR, isSuccess ); 17928 17929 // If successful, handle type chaining 17930 if ( isSuccess ) { 17931 17932 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 17933 if ( s.ifModified ) { 17934 modified = jqXHR.getResponseHeader( "Last-Modified" ); 17935 if ( modified ) { 17936 jQuery.lastModified[ cacheURL ] = modified; 17937 } 17938 modified = jqXHR.getResponseHeader( "etag" ); 17939 if ( modified ) { 17940 jQuery.etag[ cacheURL ] = modified; 17941 } 17942 } 17943 17944 // if no content 17945 if ( status === 204 || s.type === "HEAD" ) { 17946 statusText = "nocontent"; 17947 17948 // if not modified 17949 } else if ( status === 304 ) { 17950 statusText = "notmodified"; 17951 17952 // If we have data, let's convert it 17953 } else { 17954 statusText = response.state; 17955 success = response.data; 17956 error = response.error; 17957 isSuccess = !error; 17958 } 17959 } else { 17960 17961 // Extract error from statusText and normalize for non-aborts 17962 error = statusText; 17963 if ( status || !statusText ) { 17964 statusText = "error"; 17965 if ( status < 0 ) { 17966 status = 0; 17967 } 17968 } 17969 } 17970 17971 // Set data for the fake xhr object 17972 jqXHR.status = status; 17973 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 17974 17975 // Success/Error 17976 if ( isSuccess ) { 17977 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 17978 } else { 17979 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 17980 } 17981 17982 // Status-dependent callbacks 17983 jqXHR.statusCode( statusCode ); 17984 statusCode = undefined; 17985 17986 if ( fireGlobals ) { 17987 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 17988 [ jqXHR, s, isSuccess ? success : error ] ); 17989 } 17990 17991 // Complete 17992 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 17993 17994 if ( fireGlobals ) { 17995 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 17996 17997 // Handle the global AJAX counter 17998 if ( !( --jQuery.active ) ) { 17999 jQuery.event.trigger( "ajaxStop" ); 18000 } 18001 } 18002 } 18003 18004 return jqXHR; 18005 }, 18006 18007 getJSON: function( url, data, callback ) { 18008 return jQuery.get( url, data, callback, "json" ); 18009 }, 18010 18011 getScript: function( url, callback ) { 18012 return jQuery.get( url, undefined, callback, "script" ); 18013 } 18014} ); 18015 18016jQuery.each( [ "get", "post" ], function( i, method ) { 18017 jQuery[ method ] = function( url, data, callback, type ) { 18018 18019 // Shift arguments if data argument was omitted 18020 if ( isFunction( data ) ) { 18021 type = type || callback; 18022 callback = data; 18023 data = undefined; 18024 } 18025 18026 // The url can be an options object (which then must have .url) 18027 return jQuery.ajax( jQuery.extend( { 18028 url: url, 18029 type: method, 18030 dataType: type, 18031 data: data, 18032 success: callback 18033 }, jQuery.isPlainObject( url ) && url ) ); 18034 }; 18035} ); 18036 18037 18038jQuery._evalUrl = function( url ) { 18039 return jQuery.ajax( { 18040 url: url, 18041 18042 // Make this explicit, since user can override this through ajaxSetup (#11264) 18043 type: "GET", 18044 dataType: "script", 18045 cache: true, 18046 async: false, 18047 global: false, 18048 "throws": true 18049 } ); 18050}; 18051 18052 18053jQuery.fn.extend( { 18054 wrapAll: function( html ) { 18055 var wrap; 18056 18057 if ( this[ 0 ] ) { 18058 if ( isFunction( html ) ) { 18059 html = html.call( this[ 0 ] ); 18060 } 18061 18062 // The elements to wrap the target around 18063 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 18064 18065 if ( this[ 0 ].parentNode ) { 18066 wrap.insertBefore( this[ 0 ] ); 18067 } 18068 18069 wrap.map( function() { 18070 var elem = this; 18071 18072 while ( elem.firstElementChild ) { 18073 elem = elem.firstElementChild; 18074 } 18075 18076 return elem; 18077 } ).append( this ); 18078 } 18079 18080 return this; 18081 }, 18082 18083 wrapInner: function( html ) { 18084 if ( isFunction( html ) ) { 18085 return this.each( function( i ) { 18086 jQuery( this ).wrapInner( html.call( this, i ) ); 18087 } ); 18088 } 18089 18090 return this.each( function() { 18091 var self = jQuery( this ), 18092 contents = self.contents(); 18093 18094 if ( contents.length ) { 18095 contents.wrapAll( html ); 18096 18097 } else { 18098 self.append( html ); 18099 } 18100 } ); 18101 }, 18102 18103 wrap: function( html ) { 18104 var htmlIsFunction = isFunction( html ); 18105 18106 return this.each( function( i ) { 18107 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 18108 } ); 18109 }, 18110 18111 unwrap: function( selector ) { 18112 this.parent( selector ).not( "body" ).each( function() { 18113 jQuery( this ).replaceWith( this.childNodes ); 18114 } ); 18115 return this; 18116 } 18117} ); 18118 18119 18120jQuery.expr.pseudos.hidden = function( elem ) { 18121 return !jQuery.expr.pseudos.visible( elem ); 18122}; 18123jQuery.expr.pseudos.visible = function( elem ) { 18124 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 18125}; 18126 18127 18128 18129 18130jQuery.ajaxSettings.xhr = function() { 18131 try { 18132 return new window.XMLHttpRequest(); 18133 } catch ( e ) {} 18134}; 18135 18136var xhrSuccessStatus = { 18137 18138 // File protocol always yields status code 0, assume 200 18139 0: 200, 18140
vendor: 1,240 bytes, lines 18141-18183
18141 // Support: IE <=9 only 18142 // #1450: sometimes IE returns 1223 when it should be 204 18143 1223: 204 18144 }, 18145 xhrSupported = jQuery.ajaxSettings.xhr(); 18146 18147support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 18148support.ajax = xhrSupported = !!xhrSupported; 18149 18150jQuery.ajaxTransport( function( options ) { 18151 var callback, errorCallback; 18152 18153 // Cross domain only allowed if supported through XMLHttpRequest 18154 if ( support.cors || xhrSupported && !options.crossDomain ) { 18155 return { 18156 send: function( headers, complete ) { 18157 var i, 18158 xhr = options.xhr(); 18159 18160 xhr.open( 18161 options.type, 18162 options.url, 18163 options.async, 18164 options.username, 18165 options.password 18166 ); 18167 18168 // Apply custom fields if provided 18169 if ( options.xhrFields ) { 18170 for ( i in options.xhrFields ) { 18171 xhr[ i ] = options.xhrFields[ i ]; 18172 } 18173 } 18174 18175 // Override mime type if needed 18176 if ( options.mimeType && xhr.overrideMimeType ) { 18177 xhr.overrideMimeType( options.mimeType ); 18178 } 18179 18180 // X-Requested-With header 18181 // For cross-domain requests, seeing as conditions for a preflight are 18182 // akin to a jigsaw puzzle, we simply never set it to be sure. 18183 // (it can always be set on a per-request basis or even using ajaxSetup)
vendor: 5,627 bytes, lines 18184-18405
18184 // For same-domain requests, won't change header if already provided. 18185 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 18186 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 18187 } 18188 18189 // Set headers 18190 for ( i in headers ) { 18191 xhr.setRequestHeader( i, headers[ i ] ); 18192 } 18193 18194 // Callback 18195 callback = function( type ) { 18196 return function() { 18197 if ( callback ) { 18198 callback = errorCallback = xhr.onload = 18199 xhr.onerror = xhr.onabort = xhr.ontimeout = 18200 xhr.onreadystatechange = null; 18201 18202 if ( type === "abort" ) { 18203 xhr.abort(); 18204 } else if ( type === "error" ) { 18205 18206 // Support: IE <=9 only 18207 // On a manual native abort, IE9 throws 18208 // errors on any property access that is not readyState 18209 if ( typeof xhr.status !== "number" ) { 18210 complete( 0, "error" ); 18211 } else { 18212 complete( 18213 18214 // File: protocol always yields status 0; see #8605, #14207 18215 xhr.status, 18216 xhr.statusText 18217 ); 18218 } 18219 } else { 18220 complete( 18221 xhrSuccessStatus[ xhr.status ] || xhr.status, 18222 xhr.statusText, 18223 18224 // Support: IE <=9 only 18225 // IE9 has no XHR2 but throws on binary (trac-11426) 18226 // For XHR2 non-text, let the caller handle it (gh-2498) 18227 ( xhr.responseType || "text" ) !== "text" || 18228 typeof xhr.responseText !== "string" ? 18229 { binary: xhr.response } : 18230 { text: xhr.responseText }, 18231 xhr.getAllResponseHeaders() 18232 ); 18233 } 18234 } 18235 }; 18236 }; 18237 18238 // Listen to events 18239 xhr.onload = callback(); 18240 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 18241 18242 // Support: IE 9 only 18243 // Use onreadystatechange to replace onabort 18244 // to handle uncaught aborts 18245 if ( xhr.onabort !== undefined ) { 18246 xhr.onabort = errorCallback; 18247 } else { 18248 xhr.onreadystatechange = function() { 18249 18250 // Check readyState before timeout as it changes 18251 if ( xhr.readyState === 4 ) { 18252 18253 // Allow onerror to be called first, 18254 // but that will not handle a native abort 18255 // Also, save errorCallback to a variable 18256 // as xhr.onerror cannot be accessed 18257 window.setTimeout( function() { 18258 if ( callback ) { 18259 errorCallback(); 18260 } 18261 } ); 18262 } 18263 }; 18264 } 18265 18266 // Create the abort callback 18267 callback = callback( "abort" ); 18268 18269 try { 18270 18271 // Do send the request (this may raise an exception) 18272 xhr.send( options.hasContent && options.data || null ); 18273 } catch ( e ) { 18274 18275 // #14683: Only rethrow if this hasn't been notified as an error yet 18276 if ( callback ) { 18277 throw e; 18278 } 18279 } 18280 }, 18281 18282 abort: function() { 18283 if ( callback ) { 18284 callback(); 18285 } 18286 } 18287 }; 18288 } 18289} ); 18290 18291 18292 18293 18294// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 18295jQuery.ajaxPrefilter( function( s ) { 18296 if ( s.crossDomain ) { 18297 s.contents.script = false; 18298 } 18299} ); 18300 18301// Install script dataType 18302jQuery.ajaxSetup( { 18303 accepts: { 18304 script: "text/javascript, application/javascript, " + 18305 "application/ecmascript, application/x-ecmascript" 18306 }, 18307 contents: { 18308 script: /\b(?:java|ecma)script\b/ 18309 }, 18310 converters: { 18311 "text script": function( text ) { 18312 jQuery.globalEval( text ); 18313 return text; 18314 } 18315 } 18316} ); 18317 18318// Handle cache's special case and crossDomain 18319jQuery.ajaxPrefilter( "script", function( s ) { 18320 if ( s.cache === undefined ) { 18321 s.cache = false; 18322 } 18323 if ( s.crossDomain ) { 18324 s.type = "GET"; 18325 } 18326} ); 18327 18328// Bind script tag hack transport 18329jQuery.ajaxTransport( "script", function( s ) { 18330 18331 // This transport only deals with cross domain requests 18332 if ( s.crossDomain ) { 18333 var script, callback; 18334 return { 18335 send: function( _, complete ) { 18336 script = jQuery( "<script>" ).prop( { 18337 charset: s.scriptCharset, 18338 src: s.url 18339 } ).on( 18340 "load error", 18341 callback = function( evt ) { 18342 script.remove(); 18343 callback = null; 18344 if ( evt ) { 18345 complete( evt.type === "error" ? 404 : 200, evt.type ); 18346 } 18347 } 18348 ); 18349 18350 // Use native DOM manipulation to avoid our domManip AJAX trickery 18351 document.head.appendChild( script[ 0 ] ); 18352 }, 18353 abort: function() { 18354 if ( callback ) { 18355 callback(); 18356 } 18357 } 18358 }; 18359 } 18360} ); 18361 18362 18363 18364 18365var oldCallbacks = [], 18366 rjsonp = /(=)\?(?=&|$)|\?\?/; 18367 18368// Default jsonp settings 18369jQuery.ajaxSetup( { 18370 jsonp: "callback", 18371 jsonpCallback: function() { 18372 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); 18373 this[ callback ] = true; 18374 return callback; 18375 } 18376} ); 18377 18378// Detect, normalize options and install callbacks for jsonp requests 18379jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 18380 18381 var callbackName, overwritten, responseContainer, 18382 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 18383 "url" : 18384 typeof s.data === "string" && 18385 ( s.contentType || "" ) 18386 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 18387 rjsonp.test( s.data ) && "data" 18388 ); 18389 18390 // Handle iff the expected data type is "jsonp" or we have a parameter to set 18391 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 18392 18393 // Get callback name, remembering preexisting value associated with it 18394 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 18395 s.jsonpCallback() : 18396 s.jsonpCallback; 18397 18398 // Insert callback into url or form data 18399 if ( jsonProp ) { 18400 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 18401 } else if ( s.jsonp !== false ) { 18402 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 18403 } 18404 18405 // Use data converter to retrieve json after script execution
vendor: 2,987 bytes, lines 18406-18515
18406 s.converters[ "script json" ] = function() { 18407 if ( !responseContainer ) { 18408 jQuery.error( callbackName + " was not called" ); 18409 } 18410 return responseContainer[ 0 ]; 18411 }; 18412 18413 // Force json dataType 18414 s.dataTypes[ 0 ] = "json"; 18415 18416 // Install callback 18417 overwritten = window[ callbackName ]; 18418 window[ callbackName ] = function() { 18419 responseContainer = arguments; 18420 }; 18421 18422 // Clean-up function (fires after converters) 18423 jqXHR.always( function() { 18424 18425 // If previous value didn't exist - remove it 18426 if ( overwritten === undefined ) { 18427 jQuery( window ).removeProp( callbackName ); 18428 18429 // Otherwise restore preexisting value 18430 } else { 18431 window[ callbackName ] = overwritten; 18432 } 18433 18434 // Save back as free 18435 if ( s[ callbackName ] ) { 18436 18437 // Make sure that re-using the options doesn't screw things around 18438 s.jsonpCallback = originalSettings.jsonpCallback; 18439 18440 // Save the callback name for future use 18441 oldCallbacks.push( callbackName ); 18442 } 18443 18444 // Call if it was a function and we have a response 18445 if ( responseContainer && isFunction( overwritten ) ) { 18446 overwritten( responseContainer[ 0 ] ); 18447 } 18448 18449 responseContainer = overwritten = undefined; 18450 } ); 18451 18452 // Delegate to script 18453 return "script"; 18454 } 18455} ); 18456 18457 18458 18459 18460// Support: Safari 8 only 18461// In Safari 8 documents created via document.implementation.createHTMLDocument 18462// collapse sibling forms: the second one becomes a child of the first one. 18463// Because of that, this security measure has to be disabled in Safari 8. 18464// https://bugs.webkit.org/show_bug.cgi?id=137337 18465support.createHTMLDocument = ( function() { 18466 var body = document.implementation.createHTMLDocument( "" ).body; 18467 body.innerHTML = "<form></form><form></form>"; 18468 return body.childNodes.length === 2; 18469} )(); 18470 18471 18472// Argument "data" should be string of html 18473// context (optional): If specified, the fragment will be created in this context, 18474// defaults to document 18475// keepScripts (optional): If true, will include scripts passed in the html string 18476jQuery.parseHTML = function( data, context, keepScripts ) { 18477 if ( typeof data !== "string" ) { 18478 return []; 18479 } 18480 if ( typeof context === "boolean" ) { 18481 keepScripts = context; 18482 context = false; 18483 } 18484 18485 var base, parsed, scripts; 18486 18487 if ( !context ) { 18488 18489 // Stop scripts or inline event handlers from being executed immediately 18490 // by using document.implementation 18491 if ( support.createHTMLDocument ) { 18492 context = document.implementation.createHTMLDocument( "" ); 18493 18494 // Set the base href for the created document 18495 // so any parsed elements with URLs 18496 // are based on the document's URL (gh-2965) 18497 base = context.createElement( "base" ); 18498 base.href = document.location.href; 18499 context.head.appendChild( base ); 18500 } else { 18501 context = document; 18502 } 18503 } 18504 18505 parsed = rsingleTag.exec( data ); 18506 scripts = !keepScripts && []; 18507 18508 // Single tag 18509 if ( parsed ) { 18510 return [ context.createElement( parsed[ 1 ] ) ]; 18511 } 18512 18513 parsed = buildFragment( [ data ], context, scripts ); 18514 18515 if ( scripts && scripts.length ) {
vendor: 14,511 bytes, lines 18516-19036
18516 jQuery( scripts ).remove(); 18517 } 18518 18519 return jQuery.merge( [], parsed.childNodes ); 18520}; 18521 18522 18523/** 18524 * Load a url into a page 18525 */ 18526jQuery.fn.load = function( url, params, callback ) { 18527 var selector, type, response, 18528 self = this, 18529 off = url.indexOf( " " ); 18530 18531 if ( off > -1 ) { 18532 selector = stripAndCollapse( url.slice( off ) ); 18533 url = url.slice( 0, off ); 18534 } 18535 18536 // If it's a function 18537 if ( isFunction( params ) ) { 18538 18539 // We assume that it's the callback 18540 callback = params; 18541 params = undefined; 18542 18543 // Otherwise, build a param string 18544 } else if ( params && typeof params === "object" ) { 18545 type = "POST"; 18546 } 18547 18548 // If we have elements to modify, make the request 18549 if ( self.length > 0 ) { 18550 jQuery.ajax( { 18551 url: url, 18552 18553 // If "type" variable is undefined, then "GET" method will be used. 18554 // Make value of this field explicit since 18555 // user can override it through ajaxSetup method 18556 type: type || "GET", 18557 dataType: "html", 18558 data: params 18559 } ).done( function( responseText ) { 18560 18561 // Save response for use in complete callback 18562 response = arguments; 18563 18564 self.html( selector ? 18565 18566 // If a selector was specified, locate the right elements in a dummy div 18567 // Exclude scripts to avoid IE 'Permission Denied' errors 18568 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 18569 18570 // Otherwise use the full result 18571 responseText ); 18572 18573 // If the request succeeds, this function gets "data", "status", "jqXHR" 18574 // but they are ignored because response was set above. 18575 // If it fails, this function gets "jqXHR", "status", "error" 18576 } ).always( callback && function( jqXHR, status ) { 18577 self.each( function() { 18578 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 18579 } ); 18580 } ); 18581 } 18582 18583 return this; 18584}; 18585 18586 18587 18588 18589// Attach a bunch of functions for handling common AJAX events 18590jQuery.each( [ 18591 "ajaxStart", 18592 "ajaxStop", 18593 "ajaxComplete", 18594 "ajaxError", 18595 "ajaxSuccess", 18596 "ajaxSend" 18597], function( i, type ) { 18598 jQuery.fn[ type ] = function( fn ) { 18599 return this.on( type, fn ); 18600 }; 18601} ); 18602 18603 18604 18605 18606jQuery.expr.pseudos.animated = function( elem ) { 18607 return jQuery.grep( jQuery.timers, function( fn ) { 18608 return elem === fn.elem; 18609 } ).length; 18610}; 18611 18612 18613 18614 18615jQuery.offset = { 18616 setOffset: function( elem, options, i ) { 18617 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 18618 position = jQuery.css( elem, "position" ), 18619 curElem = jQuery( elem ), 18620 props = {}; 18621 18622 // Set position first, in-case top/left are set even on static elem 18623 if ( position === "static" ) { 18624 elem.style.position = "relative"; 18625 } 18626 18627 curOffset = curElem.offset(); 18628 curCSSTop = jQuery.css( elem, "top" ); 18629 curCSSLeft = jQuery.css( elem, "left" ); 18630 calculatePosition = ( position === "absolute" || position === "fixed" ) && 18631 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 18632 18633 // Need to be able to calculate position if either 18634 // top or left is auto and position is either absolute or fixed 18635 if ( calculatePosition ) { 18636 curPosition = curElem.position(); 18637 curTop = curPosition.top; 18638 curLeft = curPosition.left; 18639 18640 } else { 18641 curTop = parseFloat( curCSSTop ) || 0; 18642 curLeft = parseFloat( curCSSLeft ) || 0; 18643 } 18644 18645 if ( isFunction( options ) ) { 18646 18647 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 18648 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 18649 } 18650 18651 if ( options.top != null ) { 18652 props.top = ( options.top - curOffset.top ) + curTop; 18653 } 18654 if ( options.left != null ) { 18655 props.left = ( options.left - curOffset.left ) + curLeft; 18656 } 18657 18658 if ( "using" in options ) { 18659 options.using.call( elem, props ); 18660 18661 } else { 18662 curElem.css( props ); 18663 } 18664 } 18665}; 18666 18667jQuery.fn.extend( { 18668 18669 // offset() relates an element's border box to the document origin 18670 offset: function( options ) { 18671 18672 // Preserve chaining for setter 18673 if ( arguments.length ) { 18674 return options === undefined ? 18675 this : 18676 this.each( function( i ) { 18677 jQuery.offset.setOffset( this, options, i ); 18678 } ); 18679 } 18680 18681 var rect, win, 18682 elem = this[ 0 ]; 18683 18684 if ( !elem ) { 18685 return; 18686 } 18687 18688 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 18689 // Support: IE <=11 only 18690 // Running getBoundingClientRect on a 18691 // disconnected node in IE throws an error 18692 if ( !elem.getClientRects().length ) { 18693 return { top: 0, left: 0 }; 18694 } 18695 18696 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 18697 rect = elem.getBoundingClientRect(); 18698 win = elem.ownerDocument.defaultView; 18699 return { 18700 top: rect.top + win.pageYOffset, 18701 left: rect.left + win.pageXOffset 18702 }; 18703 }, 18704 18705 // position() relates an element's margin box to its offset parent's padding box 18706 // This corresponds to the behavior of CSS absolute positioning 18707 position: function() { 18708 if ( !this[ 0 ] ) { 18709 return; 18710 } 18711 18712 var offsetParent, offset, doc, 18713 elem = this[ 0 ], 18714 parentOffset = { top: 0, left: 0 }; 18715 18716 // position:fixed elements are offset from the viewport, which itself always has zero offset 18717 if ( jQuery.css( elem, "position" ) === "fixed" ) { 18718 18719 // Assume position:fixed implies availability of getBoundingClientRect 18720 offset = elem.getBoundingClientRect(); 18721 18722 } else { 18723 offset = this.offset(); 18724 18725 // Account for the *real* offset parent, which can be the document or its root element 18726 // when a statically positioned element is identified 18727 doc = elem.ownerDocument; 18728 offsetParent = elem.offsetParent || doc.documentElement; 18729 while ( offsetParent && 18730 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 18731 jQuery.css( offsetParent, "position" ) === "static" ) { 18732 18733 offsetParent = offsetParent.parentNode; 18734 } 18735 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 18736 18737 // Incorporate borders into its offset, since they are outside its content origin 18738 parentOffset = jQuery( offsetParent ).offset(); 18739 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 18740 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 18741 } 18742 } 18743 18744 // Subtract parent offsets and element margins 18745 return { 18746 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 18747 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 18748 }; 18749 }, 18750 18751 // This method will return documentElement in the following cases: 18752 // 1) For the element inside the iframe without offsetParent, this method will return 18753 // documentElement of the parent window 18754 // 2) For the hidden or detached element 18755 // 3) For body or html element, i.e. in case of the html node - it will return itself 18756 // 18757 // but those exceptions were never presented as a real life use-cases 18758 // and might be considered as more preferable results. 18759 // 18760 // This logic, however, is not guaranteed and can change at any point in the future 18761 offsetParent: function() { 18762 return this.map( function() { 18763 var offsetParent = this.offsetParent; 18764 18765 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 18766 offsetParent = offsetParent.offsetParent; 18767 } 18768 18769 return offsetParent || documentElement; 18770 } ); 18771 } 18772} ); 18773 18774// Create scrollLeft and scrollTop methods 18775jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 18776 var top = "pageYOffset" === prop; 18777 18778 jQuery.fn[ method ] = function( val ) { 18779 return access( this, function( elem, method, val ) { 18780 18781 // Coalesce documents and windows 18782 var win; 18783 if ( isWindow( elem ) ) { 18784 win = elem; 18785 } else if ( elem.nodeType === 9 ) { 18786 win = elem.defaultView; 18787 } 18788 18789 if ( val === undefined ) { 18790 return win ? win[ prop ] : elem[ method ]; 18791 } 18792 18793 if ( win ) { 18794 win.scrollTo( 18795 !top ? val : win.pageXOffset, 18796 top ? val : win.pageYOffset 18797 ); 18798 18799 } else { 18800 elem[ method ] = val; 18801 } 18802 }, method, val, arguments.length ); 18803 }; 18804} ); 18805 18806// Support: Safari <=7 - 9.1, Chrome <=37 - 49 18807// Add the top/left cssHooks using jQuery.fn.position 18808// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 18809// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 18810// getComputedStyle returns percent when specified for top/left/bottom/right; 18811// rather than make the css module depend on the offset module, just check for it here 18812jQuery.each( [ "top", "left" ], function( i, prop ) { 18813 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 18814 function( elem, computed ) { 18815 if ( computed ) { 18816 computed = curCSS( elem, prop ); 18817 18818 // If curCSS returns percentage, fallback to offset 18819 return rnumnonpx.test( computed ) ? 18820 jQuery( elem ).position()[ prop ] + "px" : 18821 computed; 18822 } 18823 } 18824 ); 18825} ); 18826 18827 18828// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 18829jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 18830 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, 18831 function( defaultExtra, funcName ) { 18832 18833 // Margin is only for outerHeight, outerWidth 18834 jQuery.fn[ funcName ] = function( margin, value ) { 18835 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 18836 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 18837 18838 return access( this, function( elem, type, value ) { 18839 var doc; 18840 18841 if ( isWindow( elem ) ) { 18842 18843 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 18844 return funcName.indexOf( "outer" ) === 0 ? 18845 elem[ "inner" + name ] : 18846 elem.document.documentElement[ "client" + name ]; 18847 } 18848 18849 // Get document width or height 18850 if ( elem.nodeType === 9 ) { 18851 doc = elem.documentElement; 18852 18853 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 18854 // whichever is greatest 18855 return Math.max( 18856 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 18857 elem.body[ "offset" + name ], doc[ "offset" + name ], 18858 doc[ "client" + name ] 18859 ); 18860 } 18861 18862 return value === undefined ? 18863 18864 // Get width or height on the element, requesting but not forcing parseFloat 18865 jQuery.css( elem, type, extra ) : 18866 18867 // Set width or height on the element 18868 jQuery.style( elem, type, value, extra ); 18869 }, type, chainable ? margin : undefined, chainable ); 18870 }; 18871 } ); 18872} ); 18873 18874 18875jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + 18876 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 18877 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 18878 function( i, name ) { 18879 18880 // Handle event binding 18881 jQuery.fn[ name ] = function( data, fn ) { 18882 return arguments.length > 0 ? 18883 this.on( name, null, data, fn ) : 18884 this.trigger( name ); 18885 }; 18886} ); 18887 18888jQuery.fn.extend( { 18889 hover: function( fnOver, fnOut ) { 18890 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 18891 } 18892} ); 18893 18894 18895 18896 18897jQuery.fn.extend( { 18898 18899 bind: function( types, data, fn ) { 18900 return this.on( types, null, data, fn ); 18901 }, 18902 unbind: function( types, fn ) { 18903 return this.off( types, null, fn ); 18904 }, 18905 18906 delegate: function( selector, types, data, fn ) { 18907 return this.on( types, selector, data, fn ); 18908 }, 18909 undelegate: function( selector, types, fn ) { 18910 18911 // ( namespace ) or ( selector, types [, fn] ) 18912 return arguments.length === 1 ? 18913 this.off( selector, "**" ) : 18914 this.off( types, selector || "**", fn ); 18915 } 18916} ); 18917 18918// Bind a function to a context, optionally partially applying any 18919// arguments. 18920// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 18921// However, it is not slated for removal any time soon 18922jQuery.proxy = function( fn, context ) { 18923 var tmp, args, proxy; 18924 18925 if ( typeof context === "string" ) { 18926 tmp = fn[ context ]; 18927 context = fn; 18928 fn = tmp; 18929 } 18930 18931 // Quick check to determine if target is callable, in the spec 18932 // this throws a TypeError, but we will just return undefined. 18933 if ( !isFunction( fn ) ) { 18934 return undefined; 18935 } 18936 18937 // Simulated bind 18938 args = slice.call( arguments, 2 ); 18939 proxy = function() { 18940 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 18941 }; 18942 18943 // Set the guid of unique handler to the same of original handler, so it can be removed 18944 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 18945 18946 return proxy; 18947}; 18948 18949jQuery.holdReady = function( hold ) { 18950 if ( hold ) { 18951 jQuery.readyWait++; 18952 } else { 18953 jQuery.ready( true ); 18954 } 18955}; 18956jQuery.isArray = Array.isArray; 18957jQuery.parseJSON = JSON.parse; 18958jQuery.nodeName = nodeName; 18959jQuery.isFunction = isFunction; 18960jQuery.isWindow = isWindow; 18961jQuery.camelCase = camelCase; 18962jQuery.type = toType; 18963 18964jQuery.now = Date.now; 18965 18966jQuery.isNumeric = function( obj ) { 18967 18968 // As of jQuery 3.0, isNumeric is limited to 18969 // strings and numbers (primitives or objects) 18970 // that can be coerced to finite numbers (gh-2662) 18971 var type = jQuery.type( obj ); 18972 return ( type === "number" || type === "string" ) && 18973 18974 // parseFloat NaNs numeric-cast false positives ("") 18975 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 18976 // subtraction forces infinities to NaN 18977 !isNaN( obj - parseFloat( obj ) ); 18978}; 18979 18980 18981 18982 18983// Register as a named AMD module, since jQuery can be concatenated with other 18984// files that may use define, but not via a proper concatenation script that 18985// understands anonymous AMD modules. A named AMD is safest and most robust 18986// way to register. Lowercase jquery is used because AMD module names are 18987// derived from file names, and jQuery is normally delivered in a lowercase 18988// file name. Do this after creating the global so that if an AMD module wants 18989// to call noConflict to hide this version of jQuery, it will work. 18990 18991// Note that for maximum portability, libraries that are not jQuery should 18992// declare themselves as anonymous modules, and avoid setting a global if an 18993// AMD loader is present. jQuery is a special case. For more information, see 18994// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 18995 18996if ( typeof define === "function" && define.amd ) { 18997 define( "jquery", [], function() { 18998 return jQuery; 18999 } ); 19000} 19001 19002 19003 19004 19005var 19006 19007 // Map over jQuery in case of overwrite 19008 _jQuery = window.jQuery, 19009 19010 // Map over the $ in case of overwrite 19011 _$ = window.$; 19012 19013jQuery.noConflict = function( deep ) { 19014 if ( window.$ === jQuery ) { 19015 window.$ = _$; 19016 } 19017 19018 if ( deep && window.jQuery === jQuery ) { 19019 window.jQuery = _jQuery; 19020 } 19021 19022 return jQuery; 19023}; 19024 19025// Expose jQuery and $ identifiers, even in AMD 19026// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 19027// and CommonJS for browser emulators (#13566) 19028if ( !noGlobal ) { 19029 window.jQuery = window.$ = jQuery; 19030} 19031 19032 19033 19034 19035return jQuery; 19036} );
19037 19038},{}]},{},[3]);
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.