diff options
| author | F A T <[email protected]> | 2015-02-11 11:36:16 -0800 |
|---|---|---|
| committer | F A T <[email protected]> | 2015-02-11 11:36:16 -0800 |
| commit | f483640378c8dfe7fd41f7743dc43d8ad0ea8b1b (patch) | |
| tree | 19bfdadb0c140df437e7b7034e5e1f5ce58343cc /dist | |
| parent | aed1cd31218113d67d2eca3296edf5d1700b19b8 (diff) | |
| parent | 834220ea20ce5b7cd31edfb624a28b4bf8b29a6a (diff) | |
| download | bootstrap-f483640378c8dfe7fd41f7743dc43d8ad0ea8b1b.tar.xz bootstrap-f483640378c8dfe7fd41f7743dc43d8ad0ea8b1b.zip | |
Merge pull request #57 from twbs/fat-closure
Bootstrap onto closure v2
Diffstat (limited to 'dist')
| -rw-r--r-- | dist/js/bootstrap.js | 5449 | ||||
| -rw-r--r-- | dist/js/bootstrap.min.js | 74 | ||||
| -rw-r--r-- | dist/js/bootstrap.min.js.gz | bin | 0 -> 10652 bytes | |||
| -rw-r--r-- | dist/js/npm.js | 8 |
4 files changed, 3938 insertions, 1593 deletions
diff --git a/dist/js/bootstrap.js b/dist/js/bootstrap.js index 584fe3ba2..5d3f63040 100644 --- a/dist/js/bootstrap.js +++ b/dist/js/bootstrap.js @@ -15,2291 +15,4566 @@ if (typeof jQuery === 'undefined') { } }(jQuery); -/* ======================================================================== - * Bootstrap: transition.js v3.3.2 - * http://getbootstrap.com/javascript/#transitions +/** ======================================================================= + * Bootstrap: util.js v4.0.0 + * http://getbootstrap.com/javascript/#alerts * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's private util helper. Adds private util + * helpers for things like accesibility and transitions. These methods are + * shared across all bootstrap plugins. + * ======================================================================== + */ +'use strict'; -+function ($) { - 'use strict'; - // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) - // ============================================================ +/** + * @type {Object} + */ +var Bootstrap = {} - function transitionEnd() { - var el = document.createElement('bootstrap') - var transEndEventNames = { - WebkitTransition : 'webkitTransitionEnd', - MozTransition : 'transitionend', - OTransition : 'oTransitionEnd otransitionend', - transition : 'transitionend' - } +/** + * @const + * @type {string} + */ +Bootstrap.TRANSITION_END = 'bsTransitionEnd' - for (var name in transEndEventNames) { - if (el.style[name] !== undefined) { - return { end: transEndEventNames[name] } - } - } - return false // explicit for ie8 ( ._.) - } +/** + * @const + * @type {Object} + */ +Bootstrap.TransitionEndEvent = { + 'WebkitTransition' : 'webkitTransitionEnd', + 'MozTransition' : 'transitionend', + 'OTransition' : 'oTransitionEnd otransitionend', + 'transition' : 'transitionend' +} + + +/** + * @param {Function} childConstructor + * @param {Function} parentConstructor + */ +Bootstrap.inherits = function(childConstructor, parentConstructor) { + /** @constructor */ + function tempConstructor() {} + tempConstructor.prototype = parentConstructor.prototype + childConstructor.prototype = new tempConstructor() + /** @override */ + childConstructor.prototype.constructor = childConstructor +} + + +/** + * @param {Element} element + * @return {string|null} + */ +Bootstrap.getSelectorFromElement = function (element) { + var selector = element.getAttribute('data-target') - // http://blog.alexmaccaw.com/css-transitions - $.fn.emulateTransitionEnd = function (duration) { - var called = false - var $el = this - $(this).one('bsTransitionEnd', function () { called = true }) - var callback = function () { if (!called) $($el).trigger($.support.transition.end) } - setTimeout(callback, duration) - return this + if (!selector) { + selector = element.getAttribute('href') || '' + selector = /^#[a-z]/i.test(selector) ? selector : null } - $(function () { - $.support.transition = transitionEnd() + return selector +} + + +/** + * @param {string} prefix + * @return {string} + */ +Bootstrap.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix +} - if (!$.support.transition) return - $.event.special.bsTransitionEnd = { - bindType: $.support.transition.end, - delegateType: $.support.transition.end, - handle: function (e) { - if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) +/** + * @return {Object} + */ +Bootstrap.getSpecialTransitionEndEvent = function () { + return { + bindType: Bootstrap.transition.end, + delegateType: Bootstrap.transition.end, + handle: /** @param {jQuery.Event} event */ (function (event) { + if ($(event.target).is(this)) { + return event.handleObj.handler.apply(this, arguments) } + }) + } +} + + +/** + * @param {Element} element + */ +Bootstrap.reflow = function (element) { + new Function('bs',"return bs")(element.offsetHeight) +} + + +/** + * @return {Object|boolean} + */ +Bootstrap.transitionEndTest = function () { + if (window['QUnit']) { + return false + } + + var el = document.createElement('bootstrap') + for (var name in Bootstrap.TransitionEndEvent) { + if (el.style[name] !== undefined) { + return { end: Bootstrap.TransitionEndEvent[name] } } + } + return false +} + + +/** + * @param {number} duration + * @this {Element} + * @return {Object} + */ +Bootstrap.transitionEndEmulator = function (duration) { + var called = false + + $(this).one(Bootstrap.TRANSITION_END, function () { + called = true }) -}(jQuery); + var callback = function () { + if (!called) { + $(this).trigger(Bootstrap.transition.end) + } + }.bind(this) + + setTimeout(callback, duration) + + return this +} + + +/** + * ------------------------------------------------------------------------ + * jQuery Interface + * ------------------------------------------------------------------------ + */ + +$.fn.emulateTransitionEnd = Bootstrap.transitionEndEmulator + +$(function () { + Bootstrap.transition = Bootstrap.transitionEndTest() + + if (!Bootstrap.transition) { + return + } -/* ======================================================================== - * Bootstrap: alert.js v3.3.2 + $.event.special[Bootstrap.TRANSITION_END] = Bootstrap.getSpecialTransitionEndEvent() +}) + +$(document).on('mq4hsChange', function (e) { + $(document.documentElement).toggleClass('bs-true-hover', e.trueHover) +}) + +/*! + * mq4-hover-shim v0.1.0 + * https://github.com/twbs/mq4-hover-shim + * Copyright (c) 2014-2015 Christopher Rebert + * Licensed under the MIT License (https://github.com/twbs/mq4-hover-shim/blob/master/LICENSE). + */ + +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.mq4HoverShim=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ +"use strict"; + +var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; + + + + +/** +* Does this UA's primary pointer support true hovering +* OR does the UA at least not try to quirkily emulate hovering, +* such that :hover CSS styles are appropriate? +* Essentially tries to shim the `@media (hover: hover)` CSS media query feature. +* @public +* @returns {boolean} +* @since 0.0.1 +*/ +exports.supportsTrueHover = supportsTrueHover; +/*eslint-env browser */ +/*eslint no-var:2*/ +/* jshint browser: true, esnext: true */ +/* jshint -W080 */ +/** +* @module mq4HoverShim +* @requires jquery +*/ +var $ = (function () { + try { + var jQuery = _interopRequireWildcard(require("jquery")); + + return jQuery; + } catch (importErr) { + var globaljQuery = window.$ || window.jQuery || window.Zepto; + if (!globaljQuery) { + throw new Error("mq4HoverShim needs jQuery (or similar)"); + } + return globaljQuery; + } +})(); + +/** @type {boolean|undefined} */ +var canTrulyHover = undefined; + +/** +* @private +* @fires mq4HoverShim#mq4hsChange +*/ +function triggerEvent() { + $(document).trigger($.Event("mq4hsChange", { bubbles: false, trueHover: canTrulyHover })); +} + +// IIFE so we can use `return`s to avoid deeply-nested if-s +(function () { + if (!window.matchMedia) { + // Opera Mini, IE<=9, Android<=2.3, ancient, or obscure; per http://caniuse.com/#feat=matchmedia + + // Opera Mini, Android, and IE Mobile don't support true hovering, so they're what we'll check for. + // Other browsers are either: + // (a) obscure + // (b) touch-based but old enough not to attempt to emulate hovering + // (c) old desktop browsers that do support true hovering + + // Explanation of this UA regex: + // IE Mobile <9 seems to always have "Windows CE", "Windows Phone", or "IEMobile" in its UA string. + // IE Mobile 9 in desktop view doesn't include "IEMobile" or "Windows Phone" in the UA string, + // but it instead includes "XBLWP7" and/or "ZuneWP7". + canTrulyHover = !/Opera Mini|Android|IEMobile|Windows (Phone|CE)|(XBL|Zune)WP7/.test(navigator.userAgent); + + // Since there won't be any event handlers to fire our events, do the one-and-only firing of it here and now. + triggerEvent(); + return; + } + + // CSSWG Media Queries Level 4 draft + // http://drafts.csswg.org/mediaqueries/#hover + var HOVER_NONE = "(hover: none),(-moz-hover: none),(-ms-hover: none),(-webkit-hover: none)"; + var HOVER_ON_DEMAND = "(hover: on-demand),(-moz-hover: on-demand),(-ms-hover: on-demand),(-webkit-hover: on-demand)"; + var HOVER_HOVER = "(hover: hover),(-moz-hover: hover),(-ms-hover: hover),(-webkit-hover: hover)"; + if (window.matchMedia("" + HOVER_NONE + "," + HOVER_ON_DEMAND + "," + HOVER_HOVER).matches) { + // Browser understands the `hover` media feature + var hoverCallback = function (mql) { + var doesMatch = mql.matches; + if (doesMatch !== canTrulyHover) { + canTrulyHover = doesMatch; + triggerEvent(); + } + }; + var atHoverQuery = window.matchMedia(HOVER_HOVER); + atHoverQuery.addListener(hoverCallback); + hoverCallback(atHoverQuery); + return; + } + + // Check for touch support instead. + // Touch generally implies that hovering is merely emulated, + // which doesn't count as true hovering support for our purposes + // due to the quirkiness of the emulation (e.g. :hover being sticky). + + // W3C Pointer Events PR, 16 December 2014 + // http://www.w3.org/TR/2014/PR-pointerevents-20141216/ + // Prefixed in IE10, per http://caniuse.com/#feat=pointer + if (window.PointerEvent || window.MSPointerEvent) { + // Browser supports Pointer Events + + // Browser supports touch if it has touch points + /* jshint -W018 */ + canTrulyHover = !((window.navigator.maxTouchPoints || window.navigator.msMaxTouchPoints) > 0); + /* jshint +W018 */ + triggerEvent(); + return; + } + + // Mozilla's -moz-touch-enabled + // https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Media_queries#-moz-touch-enabled + var touchEnabledQuery = window.matchMedia("(touch-enabled),(-moz-touch-enabled),(-ms-touch-enabled),(-webkit-touch-enabled)"); + if (touchEnabledQuery.matches) { + canTrulyHover = false; + triggerEvent(); + return; + } + + // W3C Touch Events REC, 10 October 2013 + // http://www.w3.org/TR/2013/REC-touch-events-20131010/ + if ("ontouchstart" in window) { + canTrulyHover = false; + triggerEvent(); + return; + } + + // UA's pointer is non-touch and thus likely either supports true hovering or at least does not try to emulate it. + canTrulyHover = true; + triggerEvent(); +})();function supportsTrueHover() { + return canTrulyHover; +} +exports.__esModule = true; +},{"jquery":undefined}]},{},[1])(1) +}); +/** ======================================================================= + * Bootstrap: alert.js v4.0.0 * http://getbootstrap.com/javascript/#alerts * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - + * ======================================================================== + * @fileoverview - Bootstrap's generic alert component. Add dismiss + * functionality to all alert messages with this plugin. + * + * Public Methods & Properties: + * + * + $.alert + * + $.alert.noConflict + * + $.alert.Constructor + * + $.alert.Constructor.VERSION + * + $.alert.Constructor.prototype.close + * + * ======================================================================== + */ -+function ($) { - 'use strict'; +'use strict'; - // ALERT CLASS DEFINITION - // ====================== - var dismiss = '[data-dismiss="alert"]' - var Alert = function (el) { - $(el).on('click', dismiss, this.close) +/** + * Our Alert class. + * @param {Element=} opt_element + * @constructor + */ +var Alert = function (opt_element) { + if (opt_element) { + $(opt_element).on('click', Alert._DISMISS_SELECTOR, Alert._handleDismiss(this)) } +} - Alert.VERSION = '3.3.2' - Alert.TRANSITION_DURATION = 150 +/** + * @const + * @type {string} + */ +Alert['VERSION'] = '4.0.0' - Alert.prototype.close = function (e) { - var $this = $(this) - var selector = $this.attr('data-target') - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } +/** + * @const + * @type {string} + * @private + */ +Alert._NAME = 'alert' - var $parent = $(selector) - if (e) e.preventDefault() +/** + * @const + * @type {string} + * @private + */ +Alert._DATA_KEY = 'bs.alert' + + +/** + * @const + * @type {string} + * @private + */ +Alert._DISMISS_SELECTOR = '[data-dismiss="alert"]' - if (!$parent.length) { - $parent = $this.closest('.alert') - } - $parent.trigger(e = $.Event('close.bs.alert')) +/** + * @const + * @type {number} + * @private + */ +Alert._TRANSITION_DURATION = 150 + + +/** + * @const + * @type {Function} + * @private + */ +Alert._JQUERY_NO_CONFLICT = $.fn[Alert._NAME] + + +/** + * @const + * @enum {string} + * @private + */ +Alert._Event = { + CLOSE : 'close.bs.alert', + CLOSED : 'closed.bs.alert' +} + + +/** + * @const + * @enum {string} + * @private + */ +Alert._ClassName = { + ALERT : 'alert', + FADE : 'fade', + IN : 'in' +} + + +/** + * Provides the jQuery Interface for the alert component. + * @param {string=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Alert._jQueryInterface = function (opt_config) { + return this.each(function () { + var $this = $(this) + var data = $this.data(Alert._DATA_KEY) + + if (!data) { + data = new Alert(this) + $this.data(Alert._DATA_KEY, data) + } - if (e.isDefaultPrevented()) return + if (opt_config === 'close') { + data[opt_config](this) + } + }) +} - $parent.removeClass('in') - function removeElement() { - // detach from parent, fire event then clean up data - $parent.detach().trigger('closed.bs.alert').remove() +/** + * Close the alert component + * @param {Alert} alertInstance + * @return {Function} + * @private + */ +Alert._handleDismiss = function (alertInstance) { + return function (event) { + if (event) { + event.preventDefault() } - $.support.transition && $parent.hasClass('fade') ? - $parent - .one('bsTransitionEnd', removeElement) - .emulateTransitionEnd(Alert.TRANSITION_DURATION) : - removeElement() + alertInstance['close'](this) } +} - // ALERT PLUGIN DEFINITION - // ======================= +/** + * Close the alert component + * @param {Element} element + */ +Alert.prototype['close'] = function (element) { + var rootElement = this._getRootElement(element) + var customEvent = this._triggerCloseEvent(rootElement) - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.alert') + if (customEvent.isDefaultPrevented()) return - if (!data) $this.data('bs.alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) + this._removeElement(rootElement) +} + + +/** + * Tries to get the alert's root element + * @return {Element} + * @private + */ +Alert.prototype._getRootElement = function (element) { + var parent = false + var selector = Bootstrap.getSelectorFromElement(element) + + if (selector) { + parent = $(selector)[0] } - var old = $.fn.alert + if (!parent) { + parent = $(element).closest('.' + Alert._ClassName.ALERT)[0] + } - $.fn.alert = Plugin - $.fn.alert.Constructor = Alert + return parent +} - // ALERT NO CONFLICT - // ================= +/** + * Trigger close event on element + * @return {$.Event} + * @private + */ +Alert.prototype._triggerCloseEvent = function (element) { + var closeEvent = $.Event(Alert._Event.CLOSE) + $(element).trigger(closeEvent) + return closeEvent +} + + +/** + * Trigger closed event and remove element from dom + * @private + */ +Alert.prototype._removeElement = function (element) { + $(element).removeClass(Alert._ClassName.IN) - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this + if (!Bootstrap.transition || !$(element).hasClass(Alert._ClassName.FADE)) { + this._destroyElement(element) + return } + $(element) + .one(Bootstrap.TRANSITION_END, this._destroyElement.bind(this, element)) + .emulateTransitionEnd(Alert._TRANSITION_DURATION) +} - // ALERT DATA-API - // ============== - $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) +/** + * clean up any lingering jquery data and kill element + * @private + */ +Alert.prototype._destroyElement = function (element) { + $(element) + .detach() + .trigger(Alert._Event.CLOSED) + .remove() +} -}(jQuery); -/* ======================================================================== - * Bootstrap: button.js v3.3.2 +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ + +/** + * @const + * @type {Function} + */ +$.fn[Alert._NAME] = Alert._jQueryInterface + + +/** + * @const + * @type {Function} + */ +$.fn[Alert._NAME]['Constructor'] = Alert + + +/** + * @return {Function} + */ +$.fn[Alert._NAME]['noConflict'] = function () { + $.fn[Alert._NAME] = Alert._JQUERY_NO_CONFLICT + return Alert._jQueryInterface +} + + +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + +$(document).on('click.bs.alert.data-api', Alert._DISMISS_SELECTOR, Alert._handleDismiss(new Alert)) + +/** ======================================================================= + * Bootstrap: button.js v4.0.0 * http://getbootstrap.com/javascript/#buttons * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's generic button component. + * + * Note (@fat): Deprecated "setState" – imo, better solutions for managing a + * buttons state should exist outside this plugin. + * + * Public Methods & Properties: + * + * + $.button + * + $.button.noConflict + * + $.button.Constructor + * + $.button.Constructor.VERSION + * + $.button.Constructor.prototype.toggle + * + * ======================================================================== + */ +'use strict'; -+function ($) { - 'use strict'; - // BUTTON PUBLIC CLASS DEFINITION - // ============================== +/** + * Our Button class. + * @param {Element!} element + * @constructor + */ +var Button = function (element) { - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Button.DEFAULTS, options) - this.isLoading = false - } + /** @private {Element} */ + this._element = element - Button.VERSION = '3.3.2' +} - Button.DEFAULTS = { - loadingText: 'loading...' - } - Button.prototype.setState = function (state) { - var d = 'disabled' - var $el = this.$element - var val = $el.is('input') ? 'val' : 'html' - var data = $el.data() +/** + * @const + * @type {string} + */ +Button['VERSION'] = '4.0.0' - state = state + 'Text' - if (data.resetText == null) $el.data('resetText', $el[val]()) +/** + * @const + * @type {string} + * @private + */ +Button._NAME = 'button' - // push to event loop to allow forms to submit - setTimeout($.proxy(function () { - $el[val](data[state] == null ? this.options[state] : data[state]) - if (state == 'loadingText') { - this.isLoading = true - $el.addClass(d).attr(d, d) - } else if (this.isLoading) { - this.isLoading = false - $el.removeClass(d).removeAttr(d) - } - }, this), 0) - } +/** + * @const + * @type {string} + * @private + */ +Button._DATA_KEY = 'bs.button' - Button.prototype.toggle = function () { - var changed = true - var $parent = this.$element.closest('[data-toggle="buttons"]') - if ($parent.length) { - var $input = this.$element.find('input') - if ($input.prop('type') == 'radio') { - if ($input.prop('checked') && this.$element.hasClass('active')) changed = false - else $parent.find('.active').removeClass('active') - } - if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') - } else { - this.$element.attr('aria-pressed', !this.$element.hasClass('active')) +/** + * @const + * @type {Function} + * @private + */ +Button._JQUERY_NO_CONFLICT = $.fn[Button._NAME] + + +/** + * @const + * @enum {string} + * @private + */ +Button._ClassName = { + ACTIVE : 'active', + BUTTON : 'btn', + FOCUS : 'focus' +} + + +/** + * @const + * @enum {string} + * @private + */ +Button._Selector = { + DATA_TOGGLE_CARROT : '[data-toggle^="button"]', + DATA_TOGGLE : '[data-toggle="buttons"]', + INPUT : 'input', + ACTIVE : '.active', + BUTTON : '.btn' +} + + +/** + * Provides the jQuery Interface for the Button component. + * @param {string=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Button._jQueryInterface = function (opt_config) { + return this.each(function () { + var data = $(this).data(Button._DATA_KEY) + + if (!data) { + data = new Button(this) + $(this).data(Button._DATA_KEY, data) } - if (changed) this.$element.toggleClass('active') + if (opt_config === 'toggle') { + data[opt_config]() + } + }) +} + + +/** + * Toggle's the button active state + */ +Button.prototype['toggle'] = function () { + var triggerChangeEvent = true + var rootElement = $(this._element).closest(Button._Selector.DATA_TOGGLE)[0] + + if (rootElement) { + var input = $(this._element).find(Button._Selector.INPUT)[0] + if (input) { + if (input.type == 'radio') { + if (input.checked && $(this._element).hasClass(Button._ClassName.ACTIVE)) { + triggerChangeEvent = false + } else { + var activeElement = $(rootElement).find(Button._Selector.ACTIVE)[0] + if (activeElement) { + $(activeElement).removeClass(Button._ClassName.ACTIVE) + } + } + } + + if (triggerChangeEvent) { + input.checked = !$(this._element).hasClass(Button._ClassName.ACTIVE) + $(this._element).trigger('change') + } + } + } else { + this._element.setAttribute('aria-pressed', !$(this._element).hasClass(Button._ClassName.ACTIVE)) } + if (triggerChangeEvent) { + $(this._element).toggleClass(Button._ClassName.ACTIVE) + } +} - // BUTTON PLUGIN DEFINITION - // ======================== - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.button') - var options = typeof option == 'object' && option +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ - if (!data) $this.data('bs.button', (data = new Button(this, options))) +/** + * @const + * @type {Function} + */ +$.fn[Button._NAME] = Button._jQueryInterface - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - var old = $.fn.button +/** + * @const + * @type {Function} + */ +$.fn[Button._NAME]['Constructor'] = Button - $.fn.button = Plugin - $.fn.button.Constructor = Button +/** + * @const + * @type {Function} + */ +$.fn[Button._NAME]['noConflict'] = function () { + $.fn[Button._NAME] = Button._JQUERY_NO_CONFLICT + return this +} - // BUTTON NO CONFLICT - // ================== - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ +$(document) + .on('click.bs.button.data-api', Button._Selector.DATA_TOGGLE_CARROT, function (event) { + event.preventDefault() - // BUTTON DATA-API - // =============== + var button = event.target - $(document) - .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - Plugin.call($btn, 'toggle') - e.preventDefault() - }) - .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { - $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) - }) + if (!$(button).hasClass(Button._ClassName.BUTTON)) { + button = $(button).closest(Button._Selector.BUTTON) + } -}(jQuery); + Button._jQueryInterface.call($(button), 'toggle') + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', Button._Selector.DATA_TOGGLE_CARROT, function (event) { + var button = $(event.target).closest(Button._Selector.BUTTON)[0] + $(button).toggleClass(Button._ClassName.FOCUS, /^focus(in)?$/.test(event.type)) + }) -/* ======================================================================== - * Bootstrap: carousel.js v3.3.2 +/** ======================================================================= + * Bootstrap: carousel.js v4.0.0 * http://getbootstrap.com/javascript/#carousel * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's carousel. A slideshow component for cycling + * through elements, like a carousel. Nested carousels are not supported. + * + * Public Methods & Properties: + * + * + $.carousel + * + $.carousel.noConflict + * + $.carousel.Constructor + * + $.carousel.Constructor.VERSION + * + $.carousel.Constructor.Defaults + * + $.carousel.Constructor.Defaults.interval + * + $.carousel.Constructor.Defaults.pause + * + $.carousel.Constructor.Defaults.wrap + * + $.carousel.Constructor.Defaults.keyboard + * + $.carousel.Constructor.Defaults.slide + * + $.carousel.Constructor.prototype.next + * + $.carousel.Constructor.prototype.prev + * + $.carousel.Constructor.prototype.pause + * + $.carousel.Constructor.prototype.cycle + * + * ======================================================================== + */ +'use strict'; -+function ($) { - 'use strict'; - // CAROUSEL CLASS DEFINITION - // ========================= +/** + * Our carousel class. + * @param {Element!} element + * @param {Object=} opt_config + * @constructor + */ +var Carousel = function (element, opt_config) { + + /** @private {Element} */ + this._element = $(element)[0] + + /** @private {Element} */ + this._indicatorsElement = $(this._element).find(Carousel._Selector.INDICATORS)[0] + + /** @private {?Object} */ + this._config = opt_config || null - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.paused = - this.sliding = - this.interval = - this.$active = - this.$items = null + /** @private {boolean} */ + this._isPaused = false - this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + /** @private {boolean} */ + this._isSliding = false + + /** @private {?number} */ + this._interval = null + + /** @private {?Element} */ + this._activeElement = null + + /** @private {?Array} */ + this._items = null + + this._addEventListeners() + +} + + +/** + * @const + * @type {string} + */ +Carousel['VERSION'] = '4.0.0' - this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element - .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) - .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + +/** + * @const + * @type {Object} + */ +Carousel['Defaults'] = { + 'interval' : 5000, + 'pause' : 'hover', + 'wrap' : true, + 'keyboard' : true, + 'slide' : false +} + + +/** + * @const + * @type {string} + * @private + */ +Carousel._NAME = 'carousel' + + +/** + * @const + * @type {string} + * @private + */ +Carousel._DATA_KEY = 'bs.carousel' + + +/** + * @const + * @type {number} + * @private + */ +Carousel._TRANSITION_DURATION = 600 + + +/** + * @const + * @enum {string} + * @private + */ +Carousel._Direction = { + NEXT : 'next', + PREVIOUS : 'prev' +} + + +/** + * @const + * @enum {string} + * @private + */ +Carousel._Event = { + SLIDE : 'slide.bs.carousel', + SLID : 'slid.bs.carousel' +} + + +/** + * @const + * @enum {string} + * @private + */ +Carousel._ClassName = { + CAROUSEL : 'carousel', + ACTIVE : 'active', + SLIDE : 'slide', + RIGHT : 'right', + LEFT : 'left', + ITEM : 'carousel-item' +} + + +/** + * @const + * @enum {string} + * @private + */ +Carousel._Selector = { + ACTIVE : '.active', + ACTIVE_ITEM : '.active.carousel-item', + ITEM : '.carousel-item', + NEXT_PREV : '.next, .prev', + INDICATORS : '.carousel-indicators' +} + + +/** + * @const + * @type {Function} + * @private + */ +Carousel._JQUERY_NO_CONFLICT = $.fn[Carousel._NAME] + + +/** + * @param {Object=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Carousel._jQueryInterface = function (opt_config) { + return this.each(function () { + var data = $(this).data(Carousel._DATA_KEY) + var config = $.extend({}, Carousel['Defaults'], $(this).data(), typeof opt_config == 'object' && opt_config) + var action = typeof opt_config == 'string' ? opt_config : config.slide + + if (!data) { + data = new Carousel(this, config) + $(this).data(Carousel._DATA_KEY, data) + } + + if (typeof opt_config == 'number') { + data.to(opt_config) + + } else if (action) { + data[action]() + + } else if (config.interval) { + data['pause']() + data['cycle']() + } + }) +} + + +/** + * Click handler for data api + * @param {Event} event + * @this {Element} + * @private + */ +Carousel._dataApiClickHandler = function (event) { + var selector = Bootstrap.getSelectorFromElement(this) + + if (!selector) { + return } - Carousel.VERSION = '3.3.2' + var target = $(selector)[0] + + if (!target || !$(target).hasClass(Carousel._ClassName.CAROUSEL)) { + return + } - Carousel.TRANSITION_DURATION = 600 + var config = $.extend({}, $(target).data(), $(this).data()) - Carousel.DEFAULTS = { - interval: 5000, - pause: 'hover', - wrap: true, - keyboard: true + var slideIndex = this.getAttribute('data-slide-to') + if (slideIndex) { + config.interval = false } - Carousel.prototype.keydown = function (e) { - if (/input|textarea/i.test(e.target.tagName)) return - switch (e.which) { - case 37: this.prev(); break - case 39: this.next(); break - default: return - } + Carousel._jQueryInterface.call($(target), config) - e.preventDefault() + if (slideIndex) { + $(target).data(Carousel._DATA_KEY).to(slideIndex) } - Carousel.prototype.cycle = function (e) { - e || (this.paused = false) + event.preventDefault() +} - this.interval && clearInterval(this.interval) - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) +/** + * Advance the carousel to the next slide + */ +Carousel.prototype['next'] = function () { + if (!this._isSliding) { + this._slide(Carousel._Direction.NEXT) + } +} - return this + +/** + * Return the carousel to the previous slide + */ +Carousel.prototype['prev'] = function () { + if (!this._isSliding) { + this._slide(Carousel._Direction.PREVIOUS) } +} + - Carousel.prototype.getItemIndex = function (item) { - this.$items = item.parent().children('.carousel-item') - return this.$items.index(item || this.$active) +/** + * Pause the carousel cycle + * @param {Event=} opt_event + */ +Carousel.prototype['pause'] = function (opt_event) { + if (!opt_event) { + this._isPaused = true } - Carousel.prototype.getItemForDirection = function (direction, active) { - var activeIndex = this.getItemIndex(active) - var willWrap = (direction == 'prev' && activeIndex === 0) - || (direction == 'next' && activeIndex == (this.$items.length - 1)) - if (willWrap && !this.options.wrap) return active - var delta = direction == 'prev' ? -1 : 1 - var itemIndex = (activeIndex + delta) % this.$items.length - return this.$items.eq(itemIndex) + if ($(this._element).find(Carousel._Selector.NEXT_PREV)[0] && Bootstrap.transition) { + $(this._element).trigger(Bootstrap.transition.end) + this['cycle'](true) } - Carousel.prototype.to = function (pos) { - var that = this - var activeIndex = this.getItemIndex(this.$active = this.$element.find('.carousel-item.active')) + clearInterval(this._interval) + this._interval = null +} - if (pos > (this.$items.length - 1) || pos < 0) return - if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" - if (activeIndex == pos) return this.pause().cycle() +/** + * Cycle to the next carousel item + * @param {Event|boolean=} opt_event + */ +Carousel.prototype['cycle'] = function (opt_event) { + if (!opt_event) { + this._isPaused = false + } - return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + if (this._interval) { + clearInterval(this._interval) + this._interval = null } - Carousel.prototype.pause = function (e) { - e || (this.paused = true) + if (this._config['interval'] && !this._isPaused) { + this._interval = setInterval(this['next'].bind(this), this._config['interval']) + } +} + + +/** + * @return {Object} + */ +Carousel.prototype['getConfig'] = function () { + return this._config +} - if (this.$element.find('.next, .prev').length && $.support.transition) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - this.interval = clearInterval(this.interval) +/** + * Move active carousel item to specified index + * @param {number} index + */ +Carousel.prototype.to = function (index) { + this._activeElement = $(this._element).find(Carousel._Selector.ACTIVE_ITEM)[0] - return this + var activeIndex = this._getItemIndex(this._activeElement) + + if (index > (this._items.length - 1) || index < 0) { + return } - Carousel.prototype.next = function () { - if (this.sliding) return - return this.slide('next') + if (this._isSliding) { + $(this._element).one(Carousel._Event.SLID, function () { this.to(index) }.bind(this)) + return } - Carousel.prototype.prev = function () { - if (this.sliding) return - return this.slide('prev') + if (activeIndex == index) { + this['pause']() + this['cycle']() + return } - Carousel.prototype.slide = function (type, next) { - var $active = this.$element.find('.carousel-item.active') - var $next = next || this.getItemForDirection(type, $active) - var isCycling = this.interval - var direction = type == 'next' ? 'left' : 'right' - var that = this + var direction = index > activeIndex ? + Carousel._Direction.NEXT : + Carousel._Direction.PREVIOUS - if ($next.hasClass('active')) return (this.sliding = false) + this._slide(direction, this._items[index]) +} - var relatedTarget = $next[0] - var slideEvent = $.Event('slide.bs.carousel', { - relatedTarget: relatedTarget, - direction: direction - }) - this.$element.trigger(slideEvent) - if (slideEvent.isDefaultPrevented()) return - - this.sliding = true - - isCycling && this.pause() - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) - $nextIndicator && $nextIndicator.addClass('active') - } - - var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" - if ($.support.transition && this.$element.hasClass('slide')) { - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - $active - .one('bsTransitionEnd', function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { - that.$element.trigger(slidEvent) - }, 0) - }) - .emulateTransitionEnd(Carousel.TRANSITION_DURATION) - } else { - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger(slidEvent) - } - isCycling && this.cycle() +/** + * Add event listeners to root element + * @private + */ +Carousel.prototype._addEventListeners = function () { + if (this._config['keyboard']) { + $(this._element).on('keydown.bs.carousel', this._keydown.bind(this)) + } - return this + if (this._config['pause'] == 'hover' && !('ontouchstart' in document.documentElement)) { + $(this._element) + .on('mouseenter.bs.carousel', this['pause'].bind(this)) + .on('mouseleave.bs.carousel', this['cycle'].bind(this)) } +} - // CAROUSEL PLUGIN DEFINITION - // ========================== +/** + * Keydown handler + * @param {Event} event + * @private + */ +Carousel.prototype._keydown = function (event) { + event.preventDefault() - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.carousel') - var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) - var action = typeof option == 'string' ? option : options.slide + if (/input|textarea/i.test(event.target.tagName)) return - if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) + switch (event.which) { + case 37: this['prev'](); break + case 39: this['next'](); break + default: return } +} - var old = $.fn.carousel - $.fn.carousel = Plugin - $.fn.carousel.Constructor = Carousel +/** + * Get item index + * @param {Element} element + * @return {number} + * @private + */ +Carousel.prototype._getItemIndex = function (element) { + this._items = $.makeArray($(element).parent().find(Carousel._Selector.ITEM)) + return this._items.indexOf(element) +} - // CAROUSEL NO CONFLICT - // ==================== - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this +/** + * Get next displayed item based on direction + * @param {Carousel._Direction} direction + * @param {Element} activeElement + * @return {Element} + * @private + */ +Carousel.prototype._getItemByDirection = function (direction, activeElement) { + var activeIndex = this._getItemIndex(activeElement) + var isGoingToWrap = (direction === Carousel._Direction.PREVIOUS && activeIndex === 0) || + (direction === Carousel._Direction.NEXT && activeIndex == (this._items.length - 1)) + + if (isGoingToWrap && !this._config['wrap']) { + return activeElement } + var delta = direction == Carousel._Direction.PREVIOUS ? -1 : 1 + var itemIndex = (activeIndex + delta) % this._items.length - // CAROUSEL DATA-API - // ================= + return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex] +} - var clickHandler = function (e) { - var href - var $this = $(this) - var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 - if (!$target.hasClass('carousel')) return - var options = $.extend({}, $target.data(), $this.data()) - var slideIndex = $this.attr('data-slide-to') - if (slideIndex) options.interval = false - Plugin.call($target, options) +/** + * Trigger slide event on element + * @param {Element} relatedTarget + * @param {Carousel._ClassName} directionalClassname + * @return {$.Event} + * @private + */ +Carousel.prototype._triggerSlideEvent = function (relatedTarget, directionalClassname) { + var slideEvent = $.Event(Carousel._Event.SLIDE, { + relatedTarget: relatedTarget, + direction: directionalClassname + }) - if (slideIndex) { - $target.data('bs.carousel').to(slideIndex) + $(this._element).trigger(slideEvent) + + return slideEvent +} + + +/** + * Set the active indicator if available + * @param {Element} element + * @private + */ +Carousel.prototype._setActiveIndicatorElement = function (element) { + if (this._indicatorsElement) { + $(this._indicatorsElement) + .find(Carousel._Selector.ACTIVE) + .removeClass(Carousel._ClassName.ACTIVE) + + var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)] + if (nextIndicator) { + $(nextIndicator).addClass(Carousel._ClassName.ACTIVE) } + } +} + + +/** + * Slide the carousel element in a direction + * @param {Carousel._Direction} direction + * @param {Element=} opt_nextElement + */ +Carousel.prototype._slide = function (direction, opt_nextElement) { + var activeElement = $(this._element).find(Carousel._Selector.ACTIVE_ITEM)[0] + var nextElement = opt_nextElement || activeElement && this._getItemByDirection(direction, activeElement) + + var isCycling = !!this._interval - e.preventDefault() + var directionalClassName = direction == Carousel._Direction.NEXT ? + Carousel._ClassName.LEFT : + Carousel._ClassName.RIGHT + + if (nextElement && $(nextElement).hasClass(Carousel._ClassName.ACTIVE)) { + this._isSliding = false + return } - $(document) - .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) - .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + var slideEvent = this._triggerSlideEvent(nextElement, directionalClassName) + if (slideEvent.isDefaultPrevented()) { + return + } - $(window).on('load', function () { - $('[data-ride="carousel"]').each(function () { - var $carousel = $(this) - Plugin.call($carousel, $carousel.data()) - }) - }) + if (!activeElement || !nextElement) { + // some weirdness is happening, so we bail (maybe throw exception here alerting user that they're dom is off + return + } -}(jQuery); + this._isSliding = true + + if (isCycling) { + this['pause']() + } + + this._setActiveIndicatorElement(nextElement) + + var slidEvent = $.Event(Carousel._Event.SLID, { relatedTarget: nextElement, direction: directionalClassName }) + + if (Bootstrap.transition && $(this._element).hasClass(Carousel._ClassName.SLIDE)) { + $(nextElement).addClass(direction) + + Bootstrap.reflow(nextElement) + + $(activeElement).addClass(directionalClassName) + $(nextElement).addClass(directionalClassName) -/* ======================================================================== - * Bootstrap: collapse.js v3.3.2 + $(activeElement) + .one(Bootstrap.TRANSITION_END, function () { + $(nextElement) + .removeClass(directionalClassName) + .removeClass(direction) + + $(nextElement).addClass(Carousel._ClassName.ACTIVE) + + $(activeElement) + .removeClass(Carousel._ClassName.ACTIVE) + .removeClass(direction) + .removeClass(directionalClassName) + + this._isSliding = false + + setTimeout(function () { + $(this._element).trigger(slidEvent) + }.bind(this), 0) + }.bind(this)) + .emulateTransitionEnd(Carousel._TRANSITION_DURATION) + + } else { + $(activeElement).removeClass(Carousel._ClassName.ACTIVE) + $(nextElement).addClass(Carousel._ClassName.ACTIVE) + + this._isSliding = false + $(this._element).trigger(slidEvent) + } + + if (isCycling) { + this['cycle']() + } +} + + +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ + +/** + * @const + * @type {Function} + */ +$.fn[Carousel._NAME] = Carousel._jQueryInterface + + +/** + * @const + * @type {Function} + */ +$.fn[Carousel._NAME]['Constructor'] = Carousel + + +/** + * @const + * @type {Function} + */ +$.fn[Carousel._NAME]['noConflict'] = function () { + $.fn[Carousel._NAME] = Carousel._JQUERY_NO_CONFLICT + return this +} + + +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + +$(document) + .on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', Carousel._dataApiClickHandler) + +$(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Carousel._jQueryInterface.call($carousel, /** @type {Object} */ ($carousel.data())) + }) +}) + +/** ======================================================================= + * Bootstrap: collapse.js v4.0.0 * http://getbootstrap.com/javascript/#collapse * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's collapse plugin. Flexible support for + * collapsible components like accordions and navigation. + * + * Public Methods & Properties: + * + * + $.carousel + * + $.carousel.noConflict + * + $.carousel.Constructor + * + $.carousel.Constructor.VERSION + * + $.carousel.Constructor.Defaults + * + $.carousel.Constructor.Defaults.toggle + * + $.carousel.Constructor.Defaults.trigger + * + $.carousel.Constructor.Defaults.parent + * + $.carousel.Constructor.prototype.toggle + * + $.carousel.Constructor.prototype.show + * + $.carousel.Constructor.prototype.hide + * + * ======================================================================== + */ +'use strict'; -+function ($) { - 'use strict'; - // COLLAPSE PUBLIC CLASS DEFINITION - // ================================ +/** + * Our collapse class. + * @param {Element!} element + * @param {Object=} opt_config + * @constructor + */ +var Collapse = function (element, opt_config) { - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Collapse.DEFAULTS, options) - this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') - this.transitioning = null + /** @private {Element} */ + this._element = element - if (this.options.parent) { - this.$parent = this.getParent() - } else { - this.addAriaAndCollapsedClass(this.$element, this.$trigger) - } + /** @private {Object} */ + this._config = $.extend({}, Collapse['Defaults'], opt_config) - if (this.options.toggle) this.toggle() - } + /** @private {Element} */ + this._trigger = typeof this._config['trigger'] == 'string' ? + $(this._config['trigger'])[0] : this._config['trigger'] - Collapse.VERSION = '3.3.2' + /** @private {boolean} */ + this._isTransitioning = false - Collapse.TRANSITION_DURATION = 350 + /** @private {?Element} */ + this._parent = this._config['parent'] ? this._getParent() : null - Collapse.DEFAULTS = { - toggle: true, - trigger: '[data-toggle="collapse"]' + if (!this._config['parent']) { + this._addAriaAndCollapsedClass(this._element, this._trigger) } - Collapse.prototype.dimension = function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' + if (this._config['toggle']) { + this['toggle']() } - Collapse.prototype.show = function () { - if (this.transitioning || this.$element.hasClass('in')) return +} - var activesData - var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') - if (actives && actives.length) { - activesData = actives.data('bs.collapse') - if (activesData && activesData.transitioning) return - } +/** + * @const + * @type {string} + */ +Collapse['VERSION'] = '4.0.0' - var startEvent = $.Event('show.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - if (actives && actives.length) { - Plugin.call(actives, 'hide') - activesData || actives.data('bs.collapse', null) - } +/** + * @const + * @type {Object} + */ +Collapse['Defaults'] = { + 'toggle' : true, + 'trigger' : '[data-toggle="collapse"]', + 'parent' : null +} - var dimension = this.dimension() - this.$element - .removeClass('collapse') - .addClass('collapsing')[dimension](0) - .attr('aria-expanded', true) +/** + * @const + * @type {string} + * @private + */ +Collapse._NAME = 'collapse' - this.$trigger - .removeClass('collapsed') - .attr('aria-expanded', true) - this.transitioning = 1 +/** + * @const + * @type {string} + * @private + */ +Collapse._DATA_KEY = 'bs.collapse' - var complete = function () { - this.$element - .removeClass('collapsing') - .addClass('collapse in')[dimension]('') - this.transitioning = 0 - this.$element - .trigger('shown.bs.collapse') + +/** + * @const + * @type {number} + * @private + */ +Collapse._TRANSITION_DURATION = 600 + + +/** + * @const + * @type {Function} + * @private + */ +Collapse._JQUERY_NO_CONFLICT = $.fn[Collapse._NAME] + + +/** + * @const + * @enum {string} + * @private + */ +Collapse._Event = { + SHOW : 'show.bs.collapse', + SHOWN : 'shown.bs.collapse', + HIDE : 'hide.bs.collapse', + HIDDEN : 'hidden.bs.collapse' +} + + +/** + * @const + * @enum {string} + * @private + */ +Collapse._ClassName = { + IN : 'in', + COLLAPSE : 'collapse', + COLLAPSING : 'collapsing', + COLLAPSED : 'collapsed' +} + + +/** + * @const + * @enum {string} + * @private + */ +Collapse._Dimension = { + WIDTH : 'width', + HEIGHT : 'height' +} + + +/** + * @const + * @enum {string} + * @private + */ +Collapse._Selector = { + ACTIVES : '.panel > .in, .panel > .collapsing' +} + + +/** + * Provides the jQuery Interface for the alert component. + * @param {Object|string=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Collapse._jQueryInterface = function (opt_config) { + return this.each(function () { + var $this = $(this) + var data = $this.data(Collapse._DATA_KEY) + var config = $.extend({}, Collapse['Defaults'], $this.data(), typeof opt_config == 'object' && opt_config) + + if (!data && config['toggle'] && opt_config == 'show') { + config['toggle'] = false } - if (!$.support.transition) return complete.call(this) + if (!data) { + data = new Collapse(this, config) + $this.data(Collapse._DATA_KEY, data) + } - var scrollSize = $.camelCase(['scroll', dimension].join('-')) + if (typeof opt_config == 'string') { + data[opt_config]() + } + }) +} - this.$element - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) - } - Collapse.prototype.hide = function () { - if (this.transitioning || !this.$element.hasClass('in')) return +/** + * Function for getting target element from element + * @return {Element} + * @private + */ +Collapse._getTargetFromElement = function (element) { + var selector = Bootstrap.getSelectorFromElement(element) - var startEvent = $.Event('hide.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return + return selector ? $(selector)[0] : null +} - var dimension = this.dimension() - this.$element[dimension](this.$element[dimension]())[0].offsetHeight +/** + * Toggles the collapse element based on the presence of the 'in' class + */ +Collapse.prototype['toggle'] = function () { + if ($(this._element).hasClass(Collapse._ClassName.IN)) { + this['hide']() + } else { + this['show']() + } +} - this.$element - .addClass('collapsing') - .removeClass('collapse in') - .attr('aria-expanded', false) - this.$trigger - .addClass('collapsed') - .attr('aria-expanded', false) +/** + * Show's the collapsing element + */ +Collapse.prototype['show'] = function () { + if (this._isTransitioning || $(this._element).hasClass(Collapse._ClassName.IN)) { + return + } - this.transitioning = 1 + var activesData, actives - var complete = function () { - this.transitioning = 0 - this.$element - .removeClass('collapsing') - .addClass('collapse') - .trigger('hidden.bs.collapse') + if (this._parent) { + actives = $.makeArray($(Collapse._Selector.ACTIVES)) + if (!actives.length) { + actives = null } + } - if (!$.support.transition) return complete.call(this) + if (actives) { + activesData = $(actives).data(Collapse._DATA_KEY) + if (activesData && activesData._isTransitioning) { + return + } + } - this.$element - [dimension](0) - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + var startEvent = $.Event(Collapse._Event.SHOW) + $(this._element).trigger(startEvent) + if (startEvent.isDefaultPrevented()) { + return } - Collapse.prototype.toggle = function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() + if (actives) { + Collapse._jQueryInterface.call($(actives), 'hide') + if (!activesData) { + $(actives).data(Collapse._DATA_KEY, null) + } } - Collapse.prototype.getParent = function () { - return $(this.options.parent) - .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') - .each($.proxy(function (i, element) { - var $element = $(element) - this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) - }, this)) - .end() + var dimension = this._getDimension() + + $(this._element) + .removeClass(Collapse._ClassName.COLLAPSE) + .addClass(Collapse._ClassName.COLLAPSING) + + this._element.style[dimension] = 0 + this._element.setAttribute('aria-expanded', true) + + if (this._trigger) { + $(this._trigger).removeClass(Collapse._ClassName.COLLAPSED) + this._trigger.setAttribute('aria-expanded', true) } - Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { - var isOpen = $element.hasClass('in') + this['setTransitioning'](true) - $element.attr('aria-expanded', isOpen) - $trigger - .toggleClass('collapsed', !isOpen) - .attr('aria-expanded', isOpen) + var complete = function () { + $(this._element) + .removeClass(Collapse._ClassName.COLLAPSING) + .addClass(Collapse._ClassName.COLLAPSE) + .addClass(Collapse._ClassName.IN) + + this._element.style[dimension] = '' + + this['setTransitioning'](false) + + $(this._element).trigger(Collapse._Event.SHOWN) + }.bind(this) + + if (!Bootstrap.transition) { + complete() + return } - function getTargetFromTrigger($trigger) { - var href - var target = $trigger.attr('data-target') - || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + var scrollSize = 'scroll' + (dimension[0].toUpperCase() + dimension.slice(1)) + + $(this._element) + .one(Bootstrap.TRANSITION_END, complete) + .emulateTransitionEnd(Collapse._TRANSITION_DURATION) - return $(target) + this._element.style[dimension] = this._element[scrollSize] + 'px' +} + + +/** + * Hides's the collapsing element + */ +Collapse.prototype['hide'] = function () { + if (this._isTransitioning || !$(this._element).hasClass(Collapse._ClassName.IN)) { + return } + var startEvent = $.Event(Collapse._Event.HIDE) + $(this._element).trigger(startEvent) + if (startEvent.isDefaultPrevented()) return - // COLLAPSE PLUGIN DEFINITION - // ========================== + var dimension = this._getDimension() + var offsetDimension = dimension === Collapse._Dimension.WIDTH ? + 'offsetWidth' : 'offsetHeight' - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.collapse') - var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + this._element.style[dimension] = this._element[offsetDimension] + 'px' - if (!data && options.toggle && option == 'show') options.toggle = false - if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) + Bootstrap.reflow(this._element) + + $(this._element) + .addClass(Collapse._ClassName.COLLAPSING) + .removeClass(Collapse._ClassName.COLLAPSE) + .removeClass(Collapse._ClassName.IN) + + this._element.setAttribute('aria-expanded', false) + + if (this._trigger) { + $(this._trigger).addClass(Collapse._ClassName.COLLAPSED) + this._trigger.setAttribute('aria-expanded', false) } - var old = $.fn.collapse + this['setTransitioning'](true) - $.fn.collapse = Plugin - $.fn.collapse.Constructor = Collapse + var complete = function () { + this['setTransitioning'](false) + $(this._element) + .removeClass(Collapse._ClassName.COLLAPSING) + .addClass(Collapse._ClassName.COLLAPSE) + .trigger(Collapse._Event.HIDDEN) + }.bind(this) - // COLLAPSE NO CONFLICT - // ==================== + this._element.style[dimension] = 0 - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this + if (!Bootstrap.transition) { + return complete() } + $(this._element) + .one(Bootstrap.TRANSITION_END, complete) + .emulateTransitionEnd(Collapse._TRANSITION_DURATION) +} - // COLLAPSE DATA-API - // ================= - $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { - var $this = $(this) - if (!$this.attr('data-target')) e.preventDefault() +/** + * @param {boolean} isTransitioning + */ +Collapse.prototype['setTransitioning'] = function (isTransitioning) { + this._isTransitioning = isTransitioning +} - var $target = getTargetFromTrigger($this) - var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) - Plugin.call($target, option) - }) +/** + * Returns the collapsing dimension + * @return {string} + * @private + */ +Collapse.prototype._getDimension = function () { + var hasWidth = $(this._element).hasClass(Collapse._Dimension.WIDTH) + return hasWidth ? Collapse._Dimension.WIDTH : Collapse._Dimension.HEIGHT +} -}(jQuery); -/* ======================================================================== - * Bootstrap: dropdown.js v3.3.2 - * http://getbootstrap.com/javascript/#dropdowns +/** + * Returns the parent element + * @return {Element} + * @private + */ +Collapse.prototype._getParent = function () { + var selector = '[data-toggle="collapse"][data-parent="' + this._config['parent'] + '"]' + var parent = $(this._config['parent'])[0] + var elements = /** @type {Array.<Element>} */ ($.makeArray($(parent).find(selector))) + + for (var i = 0; i < elements.length; i++) { + this._addAriaAndCollapsedClass(Collapse._getTargetFromElement(elements[i]), elements[i]) + } + + return parent +} + + +/** + * Returns the parent element + * @param {Element} element + * @param {Element} trigger + * @private + */ +Collapse.prototype._addAriaAndCollapsedClass = function (element, trigger) { + if (element) { + var isOpen = $(element).hasClass(Collapse._ClassName.IN) + element.setAttribute('aria-expanded', isOpen) + + if (trigger) { + trigger.setAttribute('aria-expanded', isOpen) + $(trigger).toggleClass(Collapse._ClassName.COLLAPSED, !isOpen) + } + } +} + + + +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ + +/** + * @const + * @type {Function} + */ +$.fn[Collapse._NAME] = Collapse._jQueryInterface + + +/** + * @const + * @type {Function} + */ +$.fn[Collapse._NAME]['Constructor'] = Collapse + + +/** + * @const + * @type {Function} + */ +$.fn[Collapse._NAME]['noConflict'] = function () { + $.fn[Collapse._NAME] = Collapse._JQUERY_NO_CONFLICT + return this +} + + +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + +$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (event) { + event.preventDefault() + + var target = Collapse._getTargetFromElement(this) + + var data = $(target).data(Collapse._DATA_KEY) + var config = data ? 'toggle' : $.extend({}, $(this).data(), { trigger: this }) + + Collapse._jQueryInterface.call($(target), config) +}) + +/** ======================================================================= + * Bootstrap: dropdown.js v4.0.0 + * http://getbootstrap.com/javascript/#dropdown * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Add dropdown menus to nearly anything with this simple + * plugin, including the navbar, tabs, and pills. + * + * Public Methods & Properties: + * + * + $.dropdown + * + $.dropdown.noConflict + * + $.dropdown.Constructor + * + $.dropdown.Constructor.VERSION + * + $.dropdown.Constructor.prototype.toggle + * + * ======================================================================== + */ +'use strict'; -+function ($) { - 'use strict'; - // DROPDOWN CLASS DEFINITION - // ========================= +/** + * Our dropdown class. + * @param {Element!} element + * @constructor + */ +var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this['toggle']) +} - var backdrop = '.dropdown-backdrop' - var toggle = '[data-toggle="dropdown"]' - var Dropdown = function (element) { - $(element).on('click.bs.dropdown', this.toggle) - } - Dropdown.VERSION = '3.3.2' +/** + * @const + * @type {string} + */ +Dropdown['VERSION'] = '4.0.0' - Dropdown.prototype.toggle = function (e) { - var $this = $(this) - if ($this.is('.disabled, :disabled')) return +/** + * @const + * @type {string} + * @private + */ +Dropdown._NAME = 'dropdown' - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - clearMenus() +/** + * @const + * @type {string} + * @private + */ +Dropdown._DATA_KEY = 'bs.dropdown' - if (!isActive) { - if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { - // if mobile we use a backdrop because click events don't delegate - $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus) - } - var relatedTarget = { relatedTarget: this } - $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) +/** + * @const + * @type {Function} + * @private + */ +Dropdown._JQUERY_NO_CONFLICT = $.fn[Dropdown._NAME] - if (e.isDefaultPrevented()) return - $this - .trigger('focus') - .attr('aria-expanded', 'true') +/** + * @const + * @enum {string} + * @private + */ +Dropdown._Event = { + HIDE : 'hide.bs.dropdown', + HIDDEN : 'hidden.bs.dropdown', + SHOW : 'show.bs.dropdown', + SHOWN : 'shown.bs.dropdown' +} + - $parent - .toggleClass('open') - .trigger('shown.bs.dropdown', relatedTarget) +/** + * @const + * @enum {string} + * @private + */ +Dropdown._ClassName = { + BACKDROP : 'dropdown-backdrop', + DISABLED : 'disabled', + OPEN : 'open' +} + + +/** + * @const + * @enum {string} + * @private + */ +Dropdown._Selector = { + BACKDROP : '.dropdown-backdrop', + DATA_TOGGLE : '[data-toggle="dropdown"]', + FORM_CHILD : '.dropdown form', + ROLE_MENU : '[role="menu"]', + ROLE_LISTBOX : '[role="listbox"]', + NAVBAR_NAV : '.navbar-nav', + VISIBLE_ITEMS : '[role="menu"] li:not(.divider) a, [role="listbox"] li:not(.divider) a' +} + + +/** + * Provides the jQuery Interface for the alert component. + * @param {string=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Dropdown._jQueryInterface = function (opt_config) { + return this.each(function () { + var data = $(this).data(Dropdown._DATA_KEY) + + if (!data) { + $(this).data(Dropdown._DATA_KEY, (data = new Dropdown(this))) } - return false - } + if (typeof opt_config === 'string') { + data[opt_config].call(this) + } + }) +} - Dropdown.prototype.keydown = function (e) { - if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return - var $this = $(this) +/** + * @param {Event=} opt_event + * @private + */ +Dropdown._clearMenus = function (opt_event) { + if (opt_event && opt_event.which == 3) { + return + } - e.preventDefault() - e.stopPropagation() + var backdrop = $(Dropdown._Selector.BACKDROP)[0] + if (backdrop) { + backdrop.parentNode.removeChild(backdrop) + } - if ($this.is('.disabled, :disabled')) return + var toggles = /** @type {Array.<Element>} */ ($.makeArray($(Dropdown._Selector.DATA_TOGGLE))) - var $parent = getParent($this) - var isActive = $parent.hasClass('open') + for (var i = 0; i < toggles.length; i++) { + var parent = Dropdown._getParentFromElement(toggles[i]) + var relatedTarget = { 'relatedTarget': toggles[i] } - if ((!isActive && e.which != 27) || (isActive && e.which == 27)) { - if (e.which == 27) $parent.find(toggle).trigger('focus') - return $this.trigger('click') + if (!$(parent).hasClass(Dropdown._ClassName.OPEN)) { + continue } - var desc = ' li:not(.divider):visible a' - var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc) + var hideEvent = $.Event(Dropdown._Event.HIDE, relatedTarget) + $(parent).trigger(hideEvent) + if (hideEvent.isDefaultPrevented()) { + continue + } - if (!$items.length) return + toggles[i].setAttribute('aria-expanded', 'false') - var index = $items.index(e.target) + $(parent) + .removeClass(Dropdown._ClassName.OPEN) + .trigger(Dropdown._Event.HIDDEN, relatedTarget) + } +} - if (e.which == 38 && index > 0) index-- // up - if (e.which == 40 && index < $items.length - 1) index++ // down - if (!~index) index = 0 - $items.eq(index).trigger('focus') +/** + * @param {Element} element + * @return {Element} + * @private + */ +Dropdown._getParentFromElement = function (element) { + var selector = Bootstrap.getSelectorFromElement(element) + + if (selector) { + var parent = $(selector)[0] } - function clearMenus(e) { - if (e && e.which === 3) return - $(backdrop).remove() - $(toggle).each(function () { - var $this = $(this) - var $parent = getParent($this) - var relatedTarget = { relatedTarget: this } + return /** @type {Element} */ (parent || element.parentNode) +} - if (!$parent.hasClass('open')) return - $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) +/** + * @param {Event} event + * @this {Element} + * @private + */ +Dropdown._dataApiKeydownHandler = function (event) { + if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) { + return + } - if (e.isDefaultPrevented()) return + event.preventDefault() + event.stopPropagation() - $this.attr('aria-expanded', 'false') - $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) - }) + if (this.disabled || $(this).hasClass(Dropdown._ClassName.DISABLED)) { + return } - function getParent($this) { - var selector = $this.attr('data-target') + var parent = Dropdown._getParentFromElement(this) + var isActive = $(parent).hasClass(Dropdown._ClassName.OPEN) - if (!selector) { - selector = $this.attr('href') - selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + if ((!isActive && event.which != 27) || (isActive && event.which == 27)) { + if (event.which == 27) { + var toggle = $(parent).find(Dropdown._Selector.DATA_TOGGLE)[0] + $(toggle).trigger('focus') } + $(this).trigger('click') + return + } - var $parent = selector && $(selector) + var items = $.makeArray($(Dropdown._Selector.VISIBLE_ITEMS)) - return $parent && $parent.length ? $parent : $this.parent() + items = items.filter(function (item) { + return item.offsetWidth || item.offsetHeight + }) + + if (!items.length) { + return } + var index = items.indexOf(event.target) - // DROPDOWN PLUGIN DEFINITION - // ========================== + if (event.which == 38 && index > 0) index-- // up + if (event.which == 40 && index < items.length - 1) index++ // down + if (!~index) index = 0 - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.dropdown') + items[index].focus() +} - if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) - if (typeof option == 'string') data[option].call($this) - }) + +/** + * Toggles the dropdown + * @this {Element} + * @return {boolean|undefined} + */ +Dropdown.prototype['toggle'] = function () { + if (this.disabled || $(this).hasClass(Dropdown._ClassName.DISABLED)) { + return } - var old = $.fn.dropdown + var parent = Dropdown._getParentFromElement(this) + var isActive = $(parent).hasClass(Dropdown._ClassName.OPEN) - $.fn.dropdown = Plugin - $.fn.dropdown.Constructor = Dropdown + Dropdown._clearMenus() + if (isActive) { + return false + } + + if ('ontouchstart' in document.documentElement && !$(parent).closest(Dropdown._Selector.NAVBAR_NAV).length) { + // if mobile we use a backdrop because click events don't delegate + var dropdown = document.createElement('div') + dropdown.className = Dropdown._ClassName.BACKDROP + this.parentNode.insertBefore(this, dropdown) + $(dropdown).on('click', Dropdown._clearMenus) + } - // DROPDOWN NO CONFLICT - // ==================== + var relatedTarget = { 'relatedTarget': this } + var showEvent = $.Event(Dropdown._Event.SHOW, relatedTarget) - $.fn.dropdown.noConflict = function () { - $.fn.dropdown = old - return this + $(parent).trigger(showEvent) + + if (showEvent.isDefaultPrevented()) { + return } + this.focus() + this.setAttribute('aria-expanded', 'true') - // APPLY TO STANDARD DROPDOWN ELEMENTS - // =================================== + $(parent).toggleClass(Dropdown._ClassName.OPEN) - $(document) - .on('click.bs.dropdown.data-api', clearMenus) - .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) - .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) - .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) - .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown) - .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown) + $(parent).trigger(Dropdown._Event.SHOWN, relatedTarget) -}(jQuery); + return false +} -/* ======================================================================== - * Bootstrap: modal.js v3.3.2 - * http://getbootstrap.com/javascript/#modals + +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ + +/** + * @const + * @type {Function} + */ +$.fn[Dropdown._NAME] = Dropdown._jQueryInterface + + +/** + * @const + * @type {Function} + */ +$.fn[Dropdown._NAME]['Constructor'] = Dropdown + + +/** + * @const + * @type {Function} + */ +$.fn[Dropdown._NAME]['noConflict'] = function () { + $.fn[Dropdown._NAME] = Dropdown._JQUERY_NO_CONFLICT + return this +} + + +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + +$(document) + .on('click.bs.dropdown.data-api', Dropdown._clearMenus) + .on('click.bs.dropdown.data-api', Dropdown._Selector.FORM_CHILD, function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', Dropdown._Selector.DATA_TOGGLE, Dropdown.prototype['toggle']) + .on('keydown.bs.dropdown.data-api', Dropdown._Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler) + .on('keydown.bs.dropdown.data-api', Dropdown._Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler) + .on('keydown.bs.dropdown.data-api', Dropdown._Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler) + +/** ======================================================================= + * Bootstrap: modal.js v4.0.0 + * http://getbootstrap.com/javascript/#modal * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's modal plugin. Modals are streamlined, but + * flexible, dialog prompts with the minimum required functionality and + * smart defaults. + * + * Public Methods & Properties: + * + * + $.modal + * + $.modal.noConflict + * + $.modal.Constructor + * + $.modal.Constructor.VERSION + * + $.modal.Constructor.Defaults + * + $.modal.Constructor.Defaults.backdrop + * + $.modal.Constructor.Defaults.keyboard + * + $.modal.Constructor.Defaults.show + * + $.modal.Constructor.prototype.toggle + * + $.modal.Constructor.prototype.show + * + $.modal.Constructor.prototype.hide + * + * ======================================================================== + */ +'use strict'; -+function ($) { - 'use strict'; - // MODAL CLASS DEFINITION - // ====================== +/** + * Our modal class. + * @param {Element} element + * @param {Object} config + * @constructor + */ +var Modal = function (element, config) { - var Modal = function (element, options) { - this.options = options - this.$body = $(document.body) - this.$element = $(element) - this.$backdrop = - this.isShown = null - this.scrollbarWidth = 0 + /** @private {Object} */ + this._config = config - if (this.options.remote) { - this.$element - .find('.modal-content') - .load(this.options.remote, $.proxy(function () { - this.$element.trigger('loaded.bs.modal') - }, this)) - } - } + /** @private {Element} */ + this._element = element - Modal.VERSION = '3.3.2' + /** @private {Element} */ + this._backdrop = null - Modal.TRANSITION_DURATION = 300 - Modal.BACKDROP_TRANSITION_DURATION = 150 + /** @private {boolean} */ + this._isShown = false - Modal.DEFAULTS = { - backdrop: true, - keyboard: true, - show: true - } + /** @private {boolean} */ + this._isBodyOverflowing = false - Modal.prototype.toggle = function (_relatedTarget) { - return this.isShown ? this.hide() : this.show(_relatedTarget) - } + /** @private {number} */ + this._scrollbarWidth = 0 - Modal.prototype.show = function (_relatedTarget) { - var that = this - var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) +} - this.$element.trigger(e) - if (this.isShown || e.isDefaultPrevented()) return +/** + * @const + * @type {string} + */ +Modal['VERSION'] = '4.0.0' - this.isShown = true - this.checkScrollbar() - this.setScrollbar() - this.$body.addClass('modal-open') +/** + * @const + * @type {Object} + */ +Modal['Defaults'] = { + 'backdrop' : true, + 'keyboard' : true, + 'show' : true +} - this.escape() - this.resize() - this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) +/** + * @const + * @type {string} + * @private + */ +Modal._NAME = 'modal' - this.backdrop(function () { - var transition = $.support.transition && that.$element.hasClass('fade') - if (!that.$element.parent().length) { - that.$element.appendTo(that.$body) // don't move modals dom position - } +/** + * @const + * @type {string} + * @private + */ +Modal._DATA_KEY = 'bs.modal' - that.$element - .show() - .scrollTop(0) - if (that.options.backdrop) that.adjustBackdrop() - that.adjustDialog() +/** + * @const + * @type {number} + * @private + */ +Modal._TRANSITION_DURATION = 300 - if (transition) { - that.$element[0].offsetWidth // force reflow - } - that.$element - .addClass('in') - .attr('aria-hidden', false) +/** + * @const + * @type {number} + * @private + */ +Modal._BACKDROP_TRANSITION_DURATION = 150 - that.enforceFocus() - var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) +/** + * @const + * @type {Function} + * @private + */ +Modal._JQUERY_NO_CONFLICT = $.fn[Modal._NAME] - transition ? - that.$element.find('.modal-dialog') // wait for modal to slide in - .one('bsTransitionEnd', function () { - that.$element.trigger('focus').trigger(e) - }) - .emulateTransitionEnd(Modal.TRANSITION_DURATION) : - that.$element.trigger('focus').trigger(e) - }) - } - Modal.prototype.hide = function (e) { - if (e) e.preventDefault() +/** + * @const + * @enum {string} + * @private + */ +Modal._Event = { + HIDE : 'hide.bs.modal', + HIDDEN : 'hidden.bs.modal', + SHOW : 'show.bs.modal', + SHOWN : 'shown.bs.modal' +} + + +/** + * @const + * @enum {string} + * @private + */ +Modal._ClassName = { + BACKDROP : 'modal-backdrop', + OPEN : 'modal-open', + FADE : 'fade', + IN : 'in' +} + + +/** + * @const + * @enum {string} + * @private + */ +Modal._Selector = { + DIALOG : '.modal-dialog', + DATA_TOGGLE : '[data-toggle="modal"]', + DATA_DISMISS : '[data-dismiss="modal"]', + SCROLLBAR_MEASURER : 'modal-scrollbar-measure' +} - e = $.Event('hide.bs.modal') - this.$element.trigger(e) - if (!this.isShown || e.isDefaultPrevented()) return +/** + * Provides the jQuery Interface for the alert component. + * @param {Object|string=} opt_config + * @param {Element=} opt_relatedTarget + * @this {jQuery} + * @return {jQuery} + * @private + */ +Modal._jQueryInterface = function Plugin(opt_config, opt_relatedTarget) { + return this.each(function () { + var data = $(this).data(Modal._DATA_KEY) + var config = $.extend({}, Modal['Defaults'], $(this).data(), typeof opt_config == 'object' && opt_config) + + if (!data) { + data = new Modal(this, config) + $(this).data(Modal._DATA_KEY, data) + } - this.isShown = false + if (typeof opt_config == 'string') { + data[opt_config](opt_relatedTarget) + + } else if (config['show']) { + data['show'](opt_relatedTarget) + } + }) +} - this.escape() - this.resize() - $(document).off('focusin.bs.modal') +/** + * @param {Element} relatedTarget + */ +Modal.prototype['toggle'] = function (relatedTarget) { + return this._isShown ? this['hide']() : this['show'](relatedTarget) +} - this.$element - .removeClass('in') - .attr('aria-hidden', true) - .off('click.dismiss.bs.modal') - $.support.transition && this.$element.hasClass('fade') ? - this.$element - .one('bsTransitionEnd', $.proxy(this.hideModal, this)) - .emulateTransitionEnd(Modal.TRANSITION_DURATION) : - this.hideModal() +/** + * @param {Element} relatedTarget + */ +Modal.prototype['show'] = function (relatedTarget) { + var showEvent = $.Event(Modal._Event.SHOW, { relatedTarget: relatedTarget }) + + $(this._element).trigger(showEvent) + + if (this._isShown || showEvent.isDefaultPrevented()) { + return } - Modal.prototype.enforceFocus = function () { - $(document) - .off('focusin.bs.modal') // guard against infinite focus loop - .on('focusin.bs.modal', $.proxy(function (e) { - if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { - this.$element.trigger('focus') - } - }, this)) + this._isShown = true + + this._checkScrollbar() + this._setScrollbar() + + $(document.body).addClass(Modal._ClassName.OPEN) + + this._escape() + this._resize() + + $(this._element).on('click.dismiss.bs.modal', Modal._Selector.DATA_DISMISS, this['hide'].bind(this)) + + this._showBackdrop(this._showElement.bind(this, relatedTarget)) +} + + +/** + * @param {Event} event + */ +Modal.prototype['hide'] = function (event) { + if (event) { + event.preventDefault() } - Modal.prototype.escape = function () { - if (this.isShown && this.options.keyboard) { - this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { - e.which == 27 && this.hide() - }, this)) - } else if (!this.isShown) { - this.$element.off('keydown.dismiss.bs.modal') - } + var hideEvent = $.Event(Modal._Event.HIDE) + + $(this._element).trigger(hideEvent) + + if (!this._isShown || hideEvent.isDefaultPrevented()) { + return } - Modal.prototype.resize = function () { - if (this.isShown) { - $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) - } else { - $(window).off('resize.bs.modal') - } + this._isShown = false + + this._escape() + this._resize() + + $(document).off('focusin.bs.modal') + + $(this._element).removeClass(Modal._ClassName.IN) + this._element.setAttribute('aria-hidden', true) + + $(this._element).off('click.dismiss.bs.modal') + + if (Bootstrap.transition && $(this._element).hasClass(Modal._ClassName.FADE)) { + $(this._element) + .one(Bootstrap.TRANSITION_END, this._hideModal.bind(this)) + .emulateTransitionEnd(Modal._TRANSITION_DURATION) + } else { + this._hideModal() } +} - Modal.prototype.hideModal = function () { - var that = this - this.$element.hide() - this.backdrop(function () { - that.$body.removeClass('modal-open') - that.resetAdjustments() - that.resetScrollbar() - that.$element.trigger('hidden.bs.modal') - }) + +/** + * @param {Element} relatedTarget + * @private + */ +Modal.prototype._showElement = function (relatedTarget) { + var transition = Bootstrap.transition && $(this._element).hasClass(Modal._ClassName.FADE) + + if (!this._element.parentNode || this._element.parentNode.nodeType != Node.ELEMENT_NODE) { + document.body.appendChild(this._element) // don't move modals dom position } - Modal.prototype.removeBackdrop = function () { - this.$backdrop && this.$backdrop.remove() - this.$backdrop = null + this._element.style.display = 'block' + this._element.scrollTop = 0 + + if (this._config['backdrop']) { + this._adjustBackdrop() } - Modal.prototype.backdrop = function (callback) { - var that = this - var animate = this.$element.hasClass('fade') ? 'fade' : '' + if (transition) { + Bootstrap.reflow(this._element) + } - if (this.isShown && this.options.backdrop) { - var doAnimate = $.support.transition && animate + $(this._element).addClass(Modal._ClassName.IN) + this._element.setAttribute('aria-hidden', false) - this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') - .prependTo(this.$element) - .on('click.dismiss.bs.modal', $.proxy(function (e) { - if (e.target !== e.currentTarget) return - this.options.backdrop == 'static' - ? this.$element[0].focus.call(this.$element[0]) - : this.hide.call(this) - }, this)) + this._enforceFocus() - if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + var shownEvent = $.Event(Modal._Event.SHOWN, { relatedTarget: relatedTarget }) - this.$backdrop.addClass('in') + var transitionComplete = function () { + this._element.focus() + $(this._element).trigger(shownEvent) + }.bind(this) - if (!callback) return + if (transition) { + var dialog = $(this._element).find(Modal._Selector.DIALOG)[0] + $(dialog) + .one(Bootstrap.TRANSITION_END, transitionComplete) + .emulateTransitionEnd(Modal._TRANSITION_DURATION) + } else { + transitionComplete() + } +} - doAnimate ? - this.$backdrop - .one('bsTransitionEnd', callback) - .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : - callback() - } else if (!this.isShown && this.$backdrop) { - this.$backdrop.removeClass('in') - var callbackRemove = function () { - that.removeBackdrop() - callback && callback() +/** + * @private + */ +Modal.prototype._enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', function (e) { + if (this._element !== e.target && !$(this._element).has(e.target).length) { + this._element.focus() } - $.support.transition && this.$element.hasClass('fade') ? - this.$backdrop - .one('bsTransitionEnd', callbackRemove) - .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : - callbackRemove() + }.bind(this)) +} - } else if (callback) { - callback() - } - } - // these following methods are used to handle overflowing modals +/** + * @private + */ +Modal.prototype._escape = function () { + if (this._isShown && this._config['keyboard']) { + $(this._element).on('keydown.dismiss.bs.modal', function (event) { + if (event.which === 27) { + this['hide']() + } + }.bind(this)) - Modal.prototype.handleUpdate = function () { - if (this.options.backdrop) this.adjustBackdrop() - this.adjustDialog() + } else if (!this._isShown) { + $(this._element).off('keydown.dismiss.bs.modal') } +} + - Modal.prototype.adjustBackdrop = function () { - this.$backdrop - .css('height', 0) - .css('height', this.$element[0].scrollHeight) +/** + * @private + */ +Modal.prototype._resize = function () { + if (this._isShown) { + $(window).on('resize.bs.modal', this._handleUpdate.bind(this)) + } else { + $(window).off('resize.bs.modal') } +} - Modal.prototype.adjustDialog = function () { - var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight - this.$element.css({ - paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', - paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' - }) - } +/** + * @private + */ +Modal.prototype._hideModal = function () { + this._element.style.display = 'none' + this._showBackdrop(function () { + $(document.body).removeClass(Modal._ClassName.OPEN) + this._resetAdjustments() + this._resetScrollbar() + $(this._element).trigger(Modal._Event.HIDDEN) + }.bind(this)) +} - Modal.prototype.resetAdjustments = function () { - this.$element.css({ - paddingLeft: '', - paddingRight: '' - }) - } - Modal.prototype.checkScrollbar = function () { - this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight - this.scrollbarWidth = this.measureScrollbar() +/** + * @private + */ +Modal.prototype._removeBackdrop = function () { + if (this._backdrop) { + this._backdrop.parentNode.removeChild(this._backdrop) + this._backdrop = null } +} + + +/** + * @param {Function} callback + * @private + */ +Modal.prototype._showBackdrop = function (callback) { + var animate = $(this._element).hasClass(Modal._ClassName.FADE) ? Modal._ClassName.FADE : '' + + if (this._isShown && this._config['backdrop']) { + var doAnimate = Bootstrap.transition && animate - Modal.prototype.setScrollbar = function () { - var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) - if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + this._backdrop = document.createElement('div') + this._backdrop.className = Modal._ClassName.BACKDROP + + if (animate) { + $(this._backdrop).addClass(animate) + } + + $(this._element).prepend(this._backdrop) + + $(this._backdrop).on('click.dismiss.bs.modal', function (event) { + if (event.target !== event.currentTarget) return + this._config['backdrop'] === 'static' + ? this._element.focus() + : this['hide']() + }.bind(this)) + + if (doAnimate) { + Bootstrap.reflow(this._backdrop) + } + + $(this._backdrop).addClass(Modal._ClassName.IN) + + if (!callback) { + return + } + + if (!doAnimate) { + callback() + return + } + + $(this._backdrop) + .one(Bootstrap.TRANSITION_END, callback) + .emulateTransitionEnd(Modal._BACKDROP_TRANSITION_DURATION) + + } else if (!this._isShown && this._backdrop) { + $(this._backdrop).removeClass(Modal._ClassName.IN) + + var callbackRemove = function () { + this._removeBackdrop() + if (callback) { + callback() + } + }.bind(this) + + if (Bootstrap.transition && $(this._element).hasClass(Modal._ClassName.FADE)) { + $(this._backdrop) + .one(Bootstrap.TRANSITION_END, callbackRemove) + .emulateTransitionEnd(Modal._BACKDROP_TRANSITION_DURATION) + } else { + callbackRemove() + } + + } else if (callback) { + callback() } +} + + +/** + * ------------------------------------------------------------------------ + * the following methods are used to handle overflowing modals + * todo (fat): these should probably be refactored into a + * ------------------------------------------------------------------------ + */ + + +/** + * @private + */ +Modal.prototype._handleUpdate = function () { + if (this._config['backdrop']) this._adjustBackdrop() + this._adjustDialog() +} + +/** + * @private + */ +Modal.prototype._adjustBackdrop = function () { + this._backdrop.style.height = 0 // todo (fat): no clue why we do this + this._backdrop.style.height = this._element.scrollHeight + 'px' +} + + +/** + * @private + */ +Modal.prototype._adjustDialog = function () { + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight - Modal.prototype.resetScrollbar = function () { - this.$body.css('padding-right', '') + if (!this._isBodyOverflowing && isModalOverflowing) { + this._element.style.paddingLeft = this._scrollbarWidth + 'px' } - Modal.prototype.measureScrollbar = function () { // thx walsh - var scrollDiv = document.createElement('div') - scrollDiv.className = 'modal-scrollbar-measure' - this.$body.append(scrollDiv) - var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth - this.$body[0].removeChild(scrollDiv) - return scrollbarWidth + if (this._isBodyOverflowing && !isModalOverflowing) { + this._element.style.paddingRight = this._scrollbarWidth + 'px' } +} - // MODAL PLUGIN DEFINITION - // ======================= +/** + * @private + */ +Modal.prototype._resetAdjustments = function () { + this._element.style.paddingLeft = '' + this._element.style.paddingRight = '' +} - function Plugin(option, _relatedTarget) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.modal') - var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) - if (!data) $this.data('bs.modal', (data = new Modal(this, options))) - if (typeof option == 'string') data[option](_relatedTarget) - else if (options.show) data.show(_relatedTarget) - }) +/** + * @private + */ +Modal.prototype._checkScrollbar = function () { + this._isBodyOverflowing = document.body.scrollHeight > document.documentElement.clientHeight + this._scrollbarWidth = this._getScrollbarWidth() +} + + +/** + * @private + */ +Modal.prototype._setScrollbar = function () { + var bodyPadding = parseInt(($(document.body).css('padding-right') || 0), 10) + + if (this._isBodyOverflowing) { + document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px' } +} - var old = $.fn.modal - $.fn.modal = Plugin - $.fn.modal.Constructor = Modal +/** + * @private + */ +Modal.prototype._resetScrollbar = function () { + document.body.style.paddingRight = '' +} - // MODAL NO CONFLICT - // ================= +/** + * @private + */ +Modal.prototype._getScrollbarWidth = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = Modal._Selector.SCROLLBAR_MEASURER + document.body.appendChild(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + document.body.removeChild(scrollDiv) + return scrollbarWidth +} - $.fn.modal.noConflict = function () { - $.fn.modal = old - return this - } +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ + +/** + * @const + * @type {Function} + */ +$.fn[Modal._NAME] = Modal._jQueryInterface - // MODAL DATA-API - // ============== - $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { - var $this = $(this) - var href = $this.attr('href') - var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 - var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) +/** + * @const + * @type {Function} + */ +$.fn[Modal._NAME]['Constructor'] = Modal - if ($this.is('a')) e.preventDefault() - $target.one('show.bs.modal', function (showEvent) { - if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown - $target.one('hidden.bs.modal', function () { - $this.is(':visible') && $this.trigger('focus') - }) - }) - Plugin.call($target, option, this) - }) +/** + * @const + * @type {Function} + */ +$.fn[Modal._NAME]['noConflict'] = function () { + $.fn[Modal._NAME] = Modal._JQUERY_NO_CONFLICT + return this +} -}(jQuery); -/* ======================================================================== - * Bootstrap: tooltip.js v3.3.2 - * http://getbootstrap.com/javascript/#tooltip - * Inspired by the original jQuery.tipsy by Jason Frame +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + +$(document).on('click.bs.modal.data-api', Modal._Selector.DATA_TOGGLE, function (event) { + var selector = Bootstrap.getSelectorFromElement(this) + + if (selector) { + var target = $(selector)[0] + } + + var config = $(target).data(Modal._DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data()) + + if (this.tagName == 'A') { + event.preventDefault() + } + + var $target = $(target).one(Modal._Event.SHOW, function (showEvent) { + if (showEvent.isDefaultPrevented()) { + return // only register focus restorer if modal will actually get shown + } + + $target.one(Modal._Event.HIDDEN, function () { + if ($(this).is(':visible')) { + this.focus() + } + }.bind(this)) + }.bind(this)) + + Modal._jQueryInterface.call($(target), config, this) +}) + +/** ======================================================================= + * Bootstrap: scrollspy.js v4.0.0 + * http://getbootstrap.com/javascript/#scrollspy * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's scrollspy plugin. + * + * Public Methods & Properties: + * + * + $.scrollspy + * + $.scrollspy.noConflict + * + $.scrollspy.Constructor + * + $.scrollspy.Constructor.VERSION + * + $.scrollspy.Constructor.Defaults + * + $.scrollspy.Constructor.Defaults.offset + * + $.scrollspy.Constructor.prototype.refresh + * + * ======================================================================== + */ +'use strict'; -+function ($) { - 'use strict'; - // TOOLTIP PUBLIC CLASS DEFINITION - // =============================== +/** + * Our scrollspy class. + * @param {Element!} element + * @param {Object=} opt_config + * @constructor + */ +function ScrollSpy(element, opt_config) { + + /** @private {Element|Window} */ + this._scrollElement = element.tagName == 'BODY' ? window : element - var Tooltip = function (element, options) { - this.type = - this.options = - this.enabled = - this.timeout = - this.hoverState = - this.$element = null + /** @private {Object} */ + this._config = $.extend({}, ScrollSpy['Defaults'], opt_config) - this.init('tooltip', element, options) - } + /** @private {string} */ + this._selector = (this._config.target || '') + ' .nav li > a' + + /** @private {Array} */ + this._offsets = [] + + /** @private {Array} */ + this._targets = [] + + /** @private {Element} */ + this._activeTarget = null + + /** @private {number} */ + this._scrollHeight = 0 + + $(this._scrollElement).on('scroll.bs.scrollspy', this._process.bind(this)) + + this['refresh']() + + this._process() +} + + +/** + * @const + * @type {string} + */ +ScrollSpy['VERSION'] = '4.0.0' + + +/** + * @const + * @type {Object} + */ +ScrollSpy['Defaults'] = { + 'offset': 10 +} + + +/** + * @const + * @type {string} + * @private + */ +ScrollSpy._NAME = 'scrollspy' + + +/** + * @const + * @type {string} + * @private + */ +ScrollSpy._DATA_KEY = 'bs.scrollspy' + + +/** + * @const + * @type {Function} + * @private + */ +ScrollSpy._JQUERY_NO_CONFLICT = $.fn[ScrollSpy._NAME] + + +/** + * @const + * @enum {string} + * @private + */ +ScrollSpy._Event = { + ACTIVATE: 'activate.bs.scrollspy' +} + + +/** + * @const + * @enum {string} + * @private + */ +ScrollSpy._ClassName = { + DROPDOWN_MENU : 'dropdown-menu', + ACTIVE : 'active' +} - Tooltip.VERSION = '3.3.2' - Tooltip.TRANSITION_DURATION = 150 +/** + * @const + * @enum {string} + * @private + */ +ScrollSpy._Selector = { + DATA_SPY : '[data-spy="scroll"]', + ACTIVE : '.active', + LI_DROPDOWN : 'li.dropdown', + LI : 'li' +} - Tooltip.DEFAULTS = { - animation: true, - placement: 'top', - selector: false, - template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', - trigger: 'hover focus', - title: '', - delay: 0, - html: false, - container: false, - viewport: { - selector: 'body', - padding: 0 + +/** + * @param {Object=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +ScrollSpy._jQueryInterface = function (opt_config) { + return this.each(function () { + var data = $(this).data(ScrollSpy._DATA_KEY) + var config = typeof opt_config === 'object' && opt_config || null + + if (!data) { + data = new ScrollSpy(this, config) + $(this).data(ScrollSpy._DATA_KEY, data) } + + if (typeof opt_config === 'string') { + data[opt_config]() + } + }) +} + + +/** + * Refresh the scrollspy target cache + */ +ScrollSpy.prototype['refresh'] = function () { + var offsetMethod = 'offset' + var offsetBase = 0 + + if (this._scrollElement !== this._scrollElement.window) { + offsetMethod = 'position' + offsetBase = this._getScrollTop() } - Tooltip.prototype.init = function (type, element, options) { - this.enabled = true - this.type = type - this.$element = $(element) - this.options = this.getOptions(options) - this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) + this._offsets = [] + this._targets = [] - var triggers = this.options.trigger.split(' ') + this._scrollHeight = this._getScrollHeight() - for (var i = triggers.length; i--;) { - var trigger = triggers[i] + var targets = /** @type {Array.<Element>} */ ($.makeArray($(this._selector))) - if (trigger == 'click') { - this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) - } else if (trigger != 'manual') { - var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' - var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + targets + .map(function (element, index) { + var target + var targetSelector = Bootstrap.getSelectorFromElement(element) - this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) - this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + if (targetSelector) { + target = $(targetSelector)[0] } - } - this.options.selector ? - (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : - this.fixTitle() + if (target && (target.offsetWidth || target.offsetHeight)) { + // todo (fat): remove sketch reliance on jQuery position/offset + return [$(target)[offsetMethod]().top + offsetBase, targetSelector] + } + }) + .filter(function (item) { return item }) + .sort(function (a, b) { return a[0] - b[0] }) + .forEach(function (item, index) { + this._offsets.push(item[0]) + this._targets.push(item[1]) + }.bind(this)) +} + + +/** + * @private + */ +ScrollSpy.prototype._getScrollTop = function () { + return this._scrollElement === window ? + this._scrollElement.scrollY : this._scrollElement.scrollTop +} + + +/** + * @private + */ +ScrollSpy.prototype._getScrollHeight = function () { + return this._scrollElement.scrollHeight + || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) +} + + +/** + * @private + */ +ScrollSpy.prototype._process = function () { + var scrollTop = this._getScrollTop() + this._config.offset + var scrollHeight = this._getScrollHeight() + var maxScroll = this._config.offset + scrollHeight - this._scrollElement.offsetHeight + + if (this._scrollHeight != scrollHeight) { + this['refresh']() } - Tooltip.prototype.getDefaults = function () { - return Tooltip.DEFAULTS + if (scrollTop >= maxScroll) { + var target = this._targets[this._targets.length - 1] + + if (this._activeTarget != target) { + this._activate(target) + } } - Tooltip.prototype.getOptions = function (options) { - options = $.extend({}, this.getDefaults(), this.$element.data(), options) + if (this._activeTarget && scrollTop < this._offsets[0]) { + this._activeTarget = null + this._clear() + return + } - if (options.delay && typeof options.delay == 'number') { - options.delay = { - show: options.delay, - hide: options.delay - } + for (var i = this._offsets.length; i--;) { + var isActiveTarget = this._activeTarget != this._targets[i] + && scrollTop >= this._offsets[i] + && (!this._offsets[i + 1] || scrollTop < this._offsets[i + 1]) + + if (isActiveTarget) { + this._activate(this._targets[i]) } + } +} + + +/** + * @param {Element} target + * @private + */ +ScrollSpy.prototype._activate = function (target) { + this._activeTarget = target + + this._clear() + + var selector = this._selector + + '[data-target="' + target + '"],' + + this._selector + '[href="' + target + '"]' + + // todo (fat): this seems horribly wrong… getting all raw li elements up the tree ,_, + var parentListItems = $(selector).parents(ScrollSpy._Selector.LI) - return options + for (var i = parentListItems.length; i--;) { + $(parentListItems[i]).addClass(ScrollSpy._ClassName.ACTIVE) + + var itemParent = parentListItems[i].parentNode + + if (itemParent && $(itemParent).hasClass(ScrollSpy._ClassName.DROPDOWN_MENU)) { + var closestDropdown = $(itemParent).closest(ScrollSpy._Selector.LI_DROPDOWN)[0] + $(closestDropdown).addClass(ScrollSpy._ClassName.ACTIVE) + } } - Tooltip.prototype.getDelegateOptions = function () { - var options = {} - var defaults = this.getDefaults() + $(this._scrollElement).trigger(ScrollSpy._Event.ACTIVATE, { + relatedTarget: target + }) +} - this._options && $.each(this._options, function (key, value) { - if (defaults[key] != value) options[key] = value - }) - return options +/** + * @private + */ +ScrollSpy.prototype._clear = function () { + var activeParents = $(this._selector).parentsUntil(this._config.target, ScrollSpy._Selector.ACTIVE) + + for (var i = activeParents.length; i--;) { + $(activeParents[i]).removeClass(ScrollSpy._ClassName.ACTIVE) } +} - Tooltip.prototype.enter = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - if (self && self.$tip && self.$tip.is(':visible')) { - self.hoverState = 'in' - return - } +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } +/** + * @const + * @type {Function} + */ +$.fn[ScrollSpy._NAME] = ScrollSpy._jQueryInterface - clearTimeout(self.timeout) - self.hoverState = 'in' +/** + * @const + * @type {Function} + */ +$.fn[ScrollSpy._NAME]['Constructor'] = ScrollSpy + + +/** + * @const + * @type {Function} + */ +$.fn[ScrollSpy._NAME]['noConflict'] = function () { + $.fn[ScrollSpy._NAME] = ScrollSpy._JQUERY_NO_CONFLICT + return this +} - if (!self.options.delay || !self.options.delay.show) return self.show() - self.timeout = setTimeout(function () { - if (self.hoverState == 'in') self.show() - }, self.options.delay.show) +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + +$(window).on('load.bs.scrollspy.data-api', function () { + var scrollSpys = /** @type {Array.<Element>} */ ($.makeArray($(ScrollSpy._Selector.DATA_SPY))) + + for (var i = scrollSpys.length; i--;) { + var $spy = $(scrollSpys[i]) + ScrollSpy._jQueryInterface.call($spy, /** @type {Object|null} */ ($spy.data())) } +}) - Tooltip.prototype.leave = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) +/** ======================================================================= + * Bootstrap: tooltip.js v4.0.0 + * http://getbootstrap.com/javascript/#tooltip + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== + * @fileoverview - Bootstrap's tooltip plugin. + * (Inspired by jQuery.tipsy by Jason Frame) + * + * Public Methods & Properties: + * + * + $.tooltip + * + $.tooltip.noConflict + * + $.tooltip.Constructor + * + $.tooltip.Constructor.VERSION + * + $.tooltip.Constructor.Defaults + * + $.tooltip.Constructor.Defaults.container + * + $.tooltip.Constructor.Defaults.animation + * + $.tooltip.Constructor.Defaults.placement + * + $.tooltip.Constructor.Defaults.selector + * + $.tooltip.Constructor.Defaults.template + * + $.tooltip.Constructor.Defaults.trigger + * + $.tooltip.Constructor.Defaults.title + * + $.tooltip.Constructor.Defaults.delay + * + $.tooltip.Constructor.Defaults.html + * + $.tooltip.Constructor.Defaults.viewport + * + $.tooltip.Constructor.Defaults.viewport.selector + * + $.tooltip.Constructor.Defaults.viewport.padding + * + $.tooltip.Constructor.prototype.enable + * + $.tooltip.Constructor.prototype.disable + * + $.tooltip.Constructor.prototype.destroy + * + $.tooltip.Constructor.prototype.toggleEnabled + * + $.tooltip.Constructor.prototype.toggle + * + $.tooltip.Constructor.prototype.show + * + $.tooltip.Constructor.prototype.hide + * + * ======================================================================== + */ - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } +'use strict'; + + +/** + * Our tooltip class. + * @param {Element!} element + * @param {Object=} opt_config + * @constructor + */ +var Tooltip = function (element, opt_config) { + + /** @private {boolean} */ + this._isEnabled = true + + /** @private {number} */ + this._timeout = 0 + + /** @private {string} */ + this._hoverState = '' + + /** @protected {Element} */ + this.element = element - clearTimeout(self.timeout) + /** @protected {Object} */ + this.config = this._getConfig(opt_config) - self.hoverState = 'out' + /** @protected {Element} */ + this.tip = null - if (!self.options.delay || !self.options.delay.hide) return self.hide() + /** @protected {Element} */ + this.arrow = null + + if (this.config['viewport']) { + + /** @private {Element} */ + this._viewport = $(this.config['viewport']['selector'] || this.config['viewport'])[0] - self.timeout = setTimeout(function () { - if (self.hoverState == 'out') self.hide() - }, self.options.delay.hide) } - Tooltip.prototype.show = function () { - var e = $.Event('show.bs.' + this.type) + this._setListeners() +} - if (this.hasContent() && this.enabled) { - this.$element.trigger(e) - var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) - if (e.isDefaultPrevented() || !inDom) return - var that = this +/** + * @const + * @type {string} + */ +Tooltip['VERSION'] = '4.0.0' - var $tip = this.tip() - var tipId = this.getUID(this.type) +/** + * @const + * @type {Object} + */ +Tooltip['Defaults'] = { + 'container' : false, + 'animation' : true, + 'placement' : 'top', + 'selector' : false, + 'template' : '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', + 'trigger' : 'hover focus', + 'title' : '', + 'delay' : 0, + 'html' : false, + 'viewport': { + 'selector': 'body', + 'padding' : 0 + } +} - this.setContent() - $tip.attr('id', tipId) - this.$element.attr('aria-describedby', tipId) - if (this.options.animation) $tip.addClass('fade') +/** + * @const + * @enum {string} + * @protected + */ +Tooltip.Direction = { + TOP: 'top', + LEFT: 'left', + RIGHT: 'right', + BOTTOM: 'bottom' +} - var placement = typeof this.options.placement == 'function' ? - this.options.placement.call(this, $tip[0], this.$element[0]) : - this.options.placement - var autoToken = /\s?auto?\s?/i - var autoPlace = autoToken.test(placement) - if (autoPlace) placement = placement.replace(autoToken, '') || 'top' +/** + * @const + * @type {string} + * @private + */ +Tooltip._NAME = 'tooltip' - $tip - .detach() - .css({ top: 0, left: 0, display: 'block' }) - .addClass(this.type + '-' + placement) - .data('bs.' + this.type, this) - this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) +/** + * @const + * @type {string} + * @private + */ +Tooltip._DATA_KEY = 'bs.tooltip' - var pos = this.getPosition() - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - if (autoPlace) { - var origPlacement = placement - var $container = this.options.container ? $(this.options.container) : this.$element.parent() - var containerDim = this.getPosition($container) +/** + * @const + * @type {number} + * @private + */ +Tooltip._TRANSITION_DURATION = 150 - placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' : - placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' : - placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' : - placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' : - placement - $tip - .removeClass(this.type + '-' + origPlacement) - .addClass(this.type + '-' + placement) - } +/** + * @const + * @enum {string} + * @private + */ +Tooltip._HoverState = { + IN: 'in', + OUT: 'out' +} - var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) - this.applyPlacement(calculatedOffset, placement) +/** + * @const + * @enum {string} + * @private + */ +Tooltip._Event = { + HIDE : 'hide.bs.tooltip', + HIDDEN : 'hidden.bs.tooltip', + SHOW : 'show.bs.tooltip', + SHOWN : 'shown.bs.tooltip' +} - var complete = function () { - var prevHoverState = that.hoverState - that.$element.trigger('shown.bs.' + that.type) - that.hoverState = null - if (prevHoverState == 'out') that.leave(that) - } +/** + * @const + * @enum {string} + * @private + */ +Tooltip._ClassName = { + FADE : 'fade', + IN : 'in' +} - $.support.transition && this.$tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - } - } - Tooltip.prototype.applyPlacement = function (offset, placement) { - var $tip = this.tip() - var width = $tip[0].offsetWidth - var height = $tip[0].offsetHeight +/** + * @const + * @enum {string} + * @private + */ +Tooltip._Selector = { + TOOLTIP : '.tooltip', + TOOLTIP_INNER : '.tooltip-inner', + TOOLTIP_ARROW : '.tooltip-arrow' +} - // manually read margins because getBoundingClientRect includes difference - var marginTop = parseInt($tip.css('margin-top'), 10) - var marginLeft = parseInt($tip.css('margin-left'), 10) - // we must check for NaN for IE9 - if (isNaN(marginTop)) marginTop = 0 - if (isNaN(marginLeft)) marginLeft = 0 +/** + * @const + * @type {Function} + * @private + */ +Tooltip._JQUERY_NO_CONFLICT = $.fn[Tooltip._NAME] - offset.top = offset.top + marginTop - offset.left = offset.left + marginLeft - // $.fn.offset doesn't round pixel values - // so we use setOffset directly with our own function B-0 - $.offset.setOffset($tip[0], $.extend({ - using: function (props) { - $tip.css({ - top: Math.round(props.top), - left: Math.round(props.left) - }) - } - }, offset), 0) +/** + * @param {Object=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Tooltip._jQueryInterface = function (opt_config) { + return this.each(function () { + var data = $(this).data(Tooltip._DATA_KEY) + var config = typeof opt_config == 'object' ? opt_config : null - $tip.addClass('in') + if (!data && opt_config == 'destroy') { + return + } - // check to see if placing tip in new offset caused the tip to resize itself - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight + if (!data) { + data = new Tooltip(this, config) + $(this).data(Tooltip._DATA_KEY, data) + } - if (placement == 'top' && actualHeight != height) { - offset.top = offset.top + height - actualHeight + if (typeof opt_config === 'string') { + data[opt_config]() } + }) +} - var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) - if (delta.left) offset.left += delta.left - else offset.top += delta.top +/** + * Enable tooltip + */ +Tooltip.prototype['enable'] = function () { + this._isEnabled = true +} - var isVertical = /top|bottom/.test(placement) - var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight - var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' - $tip.offset(offset) - this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) - } +/** + * Disable tooltip + */ +Tooltip.prototype['disable'] = function () { + this._isEnabled = false +} - Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) { - this.arrow() - .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') - .css(isHorizontal ? 'top' : 'left', '') - } - Tooltip.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() +/** + * Toggle the tooltip enable state + */ +Tooltip.prototype['toggleEnabled'] = function () { + this._isEnabled = !this._isEnabled +} - $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) - $tip.removeClass('fade in tooltip-top tooltip-bottom tooltip-left tooltip-right') - } +/** + * Toggle the tooltips display + * @param {Event} opt_event + */ +Tooltip.prototype['toggle'] = function (opt_event) { + var context = this + var dataKey = this.getDataKey() - Tooltip.prototype.hide = function (callback) { - var that = this - var $tip = this.tip() - var e = $.Event('hide.bs.' + this.type) + if (opt_event) { + context = $(opt_event.currentTarget).data(dataKey) - function complete() { - if (that.hoverState != 'in') $tip.detach() - that.$element - .removeAttr('aria-describedby') - .trigger('hidden.bs.' + that.type) - callback && callback() + if (!context) { + context = new this.constructor(opt_event.currentTarget, this._getDelegateConfig()) + $(opt_event.currentTarget).data(dataKey, context) } + } - this.$element.trigger(e) + $(context.getTipElement()).hasClass(Tooltip._ClassName.IN) ? + context._leave(null, context) : + context._enter(null, context) +} - if (e.isDefaultPrevented()) return - $tip.removeClass('in') +/** + * Remove tooltip functionality + */ +Tooltip.prototype['destroy'] = function () { + clearTimeout(this._timeout) + this['hide'](function () { + $(this.element) + .off(Tooltip._Selector.TOOLTIP) + .removeData(this.getDataKey()) + }.bind(this)) +} - $.support.transition && this.$tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - this.hoverState = null +/** + * Show the tooltip + * todo (fat): ~fuck~ this is a big function - refactor out all of positioning logic + * and replace with external lib + */ +Tooltip.prototype['show'] = function () { + var showEvent = $.Event(this.getEventObject().SHOW) - return this - } + if (this.isWithContent() && this._isEnabled) { + $(this.element).trigger(showEvent) - Tooltip.prototype.fixTitle = function () { - var $e = this.$element - if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') { - $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element) + + if (showEvent.isDefaultPrevented() || !isInTheDom) { + return } - } - Tooltip.prototype.hasContent = function () { - return this.getTitle() - } + var tip = this.getTipElement() + var tipId = Bootstrap.getUID(this.getName()) - Tooltip.prototype.getPosition = function ($element) { - $element = $element || this.$element + tip.setAttribute('id', tipId) + this.element.setAttribute('aria-describedby', tipId) - var el = $element[0] - var isBody = el.tagName == 'BODY' + this.setContent() - var elRect = el.getBoundingClientRect() - if (elRect.width == null) { - // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 - elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + if (this.config['animation']) { + $(tip).addClass(Tooltip._ClassName.FADE) } - var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() - var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } - var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null - return $.extend({}, elRect, scroll, outerDims, elOffset) - } + var placement = typeof this.config['placement'] == 'function' ? + this.config['placement'].call(this, tip, this.element) : + this.config['placement'] - Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { - return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : - /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + var autoToken = /\s?auto?\s?/i + var isWithAutoPlacement = autoToken.test(placement) - } + if (isWithAutoPlacement) { + placement = placement.replace(autoToken, '') || Tooltip.Direction.TOP + } - Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { - var delta = { top: 0, left: 0 } - if (!this.$viewport) return delta + if (tip.parentNode && tip.parentNode.nodeType == Node.ELEMENT_NODE) { + tip.parentNode.removeChild(tip) + } - var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 - var viewportDimensions = this.getPosition(this.$viewport) + tip.style.top = 0 + tip.style.left = 0 + tip.style.display = 'block' - if (/right|left/.test(placement)) { - var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll - var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight - if (topEdgeOffset < viewportDimensions.top) { // top overflow - delta.top = viewportDimensions.top - topEdgeOffset - } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow - delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset - } + $(tip).addClass(Tooltip._NAME + '-' + placement) + + $(tip).data(this.getDataKey(), this) + + if (this.config['container']) { + $(this.config['container'])[0].appendChild(tip) } else { - var leftEdgeOffset = pos.left - viewportPadding - var rightEdgeOffset = pos.left + viewportPadding + actualWidth - if (leftEdgeOffset < viewportDimensions.left) { // left overflow - delta.left = viewportDimensions.left - leftEdgeOffset - } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow - delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset - } + this.element.parentNode.insertBefore(tip, this.element.nextSibling) } - return delta - } + var position = this._getPosition() + var actualWidth = tip.offsetWidth + var actualHeight = tip.offsetHeight - Tooltip.prototype.getTitle = function () { - var title - var $e = this.$element - var o = this.options + var calculatedPlacement = this._getCalculatedAutoPlacement(isWithAutoPlacement, placement, position, actualWidth, actualHeight) + var calculatedOffset = this._getCalculatedOffset(calculatedPlacement, position, actualWidth, actualHeight) - title = $e.attr('data-original-title') - || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + this._applyCalculatedPlacement(calculatedOffset, calculatedPlacement) - return title - } + var complete = function () { + var prevHoverState = this.hoverState + $(this.element).trigger(this.getEventObject().SHOWN) + this.hoverState = null - Tooltip.prototype.getUID = function (prefix) { - do prefix += ~~(Math.random() * 1000000) - while (document.getElementById(prefix)) - return prefix - } + if (prevHoverState == 'out') this._leave(null, this) + }.bind(this) - Tooltip.prototype.tip = function () { - return (this.$tip = this.$tip || $(this.options.template)) + Bootstrap.transition && $(this._tip).hasClass(Tooltip._ClassName.FADE) ? + $(this._tip) + .one(Bootstrap.TRANSITION_END, complete) + .emulateTransitionEnd(Tooltip._TRANSITION_DURATION) : + complete() } +} - Tooltip.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) - } - Tooltip.prototype.enable = function () { - this.enabled = true - } +/** + * Hide the tooltip breh + */ +Tooltip.prototype['hide'] = function (callback) { + var tip = this.getTipElement() + var hideEvent = $.Event(this.getEventObject().HIDE) - Tooltip.prototype.disable = function () { - this.enabled = false - } + var complete = function () { + if (this._hoverState != Tooltip._HoverState.IN) { + tip.parentNode.removeChild(tip) + } - Tooltip.prototype.toggleEnabled = function () { - this.enabled = !this.enabled - } + this.element.removeAttribute('aria-describedby') + $(this.element).trigger(this.getEventObject().HIDDEN) - Tooltip.prototype.toggle = function (e) { - var self = this - if (e) { - self = $(e.currentTarget).data('bs.' + this.type) - if (!self) { - self = new this.constructor(e.currentTarget, this.getDelegateOptions()) - $(e.currentTarget).data('bs.' + this.type, self) - } + if (callback) { + callback() } + }.bind(this) - self.tip().hasClass('in') ? self.leave(self) : self.enter(self) - } + $(this.element).trigger(hideEvent) - Tooltip.prototype.destroy = function () { - var that = this - clearTimeout(this.timeout) - this.hide(function () { - that.$element.off('.' + that.type).removeData('bs.' + that.type) - }) + if (hideEvent.isDefaultPrevented()) return + + $(tip).removeClass(Tooltip._ClassName.IN) + + if (Bootstrap.transition && $(this._tip).hasClass(Tooltip._ClassName.FADE)) { + $(tip) + .one(Bootstrap.TRANSITION_END, complete) + .emulateTransitionEnd(Tooltip._TRANSITION_DURATION) + } else { + complete() } + this._hoverState = '' +} - // TOOLTIP PLUGIN DEFINITION - // ========================= - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tooltip') - var options = typeof option == 'object' && option +/** + * @return {string} + */ +Tooltip.prototype['getHoverState'] = function (callback) { + return this._hoverState +} - if (!data && option == 'destroy') return - if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) - if (typeof option == 'string') data[option]() - }) - } - var old = $.fn.tooltip +/** + * @return {string} + * @protected + */ +Tooltip.prototype.getName = function () { + return Tooltip._NAME +} - $.fn.tooltip = Plugin - $.fn.tooltip.Constructor = Tooltip +/** + * @return {string} + * @protected + */ +Tooltip.prototype.getDataKey = function () { + return Tooltip._DATA_KEY +} - // TOOLTIP NO CONFLICT - // =================== - $.fn.tooltip.noConflict = function () { - $.fn.tooltip = old - return this - } +/** + * @return {Object} + * @protected + */ +Tooltip.prototype.getEventObject = function () { + return Tooltip._Event +} -}(jQuery); -/* ======================================================================== - * Bootstrap: popover.js v3.3.2 - * http://getbootstrap.com/javascript/#popovers - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ +/** + * @return {string} + * @protected + */ +Tooltip.prototype.getTitle = function () { + var title = this.element.getAttribute('data-original-title') + if (!title) { + title = typeof this.config['title'] === 'function' ? + this.config['title'].call(this.element) : + this.config['title'] + } -+function ($) { - 'use strict'; + return /** @type {string} */ (title) +} - // POPOVER PUBLIC CLASS DEFINITION - // =============================== - var Popover = function (element, options) { - this.init('popover', element, options) - } +/** + * @return {Element} + * @protected + */ +Tooltip.prototype.getTipElement = function () { + return (this._tip = this._tip || $(this.config['template'])[0]) +} - if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') - Popover.VERSION = '3.3.2' +/** + * @return {Element} + * @protected + */ +Tooltip.prototype.getArrowElement = function () { + return (this.arrow = this.arrow || $(this.getTipElement()).find(Tooltip._Selector.TOOLTIP_ARROW)[0]) +} - Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { - placement: 'right', - trigger: 'click', - content: '', - template: '<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' - }) + +/** + * @return {boolean} + * @protected + */ +Tooltip.prototype.isWithContent = function () { + return !!this.getTitle() +} - // NOTE: POPOVER EXTENDS tooltip.js - // ================================ +/** + * @protected + */ +Tooltip.prototype.setContent = function () { + var tip = this.getTipElement() + var title = this.getTitle() - Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + $(tip).find(Tooltip._Selector.TOOLTIP_INNER)[0][this.config['html'] ? 'innerHTML' : 'innerText'] = title - Popover.prototype.constructor = Popover + $(tip) + .removeClass(Tooltip._ClassName.FADE) + .removeClass(Tooltip._ClassName.IN) - Popover.prototype.getDefaults = function () { - return Popover.DEFAULTS + for (var direction in Tooltip.Direction) { + $(tip).removeClass(Tooltip._NAME + '-' + direction) } +} - Popover.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - var content = this.getContent() - $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) - $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events - this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' - ](content) +/** + * @private + */ +Tooltip.prototype._setListeners = function () { + var triggers = this.config['trigger'].split(' ') - $tip.removeClass('fade popover-top popover-bottom popover-left popover-right in') + triggers.forEach(function (trigger) { + if (trigger == 'click') { + $(this.element).on('click.bs.tooltip', this.config['selector'], this['toggle'].bind(this)) - // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do - // this manually by checking the contents. - if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() - } + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' - Popover.prototype.hasContent = function () { - return this.getTitle() || this.getContent() + $(this.element) + .on(eventIn + '.bs.tooltip', this.config['selector'], this._enter.bind(this)) + .on(eventOut + '.bs.tooltip', this.config['selector'], this._leave.bind(this)) + } + }.bind(this)) + + if (this.config['selector']) { + this.config = $.extend({}, this.config, { 'trigger': 'manual', 'selector': '' }) + } else { + this._fixTitle() } +} - Popover.prototype.getContent = function () { - var $e = this.$element - var o = this.options - return $e.attr('data-content') - || (typeof o.content == 'function' ? - o.content.call($e[0]) : - o.content) - } +/** + * @param {Object=} opt_config + * @return {Object} + * @private + */ +Tooltip.prototype._getConfig = function (opt_config) { + var config = $.extend({}, this.constructor['Defaults'], $(this.element).data(), opt_config) - Popover.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.popover-arrow')) + if (config['delay'] && typeof config['delay'] == 'number') { + config['delay'] = { + 'show': config['delay'], + 'hide': config['delay'] + } } - Popover.prototype.tip = function () { - if (!this.$tip) this.$tip = $(this.options.template) - return this.$tip + return config +} + + +/** + * @return {Object} + * @private + */ +Tooltip.prototype._getDelegateConfig = function () { + var config = {} + var defaults = this.constructor['Defaults'] + + if (this.config) { + for (var key in this.config) { + var value = this.config[key] + if (defaults[key] != value) config[key] = value + } } + return config +} - // POPOVER PLUGIN DEFINITION - // ========================= - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.popover') - var options = typeof option == 'object' && option - if (!data && option == 'destroy') return - if (!data) $this.data('bs.popover', (data = new Popover(this, options))) - if (typeof option == 'string') data[option]() - }) +/** + * @param {boolean} isWithAutoPlacement + * @param {string} placement + * @param {Object} position + * @param {number} actualWidth + * @param {number} actualHeight + * @return {string} + * @private + */ +Tooltip.prototype._getCalculatedAutoPlacement = function (isWithAutoPlacement, placement, position, actualWidth, actualHeight) { + if (isWithAutoPlacement) { + var originalPlacement = placement + var container = this.config['container'] ? $(this.config['container'])[0] : this.element.parentNode + var containerDim = this._getPosition(/** @type {Element} */ (container)) + + placement = placement == Tooltip.Direction.BOTTOM && position.bottom + actualHeight > containerDim.bottom ? Tooltip.Direction.TOP : + placement == Tooltip.Direction.TOP && position.top - actualHeight < containerDim.top ? Tooltip.Direction.BOTTOM : + placement == Tooltip.Direction.RIGHT && position.right + actualWidth > containerDim.width ? Tooltip.Direction.LEFT : + placement == Tooltip.Direction.LEFT && position.left - actualWidth < containerDim.left ? Tooltip.Direction.RIGHT : + placement + + $(this._tip) + .removeClass(Tooltip._NAME + '-' + originalPlacement) + .addClass(Tooltip._NAME + '-' + placement) } - var old = $.fn.popover + return placement +} - $.fn.popover = Plugin - $.fn.popover.Constructor = Popover +/** + * @param {string} placement + * @param {Object} position + * @param {number} actualWidth + * @param {number} actualHeight + * @return {{left: number, top: number}} + * @private + */ +Tooltip.prototype._getCalculatedOffset = function (placement, position, actualWidth, actualHeight) { + return placement == Tooltip.Direction.BOTTOM ? { top: position.top + position.height, left: position.left + position.width / 2 - actualWidth / 2 } : + placement == Tooltip.Direction.TOP ? { top: position.top - actualHeight, left: position.left + position.width / 2 - actualWidth / 2 } : + placement == Tooltip.Direction.LEFT ? { top: position.top + position.height / 2 - actualHeight / 2, left: position.left - actualWidth } : + /* placement == Tooltip.Direction.RIGHT */ { top: position.top + position.height / 2 - actualHeight / 2, left: position.left + position.width } +} - // POPOVER NO CONFLICT - // =================== - $.fn.popover.noConflict = function () { - $.fn.popover = old - return this +/** + * @param {string} placement + * @param {Object} position + * @param {number} actualWidth + * @param {number} actualHeight + * @return {Object} + * @private + */ +Tooltip.prototype._getViewportAdjustedDelta = function (placement, position, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + + if (!this._viewport) { + return delta } -}(jQuery); + var viewportPadding = this.config['viewport'] && this.config['viewport']['padding'] || 0 + var viewportDimensions = this._getPosition(this._viewport) -/* ======================================================================== - * Bootstrap: scrollspy.js v3.3.2 - * http://getbootstrap.com/javascript/#scrollspy - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + if (placement === Tooltip.Direction.RIGHT || placement === Tooltip.Direction.LEFT) { + var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset -+function ($) { - 'use strict'; - - // SCROLLSPY CLASS DEFINITION - // ========================== + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } - function ScrollSpy(element, options) { - var process = $.proxy(this.process, this) + } else { + var leftEdgeOffset = position.left - viewportPadding + var rightEdgeOffset = position.left + viewportPadding + actualWidth - this.$body = $('body') - this.$scrollElement = $(element).is('body') ? $(window) : $(element) - this.options = $.extend({}, ScrollSpy.DEFAULTS, options) - this.selector = (this.options.target || '') + ' .nav li > a' - this.offsets = [] - this.targets = [] - this.activeTarget = null - this.scrollHeight = 0 + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset - this.$scrollElement.on('scroll.bs.scrollspy', process) - this.refresh() - this.process() + } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } } - ScrollSpy.VERSION = '3.3.2' + return delta +} + + +/** + * @param {Element=} opt_element + * @return {Object} + * @private + */ +Tooltip.prototype._getPosition = function (opt_element) { + var element = opt_element || this.element + var isBody = element.tagName == 'BODY' + var rect = element.getBoundingClientRect() + var offset = isBody ? { top: 0, left: 0 } : $(element).offset() + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : this.element.scrollTop } + var outerDims = isBody ? { width: window.innerWidth, height: window.innerHeight } : null + + return $.extend({}, rect, scroll, outerDims, offset) +} - ScrollSpy.DEFAULTS = { - offset: 10 - } - ScrollSpy.prototype.getScrollHeight = function () { - return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) +/** + * @param {{left: number, top: number}} offset + * @param {string} placement + * @private + */ +Tooltip.prototype._applyCalculatedPlacement = function (offset, placement) { + var tip = this.getTipElement() + var width = tip.offsetWidth + var height = tip.offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt(tip.style.marginTop, 10) + var marginLeft = parseInt(tip.style.marginLeft, 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) { + marginTop = 0 + } + if (isNaN(marginLeft)) { + marginLeft = 0 } - ScrollSpy.prototype.refresh = function () { - var offsetMethod = 'offset' - var offsetBase = 0 + offset.top = offset.top + marginTop + offset.left = offset.left + marginLeft - if (!$.isWindow(this.$scrollElement[0])) { - offsetMethod = 'position' - offsetBase = this.$scrollElement.scrollTop() + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset(tip, $.extend({ + using: function (props) { + tip.style.top = Math.round(props.top) + 'px' + tip.style.left = Math.round(props.left) + 'px' } + }, offset), 0) - this.offsets = [] - this.targets = [] - this.scrollHeight = this.getScrollHeight() - - var self = this + $(tip).addClass(Tooltip._ClassName.IN) - this.$body - .find(this.selector) - .map(function () { - var $el = $(this) - var href = $el.data('target') || $el.attr('href') - var $href = /^#./.test(href) && $(href) + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = tip.offsetWidth + var actualHeight = tip.offsetHeight - return ($href - && $href.length - && $href.is(':visible') - && [[$href[offsetMethod]().top + offsetBase, href]]) || null - }) - .sort(function (a, b) { return a[0] - b[0] }) - .each(function () { - self.offsets.push(this[0]) - self.targets.push(this[1]) - }) + if (placement == Tooltip.Direction.TOP && actualHeight != height) { + offset.top = offset.top + height - actualHeight } - ScrollSpy.prototype.process = function () { - var scrollTop = this.$scrollElement.scrollTop() + this.options.offset - var scrollHeight = this.getScrollHeight() - var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() - var offsets = this.offsets - var targets = this.targets - var activeTarget = this.activeTarget - var i + var delta = this._getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) - if (this.scrollHeight != scrollHeight) { - this.refresh() - } + if (delta.left) { + offset.left += delta.left + } else { + offset.top += delta.top + } - if (scrollTop >= maxScroll) { - return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) - } + var isVertical = placement === Tooltip.Direction.TOP || placement === Tooltip.Direction.BOTTOM + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' - if (activeTarget && scrollTop < offsets[0]) { - this.activeTarget = null - return this.clear() - } + $(tip).offset(offset) - for (i = offsets.length; i--;) { - activeTarget != targets[i] - && scrollTop >= offsets[i] - && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) - && this.activate(targets[i]) - } - } + this._replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical) +} - ScrollSpy.prototype.activate = function (target) { - this.activeTarget = target - this.clear() +/** + * @param {number} delta + * @param {number} dimension + * @param {boolean} isHorizontal + * @private + */ +Tooltip.prototype._replaceArrow = function (delta, dimension, isHorizontal) { + var arrow = this.getArrowElement() - var selector = this.selector + - '[data-target="' + target + '"],' + - this.selector + '[href="' + target + '"]' + arrow.style[isHorizontal ? 'left' : 'top'] = 50 * (1 - delta / dimension) + '%' + arrow.style[isHorizontal ? 'top' : 'left'] = '' +} - var active = $(selector) - .parents('li') - .addClass('active') - if (active.parent('.dropdown-menu').length) { - active = active - .closest('li.dropdown') - .addClass('active') - } - active.trigger('activate.bs.scrollspy') +/** + * @private + */ +Tooltip.prototype._fixTitle = function () { + if (this.element.getAttribute('title') || typeof this.element.getAttribute('data-original-title') != 'string') { + this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '') + this.element.setAttribute('title', '') } +} + - ScrollSpy.prototype.clear = function () { - $(this.selector) - .parentsUntil(this.options.target, '.active') - .removeClass('active') +/** + * @param {Event=} opt_event + * @param {Object=} opt_context + * @private + */ +Tooltip.prototype._enter = function (opt_event, opt_context) { + var dataKey = this.getDataKey() + var context = opt_context || $(opt_event.currentTarget).data(dataKey) + + if (context && context._tip && context._tip.offsetWidth) { + context._hoverState = Tooltip._HoverState.IN + return } + if (!context) { + context = new this.constructor(opt_event.currentTarget, this._getDelegateConfig()) + $(opt_event.currentTarget).data(dataKey, context) + } - // SCROLLSPY PLUGIN DEFINITION - // =========================== + clearTimeout(context._timeout) - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.scrollspy') - var options = typeof option == 'object' && option + context._hoverState = Tooltip._HoverState.IN - if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) - if (typeof option == 'string') data[option]() - }) + if (!context.config['delay'] || !context.config['delay']['show']) { + context['show']() + return } - var old = $.fn.scrollspy + context._timeout = setTimeout(function () { + if (context._hoverState == Tooltip._HoverState.IN) { + context['show']() + } + }, context.config['delay']['show']) +} - $.fn.scrollspy = Plugin - $.fn.scrollspy.Constructor = ScrollSpy +/** + * @param {Event=} opt_event + * @param {Object=} opt_context + * @private + */ +Tooltip.prototype._leave = function (opt_event, opt_context) { + var dataKey = this.getDataKey() + var context = opt_context || $(opt_event.currentTarget).data(dataKey) - // SCROLLSPY NO CONFLICT - // ===================== + if (!context) { + context = new this.constructor(opt_event.currentTarget, this._getDelegateConfig()) + $(opt_event.currentTarget).data(dataKey, context) + } - $.fn.scrollspy.noConflict = function () { - $.fn.scrollspy = old - return this + clearTimeout(context._timeout) + + context._hoverState = Tooltip._HoverState.OUT + + if (!context.config['delay'] || !context.config['delay']['hide']) { + context['hide']() + return } + context._timeout = setTimeout(function () { + if (context._hoverState == Tooltip._HoverState.OUT) { + context['hide']() + } + }, context.config['delay']['hide']) +} - // SCROLLSPY DATA-API - // ================== - $(window).on('load.bs.scrollspy.data-api', function () { - $('[data-spy="scroll"]').each(function () { - var $spy = $(this) - Plugin.call($spy, $spy.data()) - }) - }) -}(jQuery); +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ -/* ======================================================================== - * Bootstrap: tab.js v3.3.2 - * http://getbootstrap.com/javascript/#tabs +/** + * @const + * @type {Function} + */ +$.fn[Tooltip._NAME] = Tooltip._jQueryInterface + + +/** + * @const + * @type {Function} + */ +$.fn[Tooltip._NAME]['Constructor'] = Tooltip + + +/** + * @const + * @type {Function} + */ +$.fn[Tooltip._NAME]['noConflict'] = function () { + $.fn[Tooltip._NAME] = Tooltip._JQUERY_NO_CONFLICT + return this +} + +/** ======================================================================= + * Bootstrap: popover.js v4.0.0 + * http://getbootstrap.com/javascript/#popovers * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's popover plugin - extends tooltip. + * + * Public Methods & Properties: + * + * + $.popover + * + $.popover.noConflict + * + $.popover.Constructor + * + $.popover.Constructor.VERSION + * + $.popover.Constructor.Defaults + * + $.popover.Constructor.Defaults.container + * + $.popover.Constructor.Defaults.animation + * + $.popover.Constructor.Defaults.placement + * + $.popover.Constructor.Defaults.selector + * + $.popover.Constructor.Defaults.template + * + $.popover.Constructor.Defaults.trigger + * + $.popover.Constructor.Defaults.title + * + $.popover.Constructor.Defaults.content + * + $.popover.Constructor.Defaults.delay + * + $.popover.Constructor.Defaults.html + * + $.popover.Constructor.Defaults.viewport + * + $.popover.Constructor.Defaults.viewport.selector + * + $.popover.Constructor.Defaults.viewport.padding + * + $.popover.Constructor.prototype.enable + * + $.popover.Constructor.prototype.disable + * + $.popover.Constructor.prototype.destroy + * + $.popover.Constructor.prototype.toggleEnabled + * + $.popover.Constructor.prototype.toggle + * + $.popover.Constructor.prototype.show + * + $.popover.Constructor.prototype.hide + * + * ======================================================================== + */ -+function ($) { - 'use strict'; +'use strict'; - // TAB CLASS DEFINITION - // ==================== - var Tab = function (element) { - this.element = $(element) - } +if (!Tooltip) throw new Error('Popover requires tooltip.js') - Tab.VERSION = '3.3.2' - Tab.TRANSITION_DURATION = 150 +/** + * Our tooltip class. + * @param {Element!} element + * @param {Object=} opt_config + * @constructor + * @extends {Tooltip} + */ +var Popover = function (element, opt_config) { + Tooltip.apply(this, arguments) +} +Bootstrap.inherits(Popover, Tooltip) - Tab.prototype.show = function () { - var $this = this.element - var $ul = $this.closest('ul:not(.dropdown-menu)') - var selector = $this.data('target') - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } +/** + * @const + * @type {string} + */ +Popover['VERSION'] = '4.0.0' - if ($this.parent('li').hasClass('active')) return - var $previous = $ul.find('.active:last a') - var hideEvent = $.Event('hide.bs.tab', { - relatedTarget: $this[0] - }) - var showEvent = $.Event('show.bs.tab', { - relatedTarget: $previous[0] - }) +/** + * @const + * @type {Object} + */ +Popover['Defaults'] = $.extend({}, $.fn['tooltip']['Constructor']['Defaults'], { + 'placement': 'right', + 'trigger': 'click', + 'content': '', + 'template': '<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' +}) + + +/** + * @const + * @type {string} + * @private + */ +Popover._NAME = 'popover' - $previous.trigger(hideEvent) - $this.trigger(showEvent) - if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return +/** + * @const + * @type {string} + * @private + */ +Popover._DATA_KEY = 'bs.popover' - var $target = $(selector) - this.activate($this.closest('li'), $ul) - this.activate($target, $target.parent(), function () { - $previous.trigger({ - type: 'hidden.bs.tab', - relatedTarget: $this[0] - }) - $this.trigger({ - type: 'shown.bs.tab', - relatedTarget: $previous[0] - }) - }) - } +/** + * @const + * @enum {string} + * @private + */ +Popover._Event = { + HIDE : 'hide.bs.popover', + HIDDEN : 'hidden.bs.popover', + SHOW : 'show.bs.popover', + SHOWN : 'shown.bs.popover' +} - Tab.prototype.activate = function (element, container, callback) { - var $active = container.find('> .active') - var transition = callback - && $.support.transition - && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length) - - function next() { - $active - .removeClass('active') - .find('> .dropdown-menu > .active') - .removeClass('active') - .end() - .find('[data-toggle="tab"]') - .attr('aria-expanded', false) - - element - .addClass('active') - .find('[data-toggle="tab"]') - .attr('aria-expanded', true) - - if (transition) { - element[0].offsetWidth // reflow for transition - element.addClass('in') - } else { - element.removeClass('fade') - } - if (element.parent('.dropdown-menu')) { - element - .closest('li.dropdown') - .addClass('active') - .end() - .find('[data-toggle="tab"]') - .attr('aria-expanded', true) - } +/** + * @const + * @enum {string} + * @private + */ +Popover._ClassName = { + FADE : 'fade', + IN : 'in' +} - callback && callback() + +/** + * @const + * @enum {string} + * @private + */ +Popover._Selector = { + TITLE : '.popover-title', + CONTENT : '.popover-content', + ARROW : '.popover-arrow' +} + + +/** + * @const + * @type {Function} + * @private + */ +Popover._JQUERY_NO_CONFLICT = $.fn[Popover._NAME] + + +/** + * @param {Object|string=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Popover._jQueryInterface = function (opt_config) { + return this.each(function () { + var data = $(this).data(Popover._DATA_KEY) + var config = typeof opt_config === 'object' ? opt_config : null + + if (!data && opt_config === 'destroy') { + return } - $active.length && transition ? - $active - .one('bsTransitionEnd', next) - .emulateTransitionEnd(Tab.TRANSITION_DURATION) : - next() + if (!data) { + data = new Popover(this, config) + $(this).data(Popover._DATA_KEY, data) + } - $active.removeClass('in') - } + if (typeof opt_config === 'string') { + data[opt_config]() + } + }) +} - // TAB PLUGIN DEFINITION - // ===================== +/** + * @return {string} + * @protected + */ +Popover.prototype.getName = function () { + return Popover._NAME +} + - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tab') +/** + * @override + */ +Popover.prototype.getDataKey = function () { + return Popover._DATA_KEY +} - if (!data) $this.data('bs.tab', (data = new Tab(this))) - if (typeof option == 'string') data[option]() - }) - } - var old = $.fn.tab +/** + * @override + */ +Popover.prototype.getEventObject = function () { + return Popover._Event +} - $.fn.tab = Plugin - $.fn.tab.Constructor = Tab +/** + * @override + */ +Popover.prototype.getArrowElement = function () { + return (this.arrow = this.arrow || $(this.getTipElement()).find(Popover._Selector.ARROW)[0]) +} - // TAB NO CONFLICT - // =============== - $.fn.tab.noConflict = function () { - $.fn.tab = old - return this +/** + * @override + */ +Popover.prototype.setContent = function () { + var tip = this.getTipElement() + var title = this.getTitle() + var content = this._getContent() + var titleElement = $(tip).find(Popover._Selector.TITLE)[0] + + if (titleElement) { + titleElement[this.config['html'] ? 'innerHTML' : 'innerText'] = title } + // we use append for html objects to maintain js events + $(tip).find(Popover._Selector.CONTENT).children().detach().end()[ + this.config['html'] ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) - // TAB DATA-API - // ============ + $(tip) + .removeClass(Popover._ClassName.FADE) + .removeClass(Popover._ClassName.IN) - var clickHandler = function (e) { - e.preventDefault() - Plugin.call($(this), 'show') + for (var direction in Tooltip.Direction) { + $(tip).removeClass(Popover._NAME + '-' + Tooltip.Direction[direction]) } +} - $(document) - .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) - .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) -}(jQuery); +/** + * @override + */ +Popover.prototype.isWithContent = function () { + return this.getTitle() || this._getContent() +} + + +/** + * @override + */ +Popover.prototype.getTipElement = function () { + return (this.tip = this.tip || $(this.config['template'])[0]) +} -/* ======================================================================== - * Bootstrap: affix.js v3.3.2 - * http://getbootstrap.com/javascript/#affix + +/** + * @private + */ +Popover.prototype._getContent = function () { + return this.element.getAttribute('data-content') + || (typeof this.config['content'] == 'function' ? + this.config['content'].call(this.element) : + this.config['content']) +} + + + +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ + +/** + * @const + * @type {Function} + */ +$.fn[Popover._NAME] = Popover._jQueryInterface + + +/** + * @const + * @type {Function} + */ +$.fn[Popover._NAME]['Constructor'] = Popover + + +/** + * @const + * @type {Function} + */ +$.fn[Popover._NAME]['noConflict'] = function () { + $.fn[Popover._NAME] = Popover._JQUERY_NO_CONFLICT + return this +} + +/** ======================================================================= + * Bootstrap: tab.js v4.0.0 + * http://getbootstrap.com/javascript/#tabs * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ + * ======================================================================== + * @fileoverview - Bootstrap's tab plugin. Tab O_O + * + * Public Methods & Properties: + * + * + $.tab + * + $.tab.noConflict + * + $.tab.Constructor + * + $.tab.Constructor.VERSION + * + $.tab.Constructor.prototype.show + * + * ======================================================================== + */ -+function ($) { - 'use strict'; +'use strict'; - // AFFIX CLASS DEFINITION - // ====================== +/** + * Our Tab class. + * @param {Element!} element + * @constructor + */ +var Tab = function (element) { - var Affix = function (element, options) { - this.options = $.extend({}, Affix.DEFAULTS, options) + /** @type {Element} */ + this._element = element - this.$target = $(this.options.target) - .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) - .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) +} - this.$element = $(element) - this.affixed = - this.unpin = - this.pinnedOffset = null - this.checkPosition() - } +/** + * @const + * @type {string} + */ +Tab['VERSION'] = '4.0.0' - Affix.VERSION = '3.3.2' - Affix.RESET = 'affix affix-top affix-bottom' +/** + * @const + * @type {string} + * @private + */ +Tab._NAME = 'tab' - Affix.DEFAULTS = { - offset: 0, - target: window - } - Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { - var scrollTop = this.$target.scrollTop() - var position = this.$element.offset() - var targetHeight = this.$target.height() +/** + * @const + * @type {string} + * @private + */ +Tab._DATA_KEY = 'bs.tab' + - if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false +/** + * @const + * @type {number} + * @private + */ +Tab._TRANSITION_DURATION = 150 - if (this.affixed == 'bottom') { - if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' - return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + +/** + * @const + * @enum {string} + * @private + */ +Tab._Event = { + HIDE : 'hide.bs.tab', + HIDDEN : 'hidden.bs.tab', + SHOW : 'show.bs.tab', + SHOWN : 'shown.bs.tab' +} + + +/** + * @const + * @enum {string} + * @private + */ +Tab._ClassName = { + DROPDOWN_MENU : 'dropdown-menu', + ACTIVE : 'active', + FADE : 'fade', + IN : 'in' +} + + +/** + * @const + * @enum {string} + * @private + */ +Tab._Selector = { + A : 'a', + LI : 'li', + LI_DROPDOWN : 'li.dropdown', + UL : 'ul:not(.dropdown-menu)', + FADE_CHILD : ':scope > .fade', + ACTIVE : '.active', + ACTIVE_CHILD : ':scope > .active', + DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"]', + DROPDOWN_ACTIVE_CHILD : ':scope > .dropdown-menu > .active' +} + + +/** + * @param {Object|string=} opt_config + * @this {jQuery} + * @return {jQuery} + * @private + */ +Tab._jQueryInterface = function (opt_config) { + return this.each(function () { + var $this = $(this) + var data = $this.data(Tab._DATA_KEY) + + if (!data) { + data = data = new Tab(this) + $this.data(Tab._DATA_KEY, data) } - var initializing = this.affixed == null - var colliderTop = initializing ? scrollTop : position.top - var colliderHeight = initializing ? targetHeight : height + if (typeof opt_config === 'string') { + data[opt_config]() + } + }) +} - if (offsetTop != null && scrollTop <= offsetTop) return 'top' - if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' - return false +/** + * Show the tab + */ +Tab.prototype['show'] = function () { + if ( this._element.parentNode + && this._element.parentNode.nodeType == Node.ELEMENT_NODE + && $(this._element).parent().hasClass(Tab._ClassName.ACTIVE)) { + return + } + + var ulElement = $(this._element).closest(Tab._Selector.UL)[0] + var selector = Bootstrap.getSelectorFromElement(this._element) + + if (ulElement) { + var previous = /** @type {Array.<Element>} */ ($.makeArray($(ulElement).find(Tab._Selector.ACTIVE))) + previous = previous[previous.length - 1] + + if (previous) { + previous = $(previous).find('a')[0] + } } - Affix.prototype.getPinnedOffset = function () { - if (this.pinnedOffset) return this.pinnedOffset - this.$element.removeClass(Affix.RESET).addClass('affix') - var scrollTop = this.$target.scrollTop() - var position = this.$element.offset() - return (this.pinnedOffset = position.top - scrollTop) + var hideEvent = $.Event(Tab._Event.HIDE, { + relatedTarget: this._element + }) + + var showEvent = $.Event(Tab._Event.SHOW, { + relatedTarget: previous + }) + + if (previous) { + $(previous).trigger(hideEvent) } - Affix.prototype.checkPositionWithEventLoop = function () { - setTimeout($.proxy(this.checkPosition, this), 1) + $(this._element).trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + if (selector) { + var target = $(selector)[0] } - Affix.prototype.checkPosition = function () { - if (!this.$element.is(':visible')) return + this._activate($(this._element).closest(Tab._Selector.LI)[0], ulElement) - var height = this.$element.height() - var offset = this.options.offset - var offsetTop = offset.top - var offsetBottom = offset.bottom - var scrollHeight = $('body').height() + var complete = function () { + var hiddenEvent = $.Event(Tab._Event.HIDDEN, { + relatedTarget: this._element + }) - if (typeof offset != 'object') offsetBottom = offsetTop = offset - if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) - if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + var shownEvent = $.Event(Tab._Event.SHOWN, { + relatedTarget: previous + }) - var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + $(previous).trigger(hiddenEvent) + $(this._element).trigger(shownEvent) + }.bind(this) - if (this.affixed != affix) { - if (this.unpin != null) this.$element.css('top', '') + if (target) { + this._activate(target, /** @type {Element} */ (target.parentNode), complete) + } else { + complete() + } +} - var affixType = 'affix' + (affix ? '-' + affix : '') - var e = $.Event(affixType + '.bs.affix') - this.$element.trigger(e) +/** + * @param {Element} element + * @param {Element} container + * @param {Function=} opt_callback + * @private + */ +Tab.prototype._activate = function (element, container, opt_callback) { + var active = $(container).find(Tab._Selector.ACTIVE_CHILD)[0] + var isTransitioning = opt_callback + && Bootstrap.transition + && ((active && $(active).hasClass(Tab._ClassName.FADE)) + || !!$(container).find(Tab._Selector.FADE_CHILD)[0]) + + var complete = this._transitionComplete.bind(this, element, active, isTransitioning, opt_callback) + + if (active && isTransitioning) { + $(active) + .one(Bootstrap.TRANSITION_END, complete) + .emulateTransitionEnd(Tab._TRANSITION_DURATION) + + } else { + complete() + } + + if (active) { + $(active).removeClass(Tab._ClassName.IN) + } +} - if (e.isDefaultPrevented()) return - this.affixed = affix - this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null +/** + * @param {Element} element + * @param {Element} active + * @param {boolean} isTransitioning + * @param {Function=} opt_callback + * @private + */ +Tab.prototype._transitionComplete = function (element, active, isTransitioning, opt_callback) { + if (active) { + $(active).removeClass(Tab._ClassName.ACTIVE) - this.$element - .removeClass(Affix.RESET) - .addClass(affixType) - .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + var dropdownChild = $(active).find(Tab._Selector.DROPDOWN_ACTIVE_CHILD)[0] + if (dropdownChild) { + $(dropdownChild).removeClass(Tab._ClassName.ACTIVE) } - if (affix == 'bottom') { - this.$element.offset({ - top: scrollHeight - height - offsetBottom - }) + var activeToggle = $(active).find(Tab._Selector.DATA_TOGGLE)[0] + if (activeToggle) { + activeToggle.setAttribute('aria-expanded', false) } } + $(element).addClass(Tab._ClassName.ACTIVE) - // AFFIX PLUGIN DEFINITION - // ======================= + var elementToggle = $(element).find(Tab._Selector.DATA_TOGGLE)[0] + if (elementToggle) { + elementToggle.setAttribute('aria-expanded', true) + } - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.affix') - var options = typeof option == 'object' && option + if (isTransitioning) { + Bootstrap.reflow(element) + $(element).addClass(Tab._ClassName.IN) + } else { + $(element).removeClass(Tab._ClassName.FADE) + } - if (!data) $this.data('bs.affix', (data = new Affix(this, options))) - if (typeof option == 'string') data[option]() - }) + if (element.parentNode && $(element.parentNode).hasClass(Tab._ClassName.DROPDOWN_MENU)) { + var dropdownElement = $(element).closest(Tab._Selector.LI_DROPDOWN)[0] + if (dropdownElement) { + $(dropdownElement).addClass(Tab._ClassName.ACTIVE) + } + + elementToggle = $(element).find(Tab._Selector.DATA_TOGGLE)[0] + if (elementToggle) { + elementToggle.setAttribute('aria-expanded', true) + } } - var old = $.fn.affix + if (opt_callback) { + opt_callback() + } +} - $.fn.affix = Plugin - $.fn.affix.Constructor = Affix +/** + * ------------------------------------------------------------------------ + * jQuery Interface + noConflict implementaiton + * ------------------------------------------------------------------------ + */ + +/** + * @const + * @type {Function} + */ +$.fn[Tab._NAME] = Tab._jQueryInterface - // AFFIX NO CONFLICT - // ================= - $.fn.affix.noConflict = function () { - $.fn.affix = old - return this - } +/** + * @const + * @type {Function} + */ +$.fn[Tab._NAME]['Constructor'] = Tab - // AFFIX DATA-API - // ============== +/** + * @const + * @type {Function} + */ +$.fn[Tab._NAME]['noConflict'] = function () { + $.fn[Tab._NAME] = Tab._JQUERY_NO_CONFLICT + return this +} - $(window).on('load', function () { - $('[data-spy="affix"]').each(function () { - var $spy = $(this) - var data = $spy.data() - data.offset = data.offset || {} - if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom - if (data.offsetTop != null) data.offset.top = data.offsetTop +// TAB DATA-API +// ============ - Plugin.call($spy, data) - }) - }) +var clickHandler = function (e) { + e.preventDefault() + Tab._jQueryInterface.call($(this), 'show') +} -}(jQuery); +$(document) + .on('click.bs.tab.data-api', Tab._Selector.DATA_TOGGLE, clickHandler) diff --git a/dist/js/bootstrap.min.js b/dist/js/bootstrap.min.js index a17f4b3bf..089780400 100644 --- a/dist/js/bootstrap.min.js +++ b/dist/js/bootstrap.min.js @@ -3,5 +3,75 @@ * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.2",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.2",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.2",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".carousel-item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".carousel-item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".carousel-item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.2",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.2",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$backdrop=this.isShown=null,this.scrollbarWidth=0,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.2",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.options.backdrop&&d.adjustBackdrop(),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$element.find(".modal-dialog").one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').prependTo(this.$element).on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.options.backdrop&&this.adjustBackdrop(),this.adjustDialog()},c.prototype.adjustBackdrop=function(){this.$backdrop.css("height",0).css("height",this.$element[0].scrollHeight)},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){this.bodyIsOverflowing=document.body.scrollHeight>document.documentElement.clientHeight,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.2",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(this.type+"-"+h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(this.type+"-"+n).addClass(this.type+"-"+h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in tooltip-top tooltip-bottom tooltip-left tooltip-right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=this.tip(),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.2",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade popover-top popover-bottom popover-left popover-right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".popover-arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.2",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.2",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]}) -})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.2",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a("body").height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} ++function ($) { + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') + } +}(jQuery); + +(function($){var h,k,l={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};function m(a){var b=a.getAttribute("data-target");b||(b=a.getAttribute("href")||"",b=/^#[a-z]/i.test(b)?b:null);return b}function aa(a){do a+=~~(1E6*Math.random());while(document.getElementById(a));return a}function ba(){return{ha:k.end,ia:k.end,handle:function(a){if($(a.target).is(this))return a.handleObj.handler.apply(this,arguments)}}} +function n(a){(new Function("bs","return bs"))(a.offsetHeight)}function ca(){if(window.QUnit)return!1;var a=document.createElement("bootstrap"),b;for(b in l)if(void 0!==a.style[b])return{end:l[b]};return!1}$.fn.f=function(a){var b=!1;$(this).one("bsTransitionEnd",function(){b=!0});var c=function(){b||$(this).trigger(k.end)}.bind(this);setTimeout(c,a)};$(function(){(k=ca())&&($.event.special.bsTransitionEnd=ba())});function p(a){if(a)$(a).on("click",'[data-dismiss="alert"]',q(this))}p.VERSION="4.0.0";var da=$.fn.alert;function s(a){return this.each(function(){var b=$(this),c=b.data("bs.alert");c||(c=new p(this),b.data("bs.alert",c));if("close"===a)c[a](this)})}function q(a){return function(b){b&&b.preventDefault();a.close(this)}} +p.prototype.close=function(a){var b=!1,c=m(a);c&&(b=$(c)[0]);b||(b=$(a).closest(".alert")[0]);a=b;b=$.Event("close.bs.alert");$(a).trigger(b);b.isDefaultPrevented()||($(a).removeClass("in"),k&&$(a).hasClass("fade")?$(a).one("bsTransitionEnd",this.N.bind(this,a)).f(150):this.N(a))};p.prototype.N=function(a){$(a).detach().trigger("closed.bs.alert").remove()};$.fn.alert=s;$.fn.alert.Constructor=p;$.fn.alert.noConflict=function(){$.fn.alert=da;return s}; +$(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',q(new p));function t(a){this.a=a}t.VERSION="4.0.0";var ea=$.fn.button;function u(a){return this.each(function(){var b=$(this).data("bs.button");b||(b=new t(this),$(this).data("bs.button",b));if("toggle"===a)b[a]()})} +t.prototype.toggle=function(){var a=!0,b=$(this.a).closest('[data-toggle="buttons"]')[0];if(b){var c=$(this.a).find("input")[0];c&&("radio"==c.type&&(c.checked&&$(this.a).hasClass("active")?a=!1:(b=$(b).find(".active")[0])&&$(b).removeClass("active")),a&&(c.checked=!$(this.a).hasClass("active"),$(this.a).trigger("change")))}else this.a.setAttribute("aria-pressed",!$(this.a).hasClass("active"));a&&$(this.a).toggleClass("active")};$.fn.button=u;$.fn.button.Constructor=t; +$.fn.button.noConflict=function(){$.fn.button=ea;return this};$(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(a){a.preventDefault();a=a.target;$(a).hasClass("btn")||(a=$(a).closest(".btn"));u.call($(a),"toggle")}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(a){var b=$(a.target).closest(".btn")[0];$(b).toggleClass("focus",/^focus(in)?$/.test(a.type))});function v(a,b){this.a=$(a)[0];this.F=$(this.a).find(fa)[0];this.c=b||null;this.l=this.G=!1;this.h=this.M=this.k=null;if(this.c.keyboard)$(this.a).on("keydown.bs.carousel",this.Y.bind(this));if("hover"==this.c.pause&&!("ontouchstart"in document.documentElement))$(this.a).on("mouseenter.bs.carousel",this.pause.bind(this)).on("mouseleave.bs.carousel",this.cycle.bind(this))}v.VERSION="4.0.0";v.Defaults={interval:5E3,pause:"hover",wrap:!0,keyboard:!0,slide:!1};var fa=".carousel-indicators",ga=$.fn.carousel; +function w(a){return this.each(function(){var b=$(this).data("bs.carousel"),c=$.extend({},v.Defaults,$(this).data(),"object"==typeof a&&a),d="string"==typeof a?a:c.ja;b||(b=new v(this,c),$(this).data("bs.carousel",b));if("number"==typeof a)x(b,a);else if(d)b[d]();else c.interval&&(b.pause(),b.cycle())})}v.prototype.next=function(){this.l||z(this,"next")};v.prototype.prev=function(){this.l||z(this,"prev")}; +v.prototype.pause=function(a){a||(this.G=!0);$(this.a).find(".next, .prev")[0]&&k&&($(this.a).trigger(k.end),this.cycle(!0));clearInterval(this.k);this.k=null};v.prototype.cycle=function(a){a||(this.G=!1);this.k&&(clearInterval(this.k),this.k=null);this.c.interval&&!this.G&&(this.k=setInterval(this.next.bind(this),this.c.interval))};v.prototype.getConfig=function(){return this.c}; +function x(a,b){a.M=$(a.a).find(".active.carousel-item")[0];var c=A(a,a.M);if(!(b>a.h.length-1||0>b))if(a.l)$(a.a).one("slid.bs.carousel",function(){x(this,b)}.bind(a));else c==b?(a.pause(),a.cycle()):z(a,b>c?"next":"prev",a.h[b])}v.prototype.Y=function(a){a.preventDefault();if(!/input|textarea/i.test(a.target.tagName))switch(a.which){case 37:this.prev();break;case 39:this.next()}};function A(a,b){a.h=$.makeArray($(b).parent().find(".carousel-item"));return a.h.indexOf(b)} +function ha(a,b,c){var d=A(a,c);if(("prev"===b&&0===d||"next"===b&&d==a.h.length-1)&&!a.c.wrap)return c;b=(d+("prev"==b?-1:1))%a.h.length;return-1===b?a.h[a.h.length-1]:a.h[b]}function ia(a,b,c){b=$.Event("slide.bs.carousel",{relatedTarget:b,direction:c});$(a.a).trigger(b);return b}function ja(a,b){if(a.F){$(a.F).find(".active").removeClass("active");var c=a.F.children[A(a,b)];c&&$(c).addClass("active")}} +function z(a,b,c){var d=$(a.a).find(".active.carousel-item")[0],e=c||d&&ha(a,b,d);c=!!a.k;var f="next"==b?"left":"right";if(e&&$(e).hasClass("active"))a.l=!1;else if(!ia(a,e,f).isDefaultPrevented()&&d&&e){a.l=!0;c&&a.pause();ja(a,e);var g=$.Event("slid.bs.carousel",{relatedTarget:e,direction:f});k&&$(a.a).hasClass("slide")?($(e).addClass(b),n(e),$(d).addClass(f),$(e).addClass(f),$(d).one("bsTransitionEnd",function(){$(e).removeClass(f).removeClass(b);$(e).addClass("active");$(d).removeClass("active").removeClass(b).removeClass(f); +this.l=!1;setTimeout(function(){$(this.a).trigger(g)}.bind(this),0)}.bind(a)).f(600)):($(d).removeClass("active"),$(e).addClass("active"),a.l=!1,$(a.a).trigger(g));c&&a.cycle()}}$.fn.carousel=w;$.fn.carousel.Constructor=v;$.fn.carousel.noConflict=function(){$.fn.carousel=ga;return this}; +$(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(a){var b=m(this);if(b&&(b=$(b)[0])&&$(b).hasClass("carousel")){var c=$.extend({},$(b).data(),$(this).data()),d=this.getAttribute("data-slide-to");d&&(c.interval=!1);w.call($(b),c);d&&x($(b).data("bs.carousel"),d);a.preventDefault()}});$(window).on("load",function(){$('[data-ride="carousel"]').each(function(){var a=$(this);w.call(a,a.data())})});function B(a,b){this.a=a;this.c=$.extend({},B.Defaults,b);this.o="string"==typeof this.c.trigger?$(this.c.trigger)[0]:this.c.trigger;this.A=!1;var c;if(this.c.parent){var d='[data-toggle="collapse"][data-parent="'+this.c.parent+'"]';c=$(this.c.parent)[0];for(var d=$.makeArray($(c).find(d)),e=0;e<d.length;e++)C(D(d[e]),d[e])}else c=null;this.Z=c;this.c.parent||C(this.a,this.o);this.c.toggle&&this.toggle()}B.VERSION="4.0.0";B.Defaults={toggle:!0,trigger:'[data-toggle="collapse"]',parent:null}; +var ka=$.fn.collapse;function E(a){return this.each(function(){var b=$(this),c=b.data("bs.collapse"),d=$.extend({},B.Defaults,b.data(),"object"==typeof a&&a);!c&&d.toggle&&"show"==a&&(d.toggle=!1);c||(c=new B(this,d),b.data("bs.collapse",c));if("string"==typeof a)c[a]()})}function D(a){return(a=m(a))?$(a)[0]:null}B.prototype.toggle=function(){$(this.a).hasClass("in")?this.hide():this.show()}; +B.prototype.show=function(){if(!this.A&&!$(this.a).hasClass("in")){var a,b;this.Z&&(b=$.makeArray($(".panel > .in, .panel > .collapsing")),b.length||(b=null));if(b&&(a=$(b).data("bs.collapse"))&&a.A)return;var c=$.Event("show.bs.collapse");$(this.a).trigger(c);if(!c.isDefaultPrevented()){b&&(E.call($(b),"hide"),a||$(b).data("bs.collapse",null));var d=F(this);$(this.a).removeClass("collapse").addClass("collapsing");this.a.style[d]=0;this.a.setAttribute("aria-expanded",!0);this.o&&($(this.o).removeClass("collapsed"), +this.o.setAttribute("aria-expanded",!0));this.setTransitioning(!0);a=function(){$(this.a).removeClass("collapsing").addClass("collapse").addClass("in");this.a.style[d]="";this.setTransitioning(!1);$(this.a).trigger("shown.bs.collapse")}.bind(this);k?(b="scroll"+(d[0].toUpperCase()+d.slice(1)),$(this.a).one("bsTransitionEnd",a).f(600),this.a.style[d]=this.a[b]+"px"):a()}}}; +B.prototype.hide=function(){if(!this.A&&$(this.a).hasClass("in")){var a=$.Event("hide.bs.collapse");$(this.a).trigger(a);if(!a.isDefaultPrevented()){a=F(this);this.a.style[a]=this.a["width"===a?"offsetWidth":"offsetHeight"]+"px";n(this.a);$(this.a).addClass("collapsing").removeClass("collapse").removeClass("in");this.a.setAttribute("aria-expanded",!1);this.o&&($(this.o).addClass("collapsed"),this.o.setAttribute("aria-expanded",!1));this.setTransitioning(!0);var b=function(){this.setTransitioning(!1); +$(this.a).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")}.bind(this);this.a.style[a]=0;if(!k)return b();$(this.a).one("bsTransitionEnd",b).f(600)}}};B.prototype.setTransitioning=function(a){this.A=a};function F(a){return $(a.a).hasClass("width")?"width":"height"}function C(a,b){if(a){var c=$(a).hasClass("in");a.setAttribute("aria-expanded",c);b&&(b.setAttribute("aria-expanded",c),$(b).toggleClass("collapsed",!c))}}$.fn.collapse=E;$.fn.collapse.Constructor=B; +$.fn.collapse.noConflict=function(){$.fn.collapse=ka;return this};$(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(a){a.preventDefault();a=D(this);var b=$(a).data("bs.collapse")?"toggle":$.extend({},$(this).data(),{trigger:this});E.call($(a),b)});function G(a){$(a).on("click.bs.dropdown",this.toggle)}G.VERSION="4.0.0";var la=$.fn.dropdown; +function H(a){if(!a||3!=a.which){(a=$(".dropdown-backdrop")[0])&&a.parentNode.removeChild(a);a=$.makeArray($('[data-toggle="dropdown"]'));for(var b=0;b<a.length;b++){var c=I(a[b]),d={relatedTarget:a[b]};if($(c).hasClass("open")){var e=$.Event("hide.bs.dropdown",d);$(c).trigger(e);e.isDefaultPrevented()||(a[b].setAttribute("aria-expanded","false"),$(c).removeClass("open").trigger("hidden.bs.dropdown",d))}}}}function I(a){var b=m(a);if(b)var c=$(b)[0];return c||a.parentNode} +function J(a){if(/(38|40|27|32)/.test(a.which)&&!/input|textarea/i.test(a.target.tagName)&&(a.preventDefault(),a.stopPropagation(),!this.disabled&&!$(this).hasClass("disabled"))){var b=I(this),c=$(b).hasClass("open");!c&&27!=a.which||c&&27==a.which?(27==a.which&&(a=$(b).find('[data-toggle="dropdown"]')[0],$(a).trigger("focus")),$(this).trigger("click")):(b=$.makeArray($('[role="menu"] li:not(.divider) a, [role="listbox"] li:not(.divider) a')),b=b.filter(function(a){return a.offsetWidth||a.offsetHeight}), +b.length&&(c=b.indexOf(a.target),38==a.which&&0<c&&c--,40==a.which&&c<b.length-1&&c++,~c||(c=0),b[c].focus()))}} +G.prototype.toggle=function(){if(!this.disabled&&!$(this).hasClass("disabled")){var a=I(this),b=$(a).hasClass("open");H();if(b)return!1;"ontouchstart"in document.documentElement&&!$(a).closest(".navbar-nav").length&&(b=document.createElement("div"),b.className="dropdown-backdrop",this.parentNode.insertBefore(this,b),$(b).on("click",H));var b={relatedTarget:this},c=$.Event("show.bs.dropdown",b);$(a).trigger(c);if(!c.isDefaultPrevented())return this.focus(),this.setAttribute("aria-expanded","true"), +$(a).toggleClass("open"),$(a).trigger("shown.bs.dropdown",b),!1}};$.fn.dropdown=function(a){return this.each(function(){var b=$(this).data("bs.dropdown");b||$(this).data("bs.dropdown",b=new G(this));"string"===typeof a&&b[a].call(this)})};$.fn.dropdown.Constructor=G;$.fn.dropdown.noConflict=function(){$.fn.dropdown=la;return this}; +$(document).on("click.bs.dropdown.data-api",H).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',G.prototype.toggle).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',J).on("keydown.bs.dropdown.data-api",'[role="menu"]',J).on("keydown.bs.dropdown.data-api",'[role="listbox"]',J);function K(a,b){this.c=b;this.a=a;this.d=null;this.w=this.g=!1;this.B=0}K.VERSION="4.0.0";K.Defaults={backdrop:!0,keyboard:!0,show:!0};var ma=$.fn.modal;function L(a,b){return this.each(function(){var c=$(this).data("bs.modal"),d=$.extend({},K.Defaults,$(this).data(),"object"==typeof a&&a);c||(c=new K(this,d),$(this).data("bs.modal",c));if("string"==typeof a)c[a](b);else d.show&&c.show(b)})}K.prototype.toggle=function(a){return this.g?this.hide():this.show(a)}; +K.prototype.show=function(a){var b=$.Event("show.bs.modal",{relatedTarget:a});$(this.a).trigger(b);if(!this.g&&!b.isDefaultPrevented()){this.g=!0;this.w=document.body.scrollHeight>document.documentElement.clientHeight;b=document.createElement("div");b.className="modal-scrollbar-measure";document.body.appendChild(b);var c=b.offsetWidth-b.clientWidth;document.body.removeChild(b);this.B=c;b=parseInt($(document.body).css("padding-right")||0,10);this.w&&(document.body.style.paddingRight=b+this.B+"px"); +$(document.body).addClass("modal-open");M(this);N(this);$(this.a).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',this.hide.bind(this));O(this,this.$.bind(this,a))}}; +K.prototype.hide=function(a){a&&a.preventDefault();a=$.Event("hide.bs.modal");$(this.a).trigger(a);this.g&&!a.isDefaultPrevented()&&(this.g=!1,M(this),N(this),$(document).off("focusin.bs.modal"),$(this.a).removeClass("in"),this.a.setAttribute("aria-hidden",!0),$(this.a).off("click.dismiss.bs.modal"),k&&$(this.a).hasClass("fade")?$(this.a).one("bsTransitionEnd",this.P.bind(this)).f(300):this.P())}; +K.prototype.$=function(a){var b=k&&$(this.a).hasClass("fade");this.a.parentNode&&this.a.parentNode.nodeType==Node.ELEMENT_NODE||document.body.appendChild(this.a);this.a.style.display="block";this.a.scrollTop=0;this.c.backdrop&&P(this);b&&n(this.a);$(this.a).addClass("in");this.a.setAttribute("aria-hidden",!1);na(this);var c=$.Event("shown.bs.modal",{relatedTarget:a});a=function(){this.a.focus();$(this.a).trigger(c)}.bind(this);b?(b=$(this.a).find(".modal-dialog")[0],$(b).one("bsTransitionEnd",a).f(300)): +a()};function na(a){$(document).off("focusin.bs.modal").on("focusin.bs.modal",function(a){this.a===a.target||$(this.a).has(a.target).length||this.a.focus()}.bind(a))}function M(a){if(a.g&&a.c.keyboard)$(a.a).on("keydown.dismiss.bs.modal",function(a){27===a.which&&this.hide()}.bind(a));else a.g||$(a.a).off("keydown.dismiss.bs.modal")}function N(a){if(a.g)$(window).on("resize.bs.modal",a.X.bind(a));else $(window).off("resize.bs.modal")} +K.prototype.P=function(){this.a.style.display="none";O(this,function(){$(document.body).removeClass("modal-open");this.a.style.paddingLeft="";this.a.style.paddingRight="";document.body.style.paddingRight="";$(this.a).trigger("hidden.bs.modal")}.bind(this))}; +function O(a,b){var c=$(a.a).hasClass("fade")?"fade":"";if(a.g&&a.c.backdrop){var d=k&&c;a.d=document.createElement("div");a.d.className="modal-backdrop";c&&$(a.d).addClass(c);$(a.a).prepend(a.d);$(a.d).on("click.dismiss.bs.modal",function(a){a.target===a.currentTarget&&("static"===this.c.backdrop?this.a.focus():this.hide())}.bind(a));d&&n(a.d);$(a.d).addClass("in");b&&(d?$(a.d).one("bsTransitionEnd",b).f(150):b())}else!a.g&&a.d?($(a.d).removeClass("in"),c=function(){this.d&&(this.d.parentNode.removeChild(this.d), +this.d=null);b&&b()}.bind(a),k&&$(a.a).hasClass("fade")?$(a.d).one("bsTransitionEnd",c).f(150):c()):b&&b()}K.prototype.X=function(){this.c.backdrop&&P(this);var a=this.a.scrollHeight>document.documentElement.clientHeight;!this.w&&a&&(this.a.style.paddingLeft=this.B+"px");this.w&&!a&&(this.a.style.paddingRight=this.B+"px")};function P(a){a.d.style.height=0;a.d.style.height=a.a.scrollHeight+"px"}$.fn.modal=L;$.fn.modal.Constructor=K;$.fn.modal.noConflict=function(){$.fn.modal=ma;return this}; +$(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(a){var b=m(this);if(b)var c=$(b)[0];b=$(c).data("bs.modal")?"toggle":$.extend({},$(c).data(),$(this).data());"A"==this.tagName&&a.preventDefault();var d=$(c).one("show.bs.modal",function(a){if(!a.isDefaultPrevented())d.one("hidden.bs.modal",function(){$(this).is(":visible")&&this.focus()}.bind(this))}.bind(this));L.call($(c),b,this)});function Q(a,b){this.e="BODY"==a.tagName?window:a;this.c=$.extend({},Q.Defaults,b);this.C=(this.c.target||"")+" .nav li > a";this.m=[];this.p=[];this.s=null;this.R=0;$(this.e).on("scroll.bs.scrollspy",this.Q.bind(this));this.refresh();this.Q()}Q.VERSION="4.0.0";Q.Defaults={offset:10};var oa=$.fn.scrollspy;function R(a){return this.each(function(){var b=$(this).data("bs.scrollspy"),c="object"===typeof a&&a||null;b||(b=new Q(this,c),$(this).data("bs.scrollspy",b));if("string"===typeof a)b[a]()})} +Q.prototype.refresh=function(){var a="offset",b=0;this.e!==this.e.window&&(a="position",b=this.e===window?this.e.scrollY:this.e.scrollTop);this.m=[];this.p=[];this.R=this.e.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight);$.makeArray($(this.C)).map(function(c){var d;(c=m(c))&&(d=$(c)[0]);if(d&&(d.offsetWidth||d.offsetHeight))return[$(d)[a]().top+b,c]}).filter(function(a){return a}).sort(function(a,b){return a[0]-b[0]}).forEach(function(a){this.m.push(a[0]); +this.p.push(a[1])}.bind(this))};Q.prototype.Q=function(){var a=(this.e===window?this.e.scrollY:this.e.scrollTop)+this.c.offset,b=this.e.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight),c=this.c.offset+b-this.e.offsetHeight;this.R!=b&&this.refresh();a>=c&&(b=this.p[this.p.length-1],this.s!=b&&this.r(b));if(this.s&&a<this.m[0])this.s=null,S(this);else for(b=this.m.length;b--;)this.s!=this.p[b]&&a>=this.m[b]&&(!this.m[b+1]||a<this.m[b+1])&&this.r(this.p[b])}; +Q.prototype.r=function(a){this.s=a;S(this);for(var b=$(this.C+'[data-target="'+a+'"],'+this.C+'[href="'+a+'"]').parents("li"),c=b.length;c--;){$(b[c]).addClass("active");var d=b[c].parentNode;d&&$(d).hasClass("dropdown-menu")&&(d=$(d).closest("li.dropdown")[0],$(d).addClass("active"))}$(this.e).trigger("activate.bs.scrollspy",{relatedTarget:a})};function S(a){a=$(a.C).parentsUntil(a.c.target,".active");for(var b=a.length;b--;)$(a[b]).removeClass("active")}$.fn.scrollspy=R; +$.fn.scrollspy.Constructor=Q;$.fn.scrollspy.noConflict=function(){$.fn.scrollspy=oa;return this};$(window).on("load.bs.scrollspy.data-api",function(){for(var a=$.makeArray($('[data-spy="scroll"]')),b=a.length;b--;){var c=$(a[b]);R.call(c,c.data())}});function T(a,b){this.t=!0;this.u=0;this.j="";this.element=a;var c=$.extend({},this.constructor.Defaults,$(this.element).data(),b);c.delay&&"number"==typeof c.delay&&(c.delay={show:c.delay,hide:c.delay});this.b=c;this.D=this.W=null;this.b.viewport&&(this.S=$(this.b.viewport.selector||this.b.viewport)[0]);pa(this)}T.VERSION="4.0.0"; +T.Defaults={container:!1,animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,viewport:{selector:"body",padding:0}};var U={fa:"top",da:"left",ea:"right",ca:"bottom"},qa={J:"hide.bs.tooltip",I:"hidden.bs.tooltip",K:"show.bs.tooltip",L:"shown.bs.tooltip"},ra=$.fn.tooltip;T.prototype.enable=function(){this.t=!0}; +T.prototype.disable=function(){this.t=!1};T.prototype.toggleEnabled=function(){this.t=!this.t};T.prototype.toggle=function(a){var b=this,c=this.q();a&&(b=$(a.currentTarget).data(c),b||(b=new this.constructor(a.currentTarget,V(this)),$(a.currentTarget).data(c,b)));$(b.i()).hasClass("in")?b.H(null,b):b.O(null,b)};T.prototype.destroy=function(){clearTimeout(this.u);this.hide(function(){$(this.element).off(".tooltip").removeData(this.q())}.bind(this))}; +T.prototype.show=function(){var a=$.Event(this.v().K);if(this.U()&&this.t){$(this.element).trigger(a);var b=$.contains(this.element.ownerDocument.documentElement,this.element);if(!a.isDefaultPrevented()&&b){a=this.i();b=aa(this.getName());a.setAttribute("id",b);this.element.setAttribute("aria-describedby",b);this.V();this.b.animation&&$(a).addClass("fade");var b="function"==typeof this.b.placement?this.b.placement.call(this,a,this.element):this.b.placement,c=/\s?auto?\s?/i,d=c.test(b);d&&(b=b.replace(c, +"")||"top");a.parentNode&&a.parentNode.nodeType==Node.ELEMENT_NODE&&a.parentNode.removeChild(a);a.style.top=0;a.style.left=0;a.style.display="block";$(a).addClass("tooltip-"+b);$(a).data(this.q(),this);this.b.container?$(this.b.container)[0].appendChild(a):this.element.parentNode.insertBefore(a,this.element.nextSibling);var c=W(this),e=a.offsetWidth,a=a.offsetHeight,b=sa(this,d,b,c,e,a);ta(this,"bottom"==b?{top:c.top+c.height,left:c.left+c.width/2-e/2}:"top"==b?{top:c.top-a,left:c.left+c.width/2- +e/2}:"left"==b?{top:c.top+c.height/2-a/2,left:c.left-e}:{top:c.top+c.height/2-a/2,left:c.left+c.width},b);a=function(){var a=this.ba;$(this.element).trigger(this.v().L);this.ba=null;"out"==a&&this.H(null,this)}.bind(this);k&&$(this.n).hasClass("fade")?$(this.n).one("bsTransitionEnd",a).f(150):a()}}}; +T.prototype.hide=function(a){var b=this.i(),c=$.Event(this.v().J),d=function(){"in"!=this.j&&b.parentNode.removeChild(b);this.element.removeAttribute("aria-describedby");$(this.element).trigger(this.v().I);a&&a()}.bind(this);$(this.element).trigger(c);c.isDefaultPrevented()||($(b).removeClass("in"),k&&$(this.n).hasClass("fade")?$(b).one("bsTransitionEnd",d).f(150):d(),this.j="")};T.prototype.getHoverState=function(){return this.j};h=T.prototype;h.getName=function(){return"tooltip"};h.q=function(){return"bs.tooltip"}; +h.v=function(){return qa};function X(a){var b=a.element.getAttribute("data-original-title");b||(b="function"===typeof a.b.title?a.b.title.call(a.element):a.b.title);return b}h.i=function(){return this.n=this.n||$(this.b.template)[0]};h.T=function(){return this.D=this.D||$(this.i()).find(".tooltip-arrow")[0]};h.U=function(){return!!X(this)}; +h.V=function(){var a=this.i(),b=X(this);$(a).find(".tooltip-inner")[0][this.b.html?"innerHTML":"innerText"]=b;$(a).removeClass("fade").removeClass("in");for(var c in U)$(a).removeClass("tooltip-"+c)}; +function pa(a){a.b.trigger.split(" ").forEach(function(a){if("click"==a)$(this.element).on("click.bs.tooltip",this.b.selector,this.toggle.bind(this));else if("manual"!=a){var c="hover"==a?"mouseenter":"focusin";a="hover"==a?"mouseleave":"focusout";$(this.element).on(c+".bs.tooltip",this.b.selector,this.O.bind(this)).on(a+".bs.tooltip",this.b.selector,this.H.bind(this))}}.bind(a));a.b.selector?a.b=$.extend({},a.b,{trigger:"manual",selector:""}):ua(a)} +function V(a){var b={},c=a.constructor.Defaults;if(a.b)for(var d in a.b){var e=a.b[d];c[d]!=e&&(b[d]=e)}return b}function sa(a,b,c,d,e,f){if(b){b=c;var g=a.b.container?$(a.b.container)[0]:a.element.parentNode,g=W(a,g);c="bottom"==c&&d.bottom+f>g.bottom?"top":"top"==c&&d.top-f<g.top?"bottom":"right"==c&&d.right+e>g.width?"left":"left"==c&&d.left-e<g.left?"right":c;$(a.n).removeClass("tooltip-"+b).addClass("tooltip-"+c)}return c} +function va(a,b,c,d,e){var f={top:0,left:0};if(!a.S)return f;var g=a.b.viewport&&a.b.viewport.padding||0;a=W(a,a.S);"right"===b||"left"===b?(d=c.top-g-a.scroll,c=c.top+g-a.scroll+e,d<a.top?f.top=a.top-d:c>a.top+a.height&&(f.top=a.top+a.height-c)):(e=c.left-g,c=c.left+g+d,e<a.left?f.left=a.left-e:c>a.width&&(f.left=a.left+a.width-c));return f} +function W(a,b){var c=b||a.element,d="BODY"==c.tagName,e=c.getBoundingClientRect(),c=d?{top:0,left:0}:$(c).offset();return $.extend({},e,{scroll:d?document.documentElement.scrollTop||document.body.scrollTop:a.element.scrollTop},d?{width:window.innerWidth,height:window.innerHeight}:null,c)} +function ta(a,b,c){var d=a.i(),e=d.offsetWidth,f=d.offsetHeight,g=parseInt(d.style.marginTop,10),r=parseInt(d.style.marginLeft,10);isNaN(g)&&(g=0);isNaN(r)&&(r=0);b.top+=g;b.left+=r;$.offset.setOffset(d,$.extend({ka:function(a){d.style.top=Math.round(a.top)+"px";d.style.left=Math.round(a.left)+"px"}},b),0);$(d).addClass("in");g=d.offsetWidth;r=d.offsetHeight;"top"==c&&r!=f&&(b.top=b.top+f-r);var y=va(a,c,b,g,r);y.left?b.left+=y.left:b.top+=y.top;e=(c="top"===c||"bottom"===c)?2*y.left-e+g:2*y.top- +f+r;f=c?"offsetWidth":"offsetHeight";$(d).offset(b);wa(a,e,d[f],c)}function wa(a,b,c,d){a=a.T();a.style[d?"left":"top"]=50*(1-b/c)+"%";a.style[d?"top":"left"]=""}function ua(a){if(a.element.getAttribute("title")||"string"!=typeof a.element.getAttribute("data-original-title"))a.element.setAttribute("data-original-title",a.element.getAttribute("title")||""),a.element.setAttribute("title","")} +h.O=function(a,b){var c=this.q(),d=b||$(a.currentTarget).data(c);d&&d.n&&d.n.offsetWidth?d.j="in":(d||(d=new this.constructor(a.currentTarget,V(this)),$(a.currentTarget).data(c,d)),clearTimeout(d.u),d.j="in",d.b.delay&&d.b.delay.show?d.u=setTimeout(function(){"in"==d.j&&d.show()},d.b.delay.show):d.show())}; +h.H=function(a,b){var c=this.q(),d=b||$(a.currentTarget).data(c);d||(d=new this.constructor(a.currentTarget,V(this)),$(a.currentTarget).data(c,d));clearTimeout(d.u);d.j="out";d.b.delay&&d.b.delay.hide?d.u=setTimeout(function(){"out"==d.j&&d.hide()},d.b.delay.hide):d.hide()};$.fn.tooltip=function(a){return this.each(function(){var b=$(this).data("bs.tooltip"),c="object"==typeof a?a:null;if(b||"destroy"!=a)if(b||(b=new T(this,c),$(this).data("bs.tooltip",b)),"string"===typeof a)b[a]()})}; +$.fn.tooltip.Constructor=T;$.fn.tooltip.noConflict=function(){$.fn.tooltip=ra;return this};if(!T)throw Error("Popover requires tooltip.js");function Y(a,b){T.apply(this,arguments)}(function(){function a(){}a.prototype=T.prototype;Y.prototype=new a;Y.prototype.constructor=Y})();Y.VERSION="4.0.0";Y.Defaults=$.extend({},$.fn.tooltip.Constructor.Defaults,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}); +var xa={J:"hide.bs.popover",I:"hidden.bs.popover",K:"show.bs.popover",L:"shown.bs.popover"},ya=$.fn.popover;h=Y.prototype;h.getName=function(){return"popover"};h.q=function(){return"bs.popover"};h.v=function(){return xa};h.T=function(){return this.D=this.D||$(this.i()).find(".popover-arrow")[0]}; +h.V=function(){var a=this.i(),b=X(this),c=za(this),d=$(a).find(".popover-title")[0];d&&(d[this.b.html?"innerHTML":"innerText"]=b);$(a).find(".popover-content").children().detach().end()[this.b.html?"string"==typeof c?"html":"append":"text"](c);$(a).removeClass("fade").removeClass("in");for(var e in U)$(a).removeClass("popover-"+U[e])};h.U=function(){return X(this)||za(this)};h.i=function(){return this.W=this.W||$(this.b.template)[0]}; +function za(a){return a.element.getAttribute("data-content")||("function"==typeof a.b.content?a.b.content.call(a.element):a.b.content)}$.fn.popover=function(a){return this.each(function(){var b=$(this).data("bs.popover"),c="object"===typeof a?a:null;if(b||"destroy"!==a)if(b||(b=new Y(this,c),$(this).data("bs.popover",b)),"string"===typeof a)b[a]()})};$.fn.popover.Constructor=Y;$.fn.popover.noConflict=function(){$.fn.popover=ya;return this};function Z(a){this.a=a}Z.VERSION="4.0.0";function Aa(a){return this.each(function(){var b=$(this),c=b.data("bs.tab");c||(c=c=new Z(this),b.data("bs.tab",c));if("string"===typeof a)c[a]()})} +Z.prototype.show=function(){if(!this.a.parentNode||this.a.parentNode.nodeType!=Node.ELEMENT_NODE||!$(this.a).parent().hasClass("active")){var a=$(this.a).closest("ul:not(.dropdown-menu)")[0],b=m(this.a);if(a){var c=$.makeArray($(a).find(".active"));(c=c[c.length-1])&&(c=$(c).find("a")[0])}var d=$.Event("hide.bs.tab",{relatedTarget:this.a}),e=$.Event("show.bs.tab",{relatedTarget:c});c&&$(c).trigger(d);$(this.a).trigger(e);if(!e.isDefaultPrevented()&&!d.isDefaultPrevented()){if(b)var f=$(b)[0];this.r($(this.a).closest("li")[0], +a);a=function(){var a=$.Event("hidden.bs.tab",{relatedTarget:this.a}),b=$.Event("shown.bs.tab",{relatedTarget:c});$(c).trigger(a);$(this.a).trigger(b)}.bind(this);f?this.r(f,f.parentNode,a):a()}}};Z.prototype.r=function(a,b,c){var d=$(b).find(":scope > .active")[0];b=c&&k&&(d&&$(d).hasClass("fade")||!!$(b).find(":scope > .fade")[0]);a=this.aa.bind(this,a,d,b,c);d&&b?$(d).one("bsTransitionEnd",a).f(150):a();d&&$(d).removeClass("in")}; +Z.prototype.aa=function(a,b,c,d){if(b){$(b).removeClass("active");var e=$(b).find(":scope > .dropdown-menu > .active")[0];e&&$(e).removeClass("active");(b=$(b).find('[data-toggle="tab"], [data-toggle="pill"]')[0])&&b.setAttribute("aria-expanded",!1)}$(a).addClass("active");(b=$(a).find('[data-toggle="tab"], [data-toggle="pill"]')[0])&&b.setAttribute("aria-expanded",!0);c?(n(a),$(a).addClass("in")):$(a).removeClass("fade");a.parentNode&&$(a.parentNode).hasClass("dropdown-menu")&&((c=$(a).closest("li.dropdown")[0])&& +$(c).addClass("active"),(b=$(a).find('[data-toggle="tab"], [data-toggle="pill"]')[0])&&b.setAttribute("aria-expanded",!0));d&&d()};$.fn.tab=Aa;$.fn.tab.Constructor=Z;$.fn.tab.noConflict=function(){$.fn.tab=Z.ga;return this};$(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(a){a.preventDefault();Aa.call($(this),"show")});})(jQuery); diff --git a/dist/js/bootstrap.min.js.gz b/dist/js/bootstrap.min.js.gz Binary files differnew file mode 100644 index 000000000..84313c393 --- /dev/null +++ b/dist/js/bootstrap.min.js.gz diff --git a/dist/js/npm.js b/dist/js/npm.js index bf6aa8060..ed761ca33 100644 --- a/dist/js/npm.js +++ b/dist/js/npm.js @@ -1,13 +1,13 @@ // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. -require('../../js/transition.js') +require('../../js/util.js') +require('../../node_modules/mq4-hover-shim/dist/browser/mq4-hover-shim.js') require('../../js/alert.js') require('../../js/button.js') require('../../js/carousel.js') require('../../js/collapse.js') require('../../js/dropdown.js') require('../../js/modal.js') +require('../../js/scrollspy.js') require('../../js/tooltip.js') require('../../js/popover.js') -require('../../js/scrollspy.js') -require('../../js/tab.js') -require('../../js/affix.js')
\ No newline at end of file +require('../../js/tab.js')
\ No newline at end of file |
