1/*! 2 * Bootstrap v3.3.7 (http://getbootstrap.com) 3 * Copyright 2011-2017 Twitter, Inc. 4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 */ 6 7/*! 8 * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=c0ecd5829184dfa747c9fa7dc216b648) 9 * Config saved to config.json and https://gist.github.com/c0ecd5829184dfa747c9fa7dc216b648 10 */ 11if (typeof jQuery === 'undefined') { 12 throw new Error('Bootstrap\'s JavaScript requires jQuery') 13} 14+function ($) { 15 'use strict'; 16 var version = $.fn.jquery.split(' ')[0].split('.') 17 if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { 18 throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') 19 } 20}(jQuery); 21 22/* ======================================================================== 23 * Bootstrap: alert.js v3.3.7 24 * http://getbootstrap.com/javascript/#alerts 25 * ======================================================================== 26 * Copyright 2011-2016 Twitter, Inc. 27 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 28 * ======================================================================== */ 29 30 31+function ($) { 32 'use strict'; 33 34 // ALERT CLASS DEFINITION 35 // ====================== 36 37 var dismiss = '[data-dismiss="alert"]' 38 var Alert = function (el) { 39 $(el).on('click', dismiss, this.close) 40 } 41 42 Alert.VERSION = '3.3.7' 43 44 Alert.TRANSITION_DURATION = 150 45 46 Alert.prototype.close = function (e) { 47 var $this = $(this) 48 var selector = $this.attr('data-target') 49 50 if (!selector) { 51 selector = $this.attr('href') 52 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 53 } 54 55 var $parent = $(selector === '#' ? [] : selector) 56 57 if (e) e.preventDefault() 58 59 if (!$parent.length) { 60 $parent = $this.closest('.alert') 61 } 62 63 $parent.trigger(e = $.Event('close.bs.alert')) 64 65 if (e.isDefaultPrevented()) return 66 67 $parent.removeClass('in') 68 69 function removeElement() { 70 // detach from parent, fire event then clean up data 71 $parent.detach().trigger('closed.bs.alert').remove() 72 } 73 74 $.support.transition && $parent.hasClass('fade') ? 75 $parent 76 .one('bsTransitionEnd', removeElement) 77 .emulateTransitionEnd(Alert.TRANSITION_DURATION) : 78 removeElement() 79 } 80 81 82 // ALERT PLUGIN DEFINITION 83 // ======================= 84 85 function Plugin(option) { 86 return this.each(function () { 87 var $this = $(this) 88 var data = $this.data('bs.alert') 89 90 if (!data) $this.data('bs.alert', (data = new Alert(this))) 91 if (typeof option == 'string') data[option].call($this) 92 }) 93 } 94 95 var old = $.fn.alert 96 97 $.fn.alert = Plugin 98 $.fn.alert.Constructor = Alert 99 100 101 // ALERT NO CONFLICT 102 // ================= 103 104 $.fn.alert.noConflict = function () { 105 $.fn.alert = old 106 return this 107 } 108 109 110 // ALERT DATA-API 111 // ============== 112 113 $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 114 115}(jQuery); 116 117/* ======================================================================== 118 * Bootstrap: button.js v3.3.7 119 * http://getbootstrap.com/javascript/#buttons 120 * ======================================================================== 121 * Copyright 2011-2016 Twitter, Inc. 122 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 123 * ======================================================================== */ 124 125 126+function ($) { 127 'use strict'; 128 129 // BUTTON PUBLIC CLASS DEFINITION 130 // ============================== 131 132 var Button = function (element, options) { 133 this.$element = $(element) 134 this.options = $.extend({}, Button.DEFAULTS, options) 135 this.isLoading = false 136 } 137 138 Button.VERSION = '3.3.7' 139 140 Button.DEFAULTS = { 141 loadingText: 'loading...' 142 } 143 144 Button.prototype.setState = function (state) { 145 var d = 'disabled' 146 var $el = this.$element 147 var val = $el.is('input') ? 'val' : 'html' 148 var data = $el.data() 149 150 state += 'Text' 151 152 if (data.resetText == null) $el.data('resetText', $el[val]()) 153 154 // push to event loop to allow forms to submit 155 setTimeout($.proxy(function () { 156 $el[val](data[state] == null ? this.options[state] : data[state]) 157 158 if (state == 'loadingText') { 159 this.isLoading = true 160 $el.addClass(d).attr(d, d).prop(d, true) 161 } else if (this.isLoading) { 162 this.isLoading = false 163 $el.removeClass(d).removeAttr(d).prop(d, false) 164 } 165 }, this), 0) 166 } 167 168 Button.prototype.toggle = function () { 169 var changed = true 170 var $parent = this.$element.closest('[data-toggle="buttons"]') 171 172 if ($parent.length) { 173 var $input = this.$element.find('input') 174 if ($input.prop('type') == 'radio') { 175 if ($input.prop('checked')) changed = false 176 $parent.find('.active').removeClass('active') 177 this.$element.addClass('active') 178 } else if ($input.prop('type') == 'checkbox') { 179 if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false 180 this.$element.toggleClass('active') 181 } 182 $input.prop('checked', this.$element.hasClass('active')) 183 if (changed) $input.trigger('change') 184 } else { 185 this.$element.attr('aria-pressed', !this.$element.hasClass('active')) 186 this.$element.toggleClass('active') 187 } 188 } 189 190 191 // BUTTON PLUGIN DEFINITION 192 // ======================== 193 194 function Plugin(option) { 195 return this.each(function () { 196 var $this = $(this) 197 var data = $this.data('bs.button') 198 var options = typeof option == 'object' && option 199 200 if (!data) $this.data('bs.button', (data = new Button(this, options))) 201 202 if (option == 'toggle') data.toggle() 203 else if (option) data.setState(option) 204 }) 205 } 206 207 var old = $.fn.button 208 209 $.fn.button = Plugin 210 $.fn.button.Constructor = Button 211 212 213 // BUTTON NO CONFLICT 214 // ================== 215 216 $.fn.button.noConflict = function () { 217 $.fn.button = old 218 return this 219 } 220 221 222 // BUTTON DATA-API 223 // =============== 224 225 $(document) 226 .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 227 var $btn = $(e.target).closest('.btn') 228 Plugin.call($btn, 'toggle') 229 if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { 230 // Prevent double click on radios, and the double selections (so cancellation) on checkboxes 231 e.preventDefault() 232 // The target component still receive the focus 233 if ($btn.is('input,button')) $btn.trigger('focus') 234 else $btn.find('input:visible,button:visible').first().trigger('focus') 235 } 236 }) 237 .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { 238 $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) 239 }) 240 241}(jQuery); 242 243/* ======================================================================== 244 * Bootstrap: carousel.js v3.3.7 245 * http://getbootstrap.com/javascript/#carousel 246 * ======================================================================== 247 * Copyright 2011-2016 Twitter, Inc. 248 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 249 * ======================================================================== */ 250 251 252+function ($) { 253 'use strict'; 254 255 // CAROUSEL CLASS DEFINITION 256 // ========================= 257 258 var Carousel = function (element, options) { 259 this.$element = $(element) 260 this.$indicators = this.$element.find('.carousel-indicators') 261 this.options = options 262 this.paused = null 263 this.sliding = null 264 this.interval = null 265 this.$active = null 266 this.$items = null 267 268 this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) 269 270 this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element 271 .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) 272 .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) 273 } 274 275 Carousel.VERSION = '3.3.7' 276 277 Carousel.TRANSITION_DURATION = 600 278 279 Carousel.DEFAULTS = { 280 interval: 5000, 281 pause: 'hover', 282 wrap: true, 283 keyboard: true 284 } 285 286 Carousel.prototype.keydown = function (e) { 287 if (/input|textarea/i.test(e.target.tagName)) return 288 switch (e.which) { 289 case 37: this.prev(); break 290 case 39: this.next(); break 291 default: return 292 } 293 294 e.preventDefault() 295 } 296 297 Carousel.prototype.cycle = function (e) { 298 e || (this.paused = false) 299 300 this.interval && clearInterval(this.interval) 301 302 this.options.interval 303 && !this.paused 304 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 305 306 return this 307 } 308 309 Carousel.prototype.getItemIndex = function (item) { 310 this.$items = item.parent().children('.item') 311 return this.$items.index(item || this.$active) 312 } 313 314 Carousel.prototype.getItemForDirection = function (direction, active) { 315 var activeIndex = this.getItemIndex(active) 316 var willWrap = (direction == 'prev' && activeIndex === 0) 317 || (direction == 'next' && activeIndex == (this.$items.length - 1)) 318 if (willWrap && !this.options.wrap) return active 319 var delta = direction == 'prev' ? -1 : 1 320 var itemIndex = (activeIndex + delta) % this.$items.length 321 return this.$items.eq(itemIndex) 322 } 323 324 Carousel.prototype.to = function (pos) { 325 var that = this 326 var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) 327 328 if (pos > (this.$items.length - 1) || pos < 0) return 329 330 if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" 331 if (activeIndex == pos) return this.pause().cycle() 332 333 return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) 334 } 335 336 Carousel.prototype.pause = function (e) { 337 e || (this.paused = true) 338 339 if (this.$element.find('.next, .prev').length && $.support.transition) { 340 this.$element.trigger($.support.transition.end) 341 this.cycle(true) 342 } 343 344 this.interval = clearInterval(this.interval) 345 346 return this 347 } 348 349 Carousel.prototype.next = function () { 350 if (this.sliding) return 351 return this.slide('next') 352 } 353 354 Carousel.prototype.prev = function () { 355 if (this.sliding) return 356 return this.slide('prev') 357 } 358 359 Carousel.prototype.slide = function (type, next) { 360 var $active = this.$element.find('.item.active') 361 var $next = next || this.getItemForDirection(type, $active) 362 var isCycling = this.interval 363 var direction = type == 'next' ? 'left' : 'right' 364 var that = this 365 366 if ($next.hasClass('active')) return (this.sliding = false) 367 368 var relatedTarget = $next[0] 369 var slideEvent = $.Event('slide.bs.carousel', { 370 relatedTarget: relatedTarget, 371 direction: direction 372 }) 373 this.$element.trigger(slideEvent) 374 if (slideEvent.isDefaultPrevented()) return 375 376 this.sliding = true 377 378 isCycling && this.pause() 379 380 if (this.$indicators.length) { 381 this.$indicators.find('.active').removeClass('active') 382 var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) 383 $nextIndicator && $nextIndicator.addClass('active') 384 } 385 386 var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" 387 if ($.support.transition && this.$element.hasClass('slide')) { 388 $next.addClass(type) 389 $next[0].offsetWidth // force reflow 390 $active.addClass(direction) 391 $next.addClass(direction) 392 $active 393 .one('bsTransitionEnd', function () { 394 $next.removeClass([type, direction].join(' ')).addClass('active') 395 $active.removeClass(['active', direction].join(' ')) 396 that.sliding = false 397 setTimeout(function () { 398 that.$element.trigger(slidEvent) 399 }, 0) 400 }) 401 .emulateTransitionEnd(Carousel.TRANSITION_DURATION) 402 } else { 403 $active.removeClass('active') 404 $next.addClass('active') 405 this.sliding = false 406 this.$element.trigger(slidEvent) 407 } 408 409 isCycling && this.cycle() 410 411 return this 412 } 413 414 415 // CAROUSEL PLUGIN DEFINITION 416 // ========================== 417 418 function Plugin(option) { 419 return this.each(function () { 420 var $this = $(this) 421 var data = $this.data('bs.carousel') 422 var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) 423 var action = typeof option == 'string' ? option : options.slide 424 425 if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) 426 if (typeof option == 'number') data.to(option) 427 else if (action) data[action]() 428 else if (options.interval) data.pause().cycle() 429 }) 430 } 431 432 var old = $.fn.carousel 433 434 $.fn.carousel = Plugin 435 $.fn.carousel.Constructor = Carousel 436 437 438 // CAROUSEL NO CONFLICT 439 // ==================== 440 441 $.fn.carousel.noConflict = function () { 442 $.fn.carousel = old 443 return this 444 } 445 446 447 // CAROUSEL DATA-API 448 // ================= 449 450 var clickHandler = function (e) { 451 var href 452 var $this = $(this) 453 var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 454 if (!$target.hasClass('carousel')) return 455 var options = $.extend({}, $target.data(), $this.data()) 456 var slideIndex = $this.attr('data-slide-to') 457 if (slideIndex) options.interval = false 458 459 Plugin.call($target, options) 460 461 if (slideIndex) { 462 $target.data('bs.carousel').to(slideIndex) 463 } 464 465 e.preventDefault() 466 } 467 468 $(document) 469 .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) 470 .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) 471 472 $(window).on('load', function () { 473 $('[data-ride="carousel"]').each(function () { 474 var $carousel = $(this) 475 Plugin.call($carousel, $carousel.data()) 476 }) 477 }) 478 479}(jQuery); 480 481/* ======================================================================== 482 * Bootstrap: dropdown.js v3.3.7 483 * http://getbootstrap.com/javascript/#dropdowns 484 * ======================================================================== 485 * Copyright 2011-2016 Twitter, Inc. 486 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 487 * ======================================================================== */ 488 489 490+function ($) { 491 'use strict'; 492 493 // DROPDOWN CLASS DEFINITION 494 // ========================= 495 496 var backdrop = '.dropdown-backdrop' 497 var toggle = '[data-toggle="dropdown"]' 498 var Dropdown = function (element) { 499 $(element).on('click.bs.dropdown', this.toggle) 500 } 501 502 Dropdown.VERSION = '3.3.7' 503 504 function getParent($this) { 505 var selector = $this.attr('data-target') 506 507 if (!selector) { 508 selector = $this.attr('href') 509 selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 510 } 511 512 var $parent = selector && $(selector) 513 514 return $parent && $parent.length ? $parent : $this.parent() 515 } 516 517 function clearMenus(e) { 518 if (e && e.which === 3) return 519 $(backdrop).remove() 520 $(toggle).each(function () { 521 var $this = $(this) 522 var $parent = getParent($this) 523 var relatedTarget = { relatedTarget: this } 524 525 if (!$parent.hasClass('open')) return 526 527 if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return 528 529 $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) 530 531 if (e.isDefaultPrevented()) return 532 533 $this.attr('aria-expanded', 'false') 534 $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) 535 }) 536 } 537 538 Dropdown.prototype.toggle = function (e) { 539 var $this = $(this) 540 541 if ($this.is('.disabled, :disabled')) return 542 543 var $parent = getParent($this) 544 var isActive = $parent.hasClass('open') 545 546 clearMenus() 547 548 if (!isActive) { 549 if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 550 // if mobile we use a backdrop because click events don't delegate 551 $(document.createElement('div')) 552 .addClass('dropdown-backdrop') 553 .insertAfter($(this)) 554 .on('click', clearMenus) 555 } 556 557 var relatedTarget = { relatedTarget: this } 558 $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) 559 560 if (e.isDefaultPrevented()) return 561 562 $this 563 .trigger('focus') 564 .attr('aria-expanded', 'true') 565 566 $parent 567 .toggleClass('open') 568 .trigger($.Event('shown.bs.dropdown', relatedTarget)) 569 } 570 571 return false 572 } 573 574 Dropdown.prototype.keydown = function (e) { 575 if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return 576 577 var $this = $(this) 578 579 e.preventDefault() 580 e.stopPropagation() 581 582 if ($this.is('.disabled, :disabled')) return 583 584 var $parent = getParent($this) 585 var isActive = $parent.hasClass('open') 586 587 if (!isActive && e.which != 27 || isActive && e.which == 27) { 588 if (e.which == 27) $parent.find(toggle).trigger('focus') 589 return $this.trigger('click') 590 } 591 592 var desc = ' li:not(.disabled):visible a' 593 var $items = $parent.find('.dropdown-menu' + desc) 594 595 if (!$items.length) return 596 597 var index = $items.index(e.target) 598 599 if (e.which == 38 && index > 0) index-- // up 600 if (e.which == 40 && index < $items.length - 1) index++ // down 601 if (!~index) index = 0 602 603 $items.eq(index).trigger('focus') 604 } 605 606 607 // DROPDOWN PLUGIN DEFINITION 608 // ========================== 609 610 function Plugin(option) { 611 return this.each(function () { 612 var $this = $(this) 613 var data = $this.data('bs.dropdown') 614 615 if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) 616 if (typeof option == 'string') data[option].call($this) 617 }) 618 } 619 620 var old = $.fn.dropdown 621 622 $.fn.dropdown = Plugin 623 $.fn.dropdown.Constructor = Dropdown 624 625 626 // DROPDOWN NO CONFLICT 627 // ==================== 628 629 $.fn.dropdown.noConflict = function () { 630 $.fn.dropdown = old 631 return this 632 } 633 634 635 // APPLY TO STANDARD DROPDOWN ELEMENTS 636 // =================================== 637 638 $(document) 639 .on('click.bs.dropdown.data-api', clearMenus) 640 .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) 641 .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) 642 .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) 643 .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) 644 645}(jQuery); 646 647/* ======================================================================== 648 * Bootstrap: modal.js v3.3.7 649 * http://getbootstrap.com/javascript/#modals 650 * ======================================================================== 651 * Copyright 2011-2016 Twitter, Inc. 652 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 653 * ======================================================================== */ 654 655 656+function ($) { 657 'use strict'; 658 659 // MODAL CLASS DEFINITION 660 // ====================== 661 662 var Modal = function (element, options) { 663 this.options = options 664 this.$body = $(document.body) 665 this.$element = $(element) 666 this.$dialog = this.$element.find('.modal-dialog') 667 this.$backdrop = null 668 this.isShown = null 669 this.originalBodyPad = null 670 this.scrollbarWidth = 0 671 this.ignoreBackdropClick = false 672 673 if (this.options.remote) { 674 this.$element 675 .find('.modal-content') 676 .load(this.options.remote, $.proxy(function () { 677 this.$element.trigger('loaded.bs.modal') 678 }, this)) 679 } 680 } 681 682 Modal.VERSION = '3.3.7' 683 684 Modal.TRANSITION_DURATION = 300 685 Modal.BACKDROP_TRANSITION_DURATION = 150 686 687 Modal.DEFAULTS = { 688 backdrop: true, 689 keyboard: true, 690 show: true 691 } 692 693 Modal.prototype.toggle = function (_relatedTarget) { 694 return this.isShown ? this.hide() : this.show(_relatedTarget) 695 } 696 697 Modal.prototype.show = function (_relatedTarget) { 698 var that = this 699 var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) 700 701 this.$element.trigger(e) 702 703 if (this.isShown || e.isDefaultPrevented()) return 704 705 this.isShown = true 706 707 this.checkScrollbar() 708 this.setScrollbar() 709 this.$body.addClass('modal-open') 710 711 this.escape() 712 this.resize() 713 714 this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) 715 716 this.$dialog.on('mousedown.dismiss.bs.modal', function () { 717 that.$element.one('mouseup.dismiss.bs.modal', function (e) { 718 if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true 719 }) 720 }) 721 722 this.backdrop(function () { 723 var transition = $.support.transition && that.$element.hasClass('fade') 724 725 if (!that.$element.parent().length) { 726 that.$element.appendTo(that.$body) // don't move modals dom position 727 } 728 729 that.$element 730 .show() 731 .scrollTop(0) 732 733 that.adjustDialog() 734 735 if (transition) { 736 that.$element[0].offsetWidth // force reflow 737 } 738 739 that.$element.addClass('in') 740 741 that.enforceFocus() 742 743 var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) 744 745 transition ? 746 that.$dialog // wait for modal to slide in 747 .one('bsTransitionEnd', function () { 748 that.$element.trigger('focus').trigger(e) 749 }) 750 .emulateTransitionEnd(Modal.TRANSITION_DURATION) : 751 that.$element.trigger('focus').trigger(e) 752 }) 753 } 754 755 Modal.prototype.hide = function (e) { 756 if (e) e.preventDefault() 757 758 e = $.Event('hide.bs.modal') 759 760 this.$element.trigger(e) 761 762 if (!this.isShown || e.isDefaultPrevented()) return 763 764 this.isShown = false 765 766 this.escape() 767 this.resize() 768 769 $(document).off('focusin.bs.modal') 770 771 this.$element 772 .removeClass('in') 773 .off('click.dismiss.bs.modal') 774 .off('mouseup.dismiss.bs.modal') 775 776 this.$dialog.off('mousedown.dismiss.bs.modal') 777 778 $.support.transition && this.$element.hasClass('fade') ? 779 this.$element 780 .one('bsTransitionEnd', $.proxy(this.hideModal, this)) 781 .emulateTransitionEnd(Modal.TRANSITION_DURATION) : 782 this.hideModal() 783 } 784 785 Modal.prototype.enforceFocus = function () { 786 $(document) 787 .off('focusin.bs.modal') // guard against infinite focus loop 788 .on('focusin.bs.modal', $.proxy(function (e) { 789 if (document !== e.target && 790 this.$element[0] !== e.target && 791 !this.$element.has(e.target).length) { 792 this.$element.trigger('focus') 793 } 794 }, this)) 795 } 796 797 Modal.prototype.escape = function () { 798 if (this.isShown && this.options.keyboard) { 799 this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { 800 e.which == 27 && this.hide() 801 }, this)) 802 } else if (!this.isShown) { 803 this.$element.off('keydown.dismiss.bs.modal') 804 } 805 } 806 807 Modal.prototype.resize = function () { 808 if (this.isShown) { 809 $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) 810 } else { 811 $(window).off('resize.bs.modal') 812 } 813 } 814 815 Modal.prototype.hideModal = function () { 816 var that = this 817 this.$element.hide() 818 this.backdrop(function () { 819 that.$body.removeClass('modal-open') 820 that.resetAdjustments() 821 that.resetScrollbar() 822 that.$element.trigger('hidden.bs.modal') 823 }) 824 } 825 826 Modal.prototype.removeBackdrop = function () { 827 this.$backdrop && this.$backdrop.remove() 828 this.$backdrop = null 829 } 830 831 Modal.prototype.backdrop = function (callback) { 832 var that = this 833 var animate = this.$element.hasClass('fade') ? 'fade' : '' 834 835 if (this.isShown && this.options.backdrop) { 836 var doAnimate = $.support.transition && animate 837 838 this.$backdrop = $(document.createElement('div')) 839 .addClass('modal-backdrop ' + animate) 840 .appendTo(this.$body) 841 842 this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { 843 if (this.ignoreBackdropClick) { 844 this.ignoreBackdropClick = false 845 return 846 } 847 if (e.target !== e.currentTarget) return 848 this.options.backdrop == 'static' 849 ? this.$element[0].focus() 850 : this.hide() 851 }, this)) 852 853 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow 854 855 this.$backdrop.addClass('in') 856 857 if (!callback) return 858 859 doAnimate ? 860 this.$backdrop 861 .one('bsTransitionEnd', callback) 862 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : 863 callback() 864 865 } else if (!this.isShown && this.$backdrop) { 866 this.$backdrop.removeClass('in') 867 868 var callbackRemove = function () { 869 that.removeBackdrop() 870 callback && callback() 871 } 872 $.support.transition && this.$element.hasClass('fade') ? 873 this.$backdrop 874 .one('bsTransitionEnd', callbackRemove) 875 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : 876 callbackRemove() 877 878 } else if (callback) { 879 callback() 880 } 881 } 882 883 // these following methods are used to handle overflowing modals 884 885 Modal.prototype.handleUpdate = function () { 886 this.adjustDialog() 887 } 888 889 Modal.prototype.adjustDialog = function () { 890 var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight 891 892 this.$element.css({ 893 paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', 894 paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' 895 }) 896 } 897 898 Modal.prototype.resetAdjustments = function () { 899 this.$element.css({ 900 paddingLeft: '', 901 paddingRight: '' 902 }) 903 } 904 905 Modal.prototype.checkScrollbar = function () { 906 var fullWindowWidth = window.innerWidth 907 if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 908 var documentElementRect = document.documentElement.getBoundingClientRect() 909 fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) 910 } 911 this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth 912 this.scrollbarWidth = this.measureScrollbar() 913 } 914 915 Modal.prototype.setScrollbar = function () { 916 var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) 917 this.originalBodyPad = document.body.style.paddingRight || '' 918 if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) 919 } 920 921 Modal.prototype.resetScrollbar = function () { 922 this.$body.css('padding-right', this.originalBodyPad) 923 } 924 925 Modal.prototype.measureScrollbar = function () { // thx walsh 926 var scrollDiv = document.createElement('div') 927 scrollDiv.className = 'modal-scrollbar-measure' 928 this.$body.append(scrollDiv) 929 var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth 930 this.$body[0].removeChild(scrollDiv) 931 return scrollbarWidth 932 } 933 934 935 // MODAL PLUGIN DEFINITION 936 // ======================= 937 938 function Plugin(option, _relatedTarget) { 939 return this.each(function () { 940 var $this = $(this) 941 var data = $this.data('bs.modal') 942 var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) 943 944 if (!data) $this.data('bs.modal', (data = new Modal(this, options))) 945 if (typeof option == 'string') data[option](_relatedTarget) 946 else if (options.show) data.show(_relatedTarget) 947 }) 948 } 949 950 var old = $.fn.modal 951 952 $.fn.modal = Plugin 953 $.fn.modal.Constructor = Modal 954 955 956 // MODAL NO CONFLICT 957 // ================= 958 959 $.fn.modal.noConflict = function () { 960 $.fn.modal = old 961 return this 962 } 963 964 965 // MODAL DATA-API 966 // ============== 967 968 $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { 969 var $this = $(this) 970 var href = $this.attr('href') 971 var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 972 var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) 973 974 if ($this.is('a')) e.preventDefault() 975 976 $target.one('show.bs.modal', function (showEvent) { 977 if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown 978 $target.one('hidden.bs.modal', function () { 979 $this.is(':visible') && $this.trigger('focus') 980 }) 981 }) 982 Plugin.call($target, option, this) 983 }) 984 985}(jQuery); 986 987/* ======================================================================== 988 * Bootstrap: tooltip.js v3.3.7 989 * http://getbootstrap.com/javascript/#tooltip 990 * Inspired by the original jQuery.tipsy by Jason Frame 991 * ======================================================================== 992 * Copyright 2011-2016 Twitter, Inc. 993 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 994 * ======================================================================== */ 995 996 997+function ($) { 998 'use strict'; 999 1000 // TOOLTIP PUBLIC CLASS DEFINITION 1001 // =============================== 1002 1003 var Tooltip = function (element, options) { 1004 this.type = null 1005 this.options = null 1006 this.enabled = null 1007 this.timeout = null 1008 this.hoverState = null 1009 this.$element = null 1010 this.inState = null 1011 1012 this.init('tooltip', element, options) 1013 } 1014 1015 Tooltip.VERSION = '3.3.7' 1016 1017 Tooltip.TRANSITION_DURATION = 150 1018 1019 Tooltip.DEFAULTS = { 1020 animation: true, 1021 placement: 'top', 1022 selector: false, 1023 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 1024 trigger: 'hover focus', 1025 title: '', 1026 delay: 0, 1027 html: false, 1028 container: false, 1029 viewport: { 1030 selector: 'body', 1031 padding: 0 1032 } 1033 } 1034 1035 Tooltip.prototype.init = function (type, element, options) { 1036 this.enabled = true 1037 this.type = type 1038 this.$element = $(element) 1039 this.options = this.getOptions(options) 1040 this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) 1041 this.inState = { click: false, hover: false, focus: false } 1042 1043 if (this.$element[0] instanceof document.constructor && !this.options.selector) { 1044 throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') 1045 } 1046 1047 var triggers = this.options.trigger.split(' ') 1048 1049 for (var i = triggers.length; i--;) { 1050 var trigger = triggers[i] 1051 1052 if (trigger == 'click') { 1053 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 1054 } else if (trigger != 'manual') { 1055 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 1056 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 1057 1058 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 1059 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 1060 } 1061 } 1062 1063 this.options.selector ? 1064 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 1065 this.fixTitle() 1066 } 1067 1068 Tooltip.prototype.getDefaults = function () { 1069 return Tooltip.DEFAULTS 1070 } 1071 1072 Tooltip.prototype.getOptions = function (options) { 1073 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 1074 1075 if (options.delay && typeof options.delay == 'number') { 1076 options.delay = { 1077 show: options.delay, 1078 hide: options.delay 1079 } 1080 } 1081 1082 return options 1083 } 1084 1085 Tooltip.prototype.getDelegateOptions = function () { 1086 var options = {} 1087 var defaults = this.getDefaults() 1088 1089 this._options && $.each(this._options, function (key, value) { 1090 if (defaults[key] != value) options[key] = value 1091 }) 1092 1093 return options 1094 } 1095 1096 Tooltip.prototype.enter = function (obj) { 1097 var self = obj instanceof this.constructor ? 1098 obj : $(obj.currentTarget).data('bs.' + this.type) 1099 1100 if (!self) { 1101 self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 1102 $(obj.currentTarget).data('bs.' + this.type, self) 1103 } 1104 1105 if (obj instanceof $.Event) { 1106 self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true 1107 } 1108 1109 if (self.tip().hasClass('in') || self.hoverState == 'in') { 1110 self.hoverState = 'in' 1111 return 1112 } 1113 1114 clearTimeout(self.timeout) 1115 1116 self.hoverState = 'in' 1117 1118 if (!self.options.delay || !self.options.delay.show) return self.show() 1119 1120 self.timeout = setTimeout(function () { 1121 if (self.hoverState == 'in') self.show() 1122 }, self.options.delay.show) 1123 } 1124 1125 Tooltip.prototype.isInStateTrue = function () { 1126 for (var key in this.inState) { 1127 if (this.inState[key]) return true 1128 } 1129 1130 return false 1131 } 1132 1133 Tooltip.prototype.leave = function (obj) { 1134 var self = obj instanceof this.constructor ? 1135 obj : $(obj.currentTarget).data('bs.' + this.type) 1136 1137 if (!self) { 1138 self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 1139 $(obj.currentTarget).data('bs.' + this.type, self) 1140 } 1141 1142 if (obj instanceof $.Event) { 1143 self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false 1144 } 1145 1146 if (self.isInStateTrue()) return 1147 1148 clearTimeout(self.timeout) 1149 1150 self.hoverState = 'out' 1151 1152 if (!self.options.delay || !self.options.delay.hide) return self.hide() 1153 1154 self.timeout = setTimeout(function () { 1155 if (self.hoverState == 'out') self.hide() 1156 }, self.options.delay.hide) 1157 } 1158 1159 Tooltip.prototype.show = function () { 1160 var e = $.Event('show.bs.' + this.type) 1161 1162 if (this.hasContent() && this.enabled) { 1163 this.$element.trigger(e) 1164 1165 var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) 1166 if (e.isDefaultPrevented() || !inDom) return 1167 var that = this 1168 1169 var $tip = this.tip() 1170 1171 var tipId = this.getUID(this.type) 1172 1173 this.setContent() 1174 $tip.attr('id', tipId) 1175 this.$element.attr('aria-describedby', tipId) 1176 1177 if (this.options.animation) $tip.addClass('fade') 1178 1179 var placement = typeof this.options.placement == 'function' ? 1180 this.options.placement.call(this, $tip[0], this.$element[0]) : 1181 this.options.placement 1182 1183 var autoToken = /\s?auto?\s?/i 1184 var autoPlace = autoToken.test(placement) 1185 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 1186 1187 $tip 1188 .detach() 1189 .css({ top: 0, left: 0, display: 'block' }) 1190 .addClass(placement) 1191 .data('bs.' + this.type, this) 1192 1193 this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) 1194 this.$element.trigger('inserted.bs.' + this.type) 1195 1196 var pos = this.getPosition() 1197 var actualWidth = $tip[0].offsetWidth 1198 var actualHeight = $tip[0].offsetHeight 1199 1200 if (autoPlace) { 1201 var orgPlacement = placement 1202 var viewportDim = this.getPosition(this.$viewport) 1203 1204 placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : 1205 placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : 1206 placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : 1207 placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : 1208 placement 1209 1210 $tip 1211 .removeClass(orgPlacement) 1212 .addClass(placement) 1213 } 1214 1215 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 1216 1217 this.applyPlacement(calculatedOffset, placement) 1218 1219 var complete = function () { 1220 var prevHoverState = that.hoverState 1221 that.$element.trigger('shown.bs.' + that.type) 1222 that.hoverState = null 1223 1224 if (prevHoverState == 'out') that.leave(that) 1225 } 1226 1227 $.support.transition && this.$tip.hasClass('fade') ? 1228 $tip 1229 .one('bsTransitionEnd', complete) 1230 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 1231 complete() 1232 } 1233 } 1234 1235 Tooltip.prototype.applyPlacement = function (offset, placement) { 1236 var $tip = this.tip() 1237 var width = $tip[0].offsetWidth 1238 var height = $tip[0].offsetHeight 1239 1240 // manually read margins because getBoundingClientRect includes difference 1241 var marginTop = parseInt($tip.css('margin-top'), 10) 1242 var marginLeft = parseInt($tip.css('margin-left'), 10) 1243 1244 // we must check for NaN for ie 8/9 1245 if (isNaN(marginTop)) marginTop = 0 1246 if (isNaN(marginLeft)) marginLeft = 0 1247 1248 offset.top += marginTop 1249 offset.left += marginLeft 1250 1251 // $.fn.offset doesn't round pixel values 1252 // so we use setOffset directly with our own function B-0 1253 $.offset.setOffset($tip[0], $.extend({ 1254 using: function (props) { 1255 $tip.css({ 1256 top: Math.round(props.top), 1257 left: Math.round(props.left) 1258 }) 1259 } 1260 }, offset), 0) 1261 1262 $tip.addClass('in') 1263 1264 // check to see if placing tip in new offset caused the tip to resize itself 1265 var actualWidth = $tip[0].offsetWidth 1266 var actualHeight = $tip[0].offsetHeight 1267 1268 if (placement == 'top' && actualHeight != height) { 1269 offset.top = offset.top + height - actualHeight 1270 } 1271 1272 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 1273 1274 if (delta.left) offset.left += delta.left 1275 else offset.top += delta.top 1276 1277 var isVertical = /top|bottom/.test(placement) 1278 var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 1279 var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' 1280 1281 $tip.offset(offset) 1282 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) 1283 } 1284 1285 Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { 1286 this.arrow() 1287 .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') 1288 .css(isVertical ? 'top' : 'left', '') 1289 } 1290 1291 Tooltip.prototype.setContent = function () { 1292 var $tip = this.tip() 1293 var title = this.getTitle() 1294 1295 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 1296 $tip.removeClass('fade in top bottom left right') 1297 } 1298 1299 Tooltip.prototype.hide = function (callback) { 1300 var that = this 1301 var $tip = $(this.$tip) 1302 var e = $.Event('hide.bs.' + this.type) 1303 1304 function complete() { 1305 if (that.hoverState != 'in') $tip.detach() 1306 if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. 1307 that.$element 1308 .removeAttr('aria-describedby') 1309 .trigger('hidden.bs.' + that.type) 1310 } 1311 callback && callback() 1312 } 1313 1314 this.$element.trigger(e) 1315 1316 if (e.isDefaultPrevented()) return 1317 1318 $tip.removeClass('in') 1319 1320 $.support.transition && $tip.hasClass('fade') ? 1321 $tip 1322 .one('bsTransitionEnd', complete) 1323 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 1324 complete() 1325 1326 this.hoverState = null 1327 1328 return this 1329 } 1330 1331 Tooltip.prototype.fixTitle = function () { 1332 var $e = this.$element 1333 if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { 1334 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 1335 } 1336 } 1337 1338 Tooltip.prototype.hasContent = function () { 1339 return this.getTitle() 1340 } 1341 1342 Tooltip.prototype.getPosition = function ($element) { 1343 $element = $element || this.$element 1344 1345 var el = $element[0] 1346 var isBody = el.tagName == 'BODY' 1347 1348 var elRect = el.getBoundingClientRect() 1349 if (elRect.width == null) { 1350 // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 1351 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) 1352 } 1353 var isSvg = window.SVGElement && el instanceof window.SVGElement 1354 // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. 1355 // See https://github.com/twbs/bootstrap/issues/20280 1356 var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) 1357 var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } 1358 var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null 1359 1360 return $.extend({}, elRect, scroll, outerDims, elOffset) 1361 } 1362 1363 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 1364 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 1365 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 1366 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 1367 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 1368 1369 } 1370 1371 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 1372 var delta = { top: 0, left: 0 } 1373 if (!this.$viewport) return delta 1374 1375 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 1376 var viewportDimensions = this.getPosition(this.$viewport) 1377 1378 if (/right|left/.test(placement)) { 1379 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 1380 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 1381 if (topEdgeOffset < viewportDimensions.top) { // top overflow 1382 delta.top = viewportDimensions.top - topEdgeOffset 1383 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 1384 delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset 1385 } 1386 } else { 1387 var leftEdgeOffset = pos.left - viewportPadding 1388 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 1389 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 1390 delta.left = viewportDimensions.left - leftEdgeOffset 1391 } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow 1392 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 1393 } 1394 } 1395 1396 return delta 1397 } 1398 1399 Tooltip.prototype.getTitle = function () { 1400 var title 1401 var $e = this.$element 1402 var o = this.options 1403 1404 title = $e.attr('data-original-title') 1405 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 1406 1407 return title 1408 } 1409 1410 Tooltip.prototype.getUID = function (prefix) { 1411 do prefix += ~~(Math.random() * 1000000) 1412 while (document.getElementById(prefix)) 1413 return prefix 1414 } 1415 1416 Tooltip.prototype.tip = function () { 1417 if (!this.$tip) { 1418 this.$tip = $(this.options.template) 1419 if (this.$tip.length != 1) { 1420 throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') 1421 } 1422 } 1423 return this.$tip 1424 } 1425 1426 Tooltip.prototype.arrow = function () { 1427 return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) 1428 } 1429 1430 Tooltip.prototype.enable = function () { 1431 this.enabled = true 1432 } 1433 1434 Tooltip.prototype.disable = function () { 1435 this.enabled = false 1436 } 1437 1438 Tooltip.prototype.toggleEnabled = function () { 1439 this.enabled = !this.enabled 1440 } 1441 1442 Tooltip.prototype.toggle = function (e) { 1443 var self = this 1444 if (e) { 1445 self = $(e.currentTarget).data('bs.' + this.type) 1446 if (!self) { 1447 self = new this.constructor(e.currentTarget, this.getDelegateOptions()) 1448 $(e.currentTarget).data('bs.' + this.type, self) 1449 } 1450 } 1451 1452 if (e) { 1453 self.inState.click = !self.inState.click 1454 if (self.isInStateTrue()) self.enter(self) 1455 else self.leave(self) 1456 } else { 1457 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 1458 } 1459 } 1460 1461 Tooltip.prototype.destroy = function () { 1462 var that = this 1463 clearTimeout(this.timeout) 1464 this.hide(function () { 1465 that.$element.off('.' + that.type).removeData('bs.' + that.type) 1466 if (that.$tip) { 1467 that.$tip.detach() 1468 } 1469 that.$tip = null 1470 that.$arrow = null 1471 that.$viewport = null 1472 that.$element = null 1473 }) 1474 } 1475 1476 1477 // TOOLTIP PLUGIN DEFINITION 1478 // ========================= 1479 1480 function Plugin(option) { 1481 return this.each(function () { 1482 var $this = $(this) 1483 var data = $this.data('bs.tooltip') 1484 var options = typeof option == 'object' && option 1485 1486 if (!data && /destroy|hide/.test(option)) return 1487 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 1488 if (typeof option == 'string') data[option]() 1489 }) 1490 } 1491 1492 var old = $.fn.tooltip 1493 1494 $.fn.tooltip = Plugin 1495 $.fn.tooltip.Constructor = Tooltip 1496 1497 1498 // TOOLTIP NO CONFLICT 1499 // =================== 1500 1501 $.fn.tooltip.noConflict = function () { 1502 $.fn.tooltip = old 1503 return this 1504 } 1505 1506}(jQuery); 1507 1508/* ======================================================================== 1509 * Bootstrap: popover.js v3.3.7 1510 * http://getbootstrap.com/javascript/#popovers 1511 * ======================================================================== 1512 * Copyright 2011-2016 Twitter, Inc. 1513 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1514 * ======================================================================== */ 1515 1516 1517+function ($) { 1518 'use strict'; 1519 1520 // POPOVER PUBLIC CLASS DEFINITION 1521 // =============================== 1522 1523 var Popover = function (element, options) { 1524 this.init('popover', element, options) 1525 } 1526 1527 if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') 1528 1529 Popover.VERSION = '3.3.7' 1530 1531 Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { 1532 placement: 'right', 1533 trigger: 'click', 1534 content: '', 1535 template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' 1536 }) 1537 1538 1539 // NOTE: POPOVER EXTENDS tooltip.js 1540 // ================================ 1541 1542 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) 1543 1544 Popover.prototype.constructor = Popover 1545 1546 Popover.prototype.getDefaults = function () { 1547 return Popover.DEFAULTS 1548 } 1549 1550 Popover.prototype.setContent = function () { 1551 var $tip = this.tip() 1552 var title = this.getTitle() 1553 var content = this.getContent() 1554 1555 $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) 1556 $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events 1557 this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' 1558 ](content) 1559 1560 $tip.removeClass('fade top bottom left right in') 1561 1562 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do 1563 // this manually by checking the contents. 1564 if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() 1565 } 1566 1567 Popover.prototype.hasContent = function () { 1568 return this.getTitle() || this.getContent() 1569 } 1570 1571 Popover.prototype.getContent = function () { 1572 var $e = this.$element 1573 var o = this.options 1574 1575 return $e.attr('data-content') 1576 || (typeof o.content == 'function' ? 1577 o.content.call($e[0]) : 1578 o.content) 1579 } 1580 1581 Popover.prototype.arrow = function () { 1582 return (this.$arrow = this.$arrow || this.tip().find('.arrow')) 1583 } 1584 1585 1586 // POPOVER PLUGIN DEFINITION 1587 // ========================= 1588 1589 function Plugin(option) { 1590 return this.each(function () { 1591 var $this = $(this) 1592 var data = $this.data('bs.popover') 1593 var options = typeof option == 'object' && option 1594 1595 if (!data && /destroy|hide/.test(option)) return 1596 if (!data) $this.data('bs.popover', (data = new Popover(this, options))) 1597 if (typeof option == 'string') data[option]() 1598 }) 1599 } 1600 1601 var old = $.fn.popover 1602 1603 $.fn.popover = Plugin 1604 $.fn.popover.Constructor = Popover 1605 1606 1607 // POPOVER NO CONFLICT 1608 // =================== 1609 1610 $.fn.popover.noConflict = function () { 1611 $.fn.popover = old 1612 return this 1613 } 1614 1615}(jQuery); 1616 1617/* ======================================================================== 1618 * Bootstrap: tab.js v3.3.7 1619 * http://getbootstrap.com/javascript/#tabs 1620 * ======================================================================== 1621 * Copyright 2011-2016 Twitter, Inc. 1622 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1623 * ======================================================================== */ 1624 1625 1626+function ($) { 1627 'use strict'; 1628 1629 // TAB CLASS DEFINITION 1630 // ==================== 1631 1632 var Tab = function (element) { 1633 // jscs:disable requireDollarBeforejQueryAssignment 1634 this.element = $(element) 1635 // jscs:enable requireDollarBeforejQueryAssignment 1636 } 1637 1638 Tab.VERSION = '3.3.7' 1639 1640 Tab.TRANSITION_DURATION = 150 1641 1642 Tab.prototype.show = function () { 1643 var $this = this.element 1644 var $ul = $this.closest('ul:not(.dropdown-menu)') 1645 var selector = $this.data('target') 1646 1647 if (!selector) { 1648 selector = $this.attr('href') 1649 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 1650 } 1651 1652 if ($this.parent('li').hasClass('active')) return 1653 1654 var $previous = $ul.find('.active:last a') 1655 var hideEvent = $.Event('hide.bs.tab', { 1656 relatedTarget: $this[0] 1657 }) 1658 var showEvent = $.Event('show.bs.tab', { 1659 relatedTarget: $previous[0] 1660 }) 1661 1662 $previous.trigger(hideEvent) 1663 $this.trigger(showEvent) 1664 1665 if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return 1666 1667 var $target = $(selector) 1668 1669 this.activate($this.closest('li'), $ul) 1670 this.activate($target, $target.parent(), function () { 1671 $previous.trigger({ 1672 type: 'hidden.bs.tab', 1673 relatedTarget: $this[0] 1674 }) 1675 $this.trigger({ 1676 type: 'shown.bs.tab', 1677 relatedTarget: $previous[0] 1678 }) 1679 }) 1680 } 1681 1682 Tab.prototype.activate = function (element, container, callback) { 1683 var $active = container.find('> .active') 1684 var transition = callback 1685 && $.support.transition 1686 && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) 1687 1688 function next() { 1689 $active 1690 .removeClass('active') 1691 .find('> .dropdown-menu > .active') 1692 .removeClass('active') 1693 .end() 1694 .find('[data-toggle="tab"]') 1695 .attr('aria-expanded', false) 1696 1697 element 1698 .addClass('active') 1699 .find('[data-toggle="tab"]') 1700 .attr('aria-expanded', true) 1701 1702 if (transition) { 1703 element[0].offsetWidth // reflow for transition 1704 element.addClass('in') 1705 } else { 1706 element.removeClass('fade') 1707 } 1708 1709 if (element.parent('.dropdown-menu').length) { 1710 element 1711 .closest('li.dropdown') 1712 .addClass('active') 1713 .end() 1714 .find('[data-toggle="tab"]') 1715 .attr('aria-expanded', true) 1716 } 1717 1718 callback && callback() 1719 } 1720 1721 $active.length && transition ? 1722 $active 1723 .one('bsTransitionEnd', next) 1724 .emulateTransitionEnd(Tab.TRANSITION_DURATION) : 1725 next() 1726 1727 $active.removeClass('in') 1728 } 1729 1730 1731 // TAB PLUGIN DEFINITION 1732 // ===================== 1733 1734 function Plugin(option) { 1735 return this.each(function () { 1736 var $this = $(this) 1737 var data = $this.data('bs.tab') 1738 1739 if (!data) $this.data('bs.tab', (data = new Tab(this))) 1740 if (typeof option == 'string') data[option]() 1741 }) 1742 } 1743 1744 var old = $.fn.tab 1745 1746 $.fn.tab = Plugin 1747 $.fn.tab.Constructor = Tab 1748 1749 1750 // TAB NO CONFLICT 1751 // =============== 1752 1753 $.fn.tab.noConflict = function () { 1754 $.fn.tab = old 1755 return this 1756 } 1757 1758 1759 // TAB DATA-API 1760 // ============ 1761 1762 var clickHandler = function (e) { 1763 e.preventDefault() 1764 Plugin.call($(this), 'show') 1765 } 1766 1767 $(document) 1768 .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) 1769 .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) 1770 1771}(jQuery); 1772 1773/* ======================================================================== 1774 * Bootstrap: affix.js v3.3.7 1775 * http://getbootstrap.com/javascript/#affix 1776 * ======================================================================== 1777 * Copyright 2011-2016 Twitter, Inc. 1778 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1779 * ======================================================================== */ 1780 1781 1782+function ($) { 1783 'use strict'; 1784 1785 // AFFIX CLASS DEFINITION 1786 // ====================== 1787 1788 var Affix = function (element, options) { 1789 this.options = $.extend({}, Affix.DEFAULTS, options) 1790 1791 this.$target = $(this.options.target) 1792 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) 1793 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) 1794 1795 this.$element = $(element) 1796 this.affixed = null 1797 this.unpin = null 1798 this.pinnedOffset = null 1799 1800 this.checkPosition() 1801 } 1802 1803 Affix.VERSION = '3.3.7' 1804 1805 Affix.RESET = 'affix affix-top affix-bottom' 1806 1807 Affix.DEFAULTS = { 1808 offset: 0, 1809 target: window 1810 } 1811 1812 Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { 1813 var scrollTop = this.$target.scrollTop() 1814 var position = this.$element.offset() 1815 var targetHeight = this.$target.height() 1816 1817 if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false 1818 1819 if (this.affixed == 'bottom') { 1820 if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' 1821 return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' 1822 } 1823 1824 var initializing = this.affixed == null 1825 var colliderTop = initializing ? scrollTop : position.top 1826 var colliderHeight = initializing ? targetHeight : height 1827 1828 if (offsetTop != null && scrollTop <= offsetTop) return 'top' 1829 if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' 1830 1831 return false 1832 } 1833 1834 Affix.prototype.getPinnedOffset = function () { 1835 if (this.pinnedOffset) return this.pinnedOffset 1836 this.$element.removeClass(Affix.RESET).addClass('affix') 1837 var scrollTop = this.$target.scrollTop() 1838 var position = this.$element.offset() 1839 return (this.pinnedOffset = position.top - scrollTop) 1840 } 1841 1842 Affix.prototype.checkPositionWithEventLoop = function () { 1843 setTimeout($.proxy(this.checkPosition, this), 1) 1844 } 1845 1846 Affix.prototype.checkPosition = function () { 1847 if (!this.$element.is(':visible')) return 1848 1849 var height = this.$element.height() 1850 var offset = this.options.offset 1851 var offsetTop = offset.top 1852 var offsetBottom = offset.bottom 1853 var scrollHeight = Math.max($(document).height(), $(document.body).height()) 1854 1855 if (typeof offset != 'object') offsetBottom = offsetTop = offset 1856 if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) 1857 if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) 1858 1859 var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) 1860 1861 if (this.affixed != affix) { 1862 if (this.unpin != null) this.$element.css('top', '') 1863 1864 var affixType = 'affix' + (affix ? '-' + affix : '') 1865 var e = $.Event(affixType + '.bs.affix') 1866 1867 this.$element.trigger(e) 1868 1869 if (e.isDefaultPrevented()) return 1870 1871 this.affixed = affix 1872 this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null 1873 1874 this.$element 1875 .removeClass(Affix.RESET) 1876 .addClass(affixType) 1877 .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') 1878 } 1879 1880 if (affix == 'bottom') { 1881 this.$element.offset({ 1882 top: scrollHeight - height - offsetBottom 1883 }) 1884 } 1885 } 1886 1887 1888 // AFFIX PLUGIN DEFINITION 1889 // ======================= 1890 1891 function Plugin(option) { 1892 return this.each(function () { 1893 var $this = $(this) 1894 var data = $this.data('bs.affix') 1895 var options = typeof option == 'object' && option 1896 1897 if (!data) $this.data('bs.affix', (data = new Affix(this, options))) 1898 if (typeof option == 'string') data[option]() 1899 }) 1900 } 1901 1902 var old = $.fn.affix 1903 1904 $.fn.affix = Plugin 1905 $.fn.affix.Constructor = Affix 1906 1907 1908 // AFFIX NO CONFLICT 1909 // ================= 1910 1911 $.fn.affix.noConflict = function () { 1912 $.fn.affix = old 1913 return this 1914 } 1915 1916 1917 // AFFIX DATA-API 1918 // ============== 1919 1920 $(window).on('load', function () { 1921 $('[data-spy="affix"]').each(function () { 1922 var $spy = $(this) 1923 var data = $spy.data() 1924 1925 data.offset = data.offset || {} 1926 1927 if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom 1928 if (data.offsetTop != null) data.offset.top = data.offsetTop 1929 1930 Plugin.call($spy, data) 1931 }) 1932 }) 1933 1934}(jQuery); 1935 1936/* ======================================================================== 1937 * Bootstrap: collapse.js v3.3.7 1938 * http://getbootstrap.com/javascript/#collapse 1939 * ======================================================================== 1940 * Copyright 2011-2016 Twitter, Inc. 1941 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1942 * ======================================================================== */ 1943 1944/* jshint latedef: false */ 1945 1946+function ($) { 1947 'use strict'; 1948 1949 // COLLAPSE PUBLIC CLASS DEFINITION 1950 // ================================ 1951 1952 var Collapse = function (element, options) { 1953 this.$element = $(element) 1954 this.options = $.extend({}, Collapse.DEFAULTS, options) 1955 this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + 1956 '[data-toggle="collapse"][data-target="#' + element.id + '"]') 1957 this.transitioning = null 1958 1959 if (this.options.parent) { 1960 this.$parent = this.getParent() 1961 } else { 1962 this.addAriaAndCollapsedClass(this.$element, this.$trigger) 1963 } 1964 1965 if (this.options.toggle) this.toggle() 1966 } 1967 1968 Collapse.VERSION = '3.3.7' 1969 1970 Collapse.TRANSITION_DURATION = 350 1971 1972 Collapse.DEFAULTS = { 1973 toggle: true 1974 } 1975 1976 Collapse.prototype.dimension = function () { 1977 var hasWidth = this.$element.hasClass('width') 1978 return hasWidth ? 'width' : 'height' 1979 } 1980 1981 Collapse.prototype.show = function () { 1982 if (this.transitioning || this.$element.hasClass('in')) return 1983 1984 var activesData 1985 var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') 1986 1987 if (actives && actives.length) { 1988 activesData = actives.data('bs.collapse') 1989 if (activesData && activesData.transitioning) return 1990 } 1991 1992 var startEvent = $.Event('show.bs.collapse') 1993 this.$element.trigger(startEvent) 1994 if (startEvent.isDefaultPrevented()) return 1995 1996 if (actives && actives.length) { 1997 Plugin.call(actives, 'hide') 1998 activesData || actives.data('bs.collapse', null) 1999 } 2000 2001 var dimension = this.dimension() 2002 2003 this.$element 2004 .removeClass('collapse') 2005 .addClass('collapsing')[dimension](0) 2006 .attr('aria-expanded', true) 2007 2008 this.$trigger 2009 .removeClass('collapsed') 2010 .attr('aria-expanded', true) 2011 2012 this.transitioning = 1 2013 2014 var complete = function () { 2015 this.$element 2016 .removeClass('collapsing') 2017 .addClass('collapse in')[dimension]('') 2018 this.transitioning = 0 2019 this.$element 2020 .trigger('shown.bs.collapse') 2021 } 2022 2023 if (!$.support.transition) return complete.call(this) 2024 2025 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 2026 2027 this.$element 2028 .one('bsTransitionEnd', $.proxy(complete, this)) 2029 .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) 2030 } 2031 2032 Collapse.prototype.hide = function () { 2033 if (this.transitioning || !this.$element.hasClass('in')) return 2034 2035 var startEvent = $.Event('hide.bs.collapse') 2036 this.$element.trigger(startEvent) 2037 if (startEvent.isDefaultPrevented()) return 2038 2039 var dimension = this.dimension() 2040 2041 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 2042 2043 this.$element 2044 .addClass('collapsing') 2045 .removeClass('collapse in') 2046 .attr('aria-expanded', false) 2047 2048 this.$trigger 2049 .addClass('collapsed') 2050 .attr('aria-expanded', false) 2051 2052 this.transitioning = 1 2053 2054 var complete = function () { 2055 this.transitioning = 0 2056 this.$element 2057 .removeClass('collapsing') 2058 .addClass('collapse') 2059 .trigger('hidden.bs.collapse') 2060 } 2061 2062 if (!$.support.transition) return complete.call(this) 2063 2064 this.$element 2065 [dimension](0) 2066 .one('bsTransitionEnd', $.proxy(complete, this)) 2067 .emulateTransitionEnd(Collapse.TRANSITION_DURATION) 2068 } 2069 2070 Collapse.prototype.toggle = function () { 2071 this[this.$element.hasClass('in') ? 'hide' : 'show']() 2072 } 2073 2074 Collapse.prototype.getParent = function () { 2075 return $(this.options.parent) 2076 .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') 2077 .each($.proxy(function (i, element) { 2078 var $element = $(element) 2079 this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) 2080 }, this)) 2081 .end() 2082 } 2083 2084 Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { 2085 var isOpen = $element.hasClass('in') 2086 2087 $element.attr('aria-expanded', isOpen) 2088 $trigger 2089 .toggleClass('collapsed', !isOpen) 2090 .attr('aria-expanded', isOpen) 2091 } 2092 2093 function getTargetFromTrigger($trigger) { 2094 var href 2095 var target = $trigger.attr('data-target') 2096 || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 2097 2098 return $(target) 2099 } 2100 2101 2102 // COLLAPSE PLUGIN DEFINITION 2103 // ========================== 2104 2105 function Plugin(option) { 2106 return this.each(function () { 2107 var $this = $(this) 2108 var data = $this.data('bs.collapse') 2109 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 2110 2111 if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false 2112 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 2113 if (typeof option == 'string') data[option]() 2114 }) 2115 } 2116 2117 var old = $.fn.collapse 2118 2119 $.fn.collapse = Plugin 2120 $.fn.collapse.Constructor = Collapse 2121 2122 2123 // COLLAPSE NO CONFLICT 2124 // ==================== 2125 2126 $.fn.collapse.noConflict = function () { 2127 $.fn.collapse = old 2128 return this 2129 } 2130 2131 2132 // COLLAPSE DATA-API 2133 // ================= 2134 2135 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 2136 var $this = $(this) 2137 2138 if (!$this.attr('data-target')) e.preventDefault() 2139 2140 var $target = getTargetFromTrigger($this) 2141 var data = $target.data('bs.collapse') 2142 var option = data ? 'toggle' : $this.data() 2143 2144 Plugin.call($target, option) 2145 }) 2146 2147}(jQuery); 2148 2149/* ======================================================================== 2150 * Bootstrap: scrollspy.js v3.3.7 2151 * http://getbootstrap.com/javascript/#scrollspy 2152 * ======================================================================== 2153 * Copyright 2011-2016 Twitter, Inc. 2154 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 2155 * ======================================================================== */ 2156 2157 2158+function ($) { 2159 'use strict'; 2160 2161 // SCROLLSPY CLASS DEFINITION 2162 // ========================== 2163 2164 function ScrollSpy(element, options) { 2165 this.$body = $(document.body) 2166 this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) 2167 this.options = $.extend({}, ScrollSpy.DEFAULTS, options) 2168 this.selector = (this.options.target || '') + ' .nav li > a' 2169 this.offsets = [] 2170 this.targets = [] 2171 this.activeTarget = null 2172 this.scrollHeight = 0 2173 2174 this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) 2175 this.refresh() 2176 this.process() 2177 } 2178 2179 ScrollSpy.VERSION = '3.3.7' 2180 2181 ScrollSpy.DEFAULTS = { 2182 offset: 10 2183 } 2184 2185 ScrollSpy.prototype.getScrollHeight = function () { 2186 return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) 2187 } 2188 2189 ScrollSpy.prototype.refresh = function () { 2190 var that = this 2191 var offsetMethod = 'offset' 2192 var offsetBase = 0 2193 2194 this.offsets = [] 2195 this.targets = [] 2196 this.scrollHeight = this.getScrollHeight() 2197 2198 if (!$.isWindow(this.$scrollElement[0])) { 2199 offsetMethod = 'position' 2200 offsetBase = this.$scrollElement.scrollTop() 2201 } 2202 2203 this.$body 2204 .find(this.selector) 2205 .map(function () { 2206 var $el = $(this) 2207 var href = $el.data('target') || $el.attr('href') 2208 var $href = /^#./.test(href) && $(href) 2209 2210 return ($href 2211 && $href.length 2212 && $href.is(':visible') 2213 && [[$href[offsetMethod]().top + offsetBase, href]]) || null 2214 }) 2215 .sort(function (a, b) { return a[0] - b[0] }) 2216 .each(function () { 2217 that.offsets.push(this[0]) 2218 that.targets.push(this[1]) 2219 }) 2220 } 2221 2222 ScrollSpy.prototype.process = function () { 2223 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset 2224 var scrollHeight = this.getScrollHeight() 2225 var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() 2226 var offsets = this.offsets 2227 var targets = this.targets 2228 var activeTarget = this.activeTarget 2229 var i 2230 2231 if (this.scrollHeight != scrollHeight) { 2232 this.refresh() 2233 } 2234 2235 if (scrollTop >= maxScroll) { 2236 return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) 2237 } 2238 2239 if (activeTarget && scrollTop < offsets[0]) { 2240 this.activeTarget = null 2241 return this.clear() 2242 } 2243 2244 for (i = offsets.length; i--;) { 2245 activeTarget != targets[i] 2246 && scrollTop >= offsets[i] 2247 && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) 2248 && this.activate(targets[i]) 2249 } 2250 } 2251 2252 ScrollSpy.prototype.activate = function (target) { 2253 this.activeTarget = target 2254 2255 this.clear() 2256 2257 var selector = this.selector + 2258 '[data-target="' + target + '"],' + 2259 this.selector + '[href="' + target + '"]' 2260 2261 var active = $(selector) 2262 .parents('li') 2263 .addClass('active') 2264 2265 if (active.parent('.dropdown-menu').length) { 2266 active = active 2267 .closest('li.dropdown') 2268 .addClass('active') 2269 } 2270 2271 active.trigger('activate.bs.scrollspy') 2272 } 2273 2274 ScrollSpy.prototype.clear = function () { 2275 $(this.selector) 2276 .parentsUntil(this.options.target, '.active') 2277 .removeClass('active') 2278 } 2279 2280 2281 // SCROLLSPY PLUGIN DEFINITION 2282 // =========================== 2283 2284 function Plugin(option) { 2285 return this.each(function () { 2286 var $this = $(this) 2287 var data = $this.data('bs.scrollspy') 2288 var options = typeof option == 'object' && option 2289 2290 if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) 2291 if (typeof option == 'string') data[option]() 2292 }) 2293 } 2294 2295 var old = $.fn.scrollspy 2296 2297 $.fn.scrollspy = Plugin 2298 $.fn.scrollspy.Constructor = ScrollSpy 2299 2300 2301 // SCROLLSPY NO CONFLICT 2302 // ===================== 2303 2304 $.fn.scrollspy.noConflict = function () { 2305 $.fn.scrollspy = old 2306 return this 2307 } 2308 2309 2310 // SCROLLSPY DATA-API 2311 // ================== 2312 2313 $(window).on('load.bs.scrollspy.data-api', function () { 2314 $('[data-spy="scroll"]').each(function () { 2315 var $spy = $(this) 2316 Plugin.call($spy, $spy.data()) 2317 }) 2318 }) 2319 2320}(jQuery); 2321 2322/* ======================================================================== 2323 * Bootstrap: transition.js v3.3.7 2324 * http://getbootstrap.com/javascript/#transitions 2325 * ======================================================================== 2326 * Copyright 2011-2016 Twitter, Inc. 2327 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 2328 * ======================================================================== */ 2329 2330 2331+function ($) { 2332 'use strict'; 2333 2334 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 2335 // ============================================================ 2336 2337 function transitionEnd() { 2338 var el = document.createElement('bootstrap') 2339 2340 var transEndEventNames = { 2341 WebkitTransition : 'webkitTransitionEnd', 2342 MozTransition : 'transitionend', 2343 OTransition : 'oTransitionEnd otransitionend', 2344 transition : 'transitionend' 2345 } 2346 2347 for (var name in transEndEventNames) { 2348 if (el.style[name] !== undefined) { 2349 return { end: transEndEventNames[name] } 2350 } 2351 } 2352 2353 return false // explicit for ie8 ( ._.) 2354 } 2355 2356 // http://blog.alexmaccaw.com/css-transitions 2357 $.fn.emulateTransitionEnd = function (duration) { 2358 var called = false 2359 var $el = this 2360 $(this).one('bsTransitionEnd', function () { called = true }) 2361 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 2362 setTimeout(callback, duration) 2363 return this 2364 } 2365 2366 $(function () { 2367 $.support.transition = transitionEnd() 2368 2369 if (!$.support.transition) return 2370 2371 $.event.special.bsTransitionEnd = { 2372 bindType: $.support.transition.end, 2373 delegateType: $.support.transition.end, 2374 handle: function (e) { 2375 if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 2376 } 2377 } 2378 }) 2379 2380}(jQuery); 2381