|  |  |  | @ -5,13 +5,17 @@ | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |   // 如果未定义jQuery,则抛出错误
 | 
			
		
	
		
			
				
					|  |  |  |  |   throw new Error('Bootstrap\'s JavaScript requires jQuery') | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | +function ($) { | 
			
		
	
		
			
				
					|  |  |  |  |   // 使用严格模式
 | 
			
		
	
		
			
				
					|  |  |  |  |   'use strict'; | 
			
		
	
		
			
				
					|  |  |  |  |   var version = $.fn.jquery.split(' ')[0].split('.') | 
			
		
	
		
			
				
					|  |  |  |  |   // 获取jQuery版本号并分割成数组
 | 
			
		
	
		
			
				
					|  |  |  |  |   if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { | 
			
		
	
		
			
				
					|  |  |  |  |     // 检查jQuery版本是否在1.9.1以上但低于4之间
 | 
			
		
	
		
			
				
					|  |  |  |  |     throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | }(jQuery); | 
			
		
	
	
		
			
				
					|  |  |  | @ -32,6 +36,8 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |   // ============================================================
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   function transitionEnd() { | 
			
		
	
		
			
				
					|  |  |  |  |     // 创建一个临时元素用于检测CSS过渡支持
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     var el = document.createElement('bootstrap') | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     var transEndEventNames = { | 
			
		
	
	
		
			
				
					|  |  |  | @ -40,14 +46,16 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |       OTransition      : 'oTransitionEnd otransitionend', | 
			
		
	
		
			
				
					|  |  |  |  |       transition       : 'transitionend' | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 定义不同浏览器的过渡结束事件名称
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (var name in transEndEventNames) { | 
			
		
	
		
			
				
					|  |  |  |  |       if (el.style[name] !== undefined) { | 
			
		
	
		
			
				
					|  |  |  |  |         return { end: transEndEventNames[name] } | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果找到支持的过渡结束事件,返回对应的事件名称
 | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     return false // explicit for ie8 (  ._.)
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 对于不支持过渡的浏览器,显式返回false
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // http://blog.alexmaccaw.com/css-transitions
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -55,23 +63,30 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |     var called = false | 
			
		
	
		
			
				
					|  |  |  |  |     var $el = this | 
			
		
	
		
			
				
					|  |  |  |  |     $(this).one('bsTransitionEnd', function () { called = true }) | 
			
		
	
		
			
				
					|  |  |  |  |     // 绑定一次性事件,当过渡结束时设置called为true
 | 
			
		
	
		
			
				
					|  |  |  |  |     var callback = function () { if (!called) $($el).trigger($.support.transition.end) } | 
			
		
	
		
			
				
					|  |  |  |  |     // 定义回调函数,如果called为false,触发过渡结束事件
 | 
			
		
	
		
			
				
					|  |  |  |  |     setTimeout(callback, duration) | 
			
		
	
		
			
				
					|  |  |  |  |     // 设置定时器,在指定持续时间后执行回调函数
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   $(function () { | 
			
		
	
		
			
				
					|  |  |  |  |     $.support.transition = transitionEnd() | 
			
		
	
		
			
				
					|  |  |  |  | // 检测并设置CSS过渡支持情况
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     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) | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果事件目标与当前元素匹配,调用处理函数
 | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     // 定义自定义事件bsTransitionEnd,用于处理过渡结束事件
 | 
			
		
	
		
			
				
					|  |  |  |  |   }) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | }(jQuery); | 
			
		
	
	
		
			
				
					|  |  |  | @ -94,38 +109,42 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |   var dismiss = '[data-dismiss="alert"]' | 
			
		
	
		
			
				
					|  |  |  |  |   var Alert   = function (el) { | 
			
		
	
		
			
				
					|  |  |  |  |     $(el).on('click', dismiss, this.close) | 
			
		
	
		
			
				
					|  |  |  |  |     // 绑定点击事件,当点击带有data-dismiss属性的元素时,调用close方法
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Alert.VERSION = '3.3.7' | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 定义Alert类的版本号
 | 
			
		
	
		
			
				
					|  |  |  |  |   Alert.TRANSITION_DURATION = 150 | 
			
		
	
		
			
				
					|  |  |  |  |   // 定义过渡动画的持续时间为150毫秒
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Alert.prototype.close = function (e) { | 
			
		
	
		
			
				
					|  |  |  |  |     var $this    = $(this) | 
			
		
	
		
			
				
					|  |  |  |  |     var selector = $this.attr('data-target') | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 获取data-target属性的值作为选择器
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (!selector) { | 
			
		
	
		
			
				
					|  |  |  |  |       selector = $this.attr('href') | 
			
		
	
		
			
				
					|  |  |  |  |       selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // 如果data-target不存在,则获取href属性的值作为选择器,并去除URL中的其他部分以兼容IE7
 | 
			
		
	
		
			
				
					|  |  |  |  |     var $parent = $(selector === '#' ? [] : selector) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // 根据选择器获取父元素,如果选择器为#,则返回空数组
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (e) e.preventDefault() | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // 如果存在事件对象,阻止默认行为
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (!$parent.length) { | 
			
		
	
		
			
				
					|  |  |  |  |       $parent = $this.closest('.alert') | 
			
		
	
		
			
				
					|  |  |  |  |       // 如果父元素不存在,尝试查找最近的祖先元素
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     $parent.trigger(e = $.Event('close.bs.alert')) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (e.isDefaultPrevented()) return | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 如果事件被阻止,则返回
 | 
			
		
	
		
			
				
					|  |  |  |  |     $parent.removeClass('in') | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 移除父元素的'in'类,表示隐藏元素
 | 
			
		
	
		
			
				
					|  |  |  |  |     function removeElement() { | 
			
		
	
		
			
				
					|  |  |  |  |       // detach from parent, fire event then clean up data
 | 
			
		
	
		
			
				
					|  |  |  |  |       $parent.detach().trigger('closed.bs.alert').remove() | 
			
		
	
		
			
				
					|  |  |  |  |       // 从父元素中分离,触发关闭事件,然后移除元素及其数据
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     $.support.transition && $parent.hasClass('fade') ? | 
			
		
	
	
		
			
				
					|  |  |  | @ -133,6 +152,7 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |         .one('bsTransitionEnd', removeElement) | 
			
		
	
		
			
				
					|  |  |  |  |         .emulateTransitionEnd(Alert.TRANSITION_DURATION) : | 
			
		
	
		
			
				
					|  |  |  |  |       removeElement() | 
			
		
	
		
			
				
					|  |  |  |  |     // 如果支持过渡且父元素有'fade'类,则在过渡结束后移除元素;否则立即移除元素
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -140,34 +160,36 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |   // =======================
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   function Plugin(option) { | 
			
		
	
		
			
				
					|  |  |  |  |     // 遍历每一个匹配的元素,并执行回调函数
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this.each(function () { | 
			
		
	
		
			
				
					|  |  |  |  |       var $this = $(this) | 
			
		
	
		
			
				
					|  |  |  |  |       var data  = $this.data('bs.alert') | 
			
		
	
		
			
				
					|  |  |  |  |       var $this = $(this); // 将当前元素包装成jQuery对象
 | 
			
		
	
		
			
				
					|  |  |  |  |       var data  = $this.data('bs.'); // 获取元素的'bs.'数据
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (!data) $this.data('bs.alert', (data = new Alert(this))) | 
			
		
	
		
			
				
					|  |  |  |  |       if (typeof option == 'string') data[option].call($this) | 
			
		
	
		
			
				
					|  |  |  |  |     }) | 
			
		
	
		
			
				
					|  |  |  |  |       // 如果元素没有'bs.'数据,则创建一个新的Alert实例并存储在'bs.'数据中
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (!data) $this.data('bs.', (data = new Alert(this))); | 
			
		
	
		
			
				
					|  |  |  |  |       // 如果传入的option是字符串,则调用对应的方法
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (typeof option == 'string') data[option].call($this); | 
			
		
	
		
			
				
					|  |  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   var old = $.fn.alert | 
			
		
	
		
			
				
					|  |  |  |  |   var old = $.fn.button// 保存旧的插件定义
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.alert             = Plugin | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.alert.Constructor = Alert | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.button             = Plugin// 将Plugin函数赋值给jQuery的fn属性
 | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.button.Constructor = Button// 将Alert构造函数赋值给jQuery的fn属性的Constructor属性
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // ALERT NO CONFLICT
 | 
			
		
	
		
			
				
					|  |  |  |  | // =================
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // ALERT NO CONFLICT
 | 
			
		
	
		
			
				
					|  |  |  |  |   // =================
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.alert.noConflict = function () { | 
			
		
	
		
			
				
					|  |  |  |  |     $.fn.alert = old | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.button.noConflict = function () { | 
			
		
	
		
			
				
					|  |  |  |  |     $.fn.button = old | 
			
		
	
		
			
				
					|  |  |  |  |     return this | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // ALERT DATA-API
 | 
			
		
	
		
			
				
					|  |  |  |  |   // ==============
 | 
			
		
	
		
			
				
					|  |  |  |  | // ALERT DATA-API
 | 
			
		
	
		
			
				
					|  |  |  |  | // ==============
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) | 
			
		
	
		
			
				
					|  |  |  |  |   $(document).on('click.bs..data-api', dismiss, Alert.prototype.close); // 为文档绑定点击事件,当点击dismiss时,调用Alert原型的close方法
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | }(jQuery); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -179,7 +201,6 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 | 
			
		
	
		
			
				
					|  |  |  |  |  * ======================================================================== */ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | +function ($) { | 
			
		
	
		
			
				
					|  |  |  |  |   'use strict'; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -187,115 +208,122 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  |   // ==============================
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   var Button = function (element, options) { | 
			
		
	
		
			
				
					|  |  |  |  |     this.$element  = $(element) | 
			
		
	
		
			
				
					|  |  |  |  |     this.options   = $.extend({}, Button.DEFAULTS, options) | 
			
		
	
		
			
				
					|  |  |  |  |     this.isLoading = false | 
			
		
	
		
			
				
					|  |  |  |  |     this.$element  = $(element); // 将DOM元素包装成jQuery对象
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.options   = $.extend({}, Button.DEFAULTS, options); // 合并默认选项和用户选项
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.isLoading = false; // 初始化加载状态为false
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Button.VERSION  = '3.3.7' | 
			
		
	
		
			
				
					|  |  |  |  |   Button.VERSION  = '3.3.7'; // 设置版本号
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Button.DEFAULTS = { | 
			
		
	
		
			
				
					|  |  |  |  |     loadingText: 'loading...' | 
			
		
	
		
			
				
					|  |  |  |  |     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() | 
			
		
	
		
			
				
					|  |  |  |  |     var d    = 'disabled'; // 禁用状态的CSS类名
 | 
			
		
	
		
			
				
					|  |  |  |  |     var $el  = this.$element; // 按钮的jQuery对象
 | 
			
		
	
		
			
				
					|  |  |  |  |     var val  = $el.is('input') ? 'val' : 'html'; // 根据元素类型选择使用val或html方法
 | 
			
		
	
		
			
				
					|  |  |  |  |     var data = $el.data(); // 获取元素的数据
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     state += 'Text' | 
			
		
	
		
			
				
					|  |  |  |  |     state += 'Text'; // 拼接状态文本后缀
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (data.resetText == null) $el.data('resetText', $el[val]()) | 
			
		
	
		
			
				
					|  |  |  |  |     // 如果resetText数据不存在,则保存当前值到resetText数据中
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (data.resetText == null) $el.data('resetText', $el[val]()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // push to event loop to allow forms to submit
 | 
			
		
	
		
			
				
					|  |  |  |  |     setTimeout($.proxy(function () { | 
			
		
	
		
			
				
					|  |  |  |  |       $el[val](data[state] == null ? this.options[state] : data[state]) | 
			
		
	
		
			
				
					|  |  |  |  |       // 设置按钮文本或HTML内容
 | 
			
		
	
		
			
				
					|  |  |  |  |       $el[val](data[state] == null ? this.options[state] : data[state]); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       // 如果状态是loadingText,则设置加载状态和禁用样式
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (state == 'loadingText') { | 
			
		
	
		
			
				
					|  |  |  |  |         this.isLoading = true | 
			
		
	
		
			
				
					|  |  |  |  |         $el.addClass(d).attr(d, d).prop(d, true) | 
			
		
	
		
			
				
					|  |  |  |  |         this.isLoading = true; | 
			
		
	
		
			
				
					|  |  |  |  |         $el.addClass(d).attr(d, d).prop(d, true); | 
			
		
	
		
			
				
					|  |  |  |  |       } else if (this.isLoading) { | 
			
		
	
		
			
				
					|  |  |  |  |         this.isLoading = false | 
			
		
	
		
			
				
					|  |  |  |  |         $el.removeClass(d).removeAttr(d).prop(d, false) | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果当前状态不是loadingText且之前是加载状态,则取消加载状态和禁用样式
 | 
			
		
	
		
			
				
					|  |  |  |  |         this.isLoading = false; | 
			
		
	
		
			
				
					|  |  |  |  |         $el.removeClass(d).removeAttr(d).prop(d, false); | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  |     }, this), 0) | 
			
		
	
		
			
				
					|  |  |  |  |     }, this), 0); | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Button.prototype.toggle = function () { | 
			
		
	
		
			
				
					|  |  |  |  |     var changed = true | 
			
		
	
		
			
				
					|  |  |  |  |     var $parent = this.$element.closest('[data-toggle="buttons"]') | 
			
		
	
		
			
				
					|  |  |  |  |     var changed = true; // 标记状态是否改变
 | 
			
		
	
		
			
				
					|  |  |  |  |     var $parent = this.$element.closest('[data-toggle="buttons"]'); // 查找最近的父级按钮组容器
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if ($parent.length) { | 
			
		
	
		
			
				
					|  |  |  |  |       var $input = this.$element.find('input') | 
			
		
	
		
			
				
					|  |  |  |  |       var $input = this.$element.find('input'); // 查找按钮内的输入元素
 | 
			
		
	
		
			
				
					|  |  |  |  |       if ($input.prop('type') == 'radio') { | 
			
		
	
		
			
				
					|  |  |  |  |         if ($input.prop('checked')) changed = false | 
			
		
	
		
			
				
					|  |  |  |  |         $parent.find('.active').removeClass('active') | 
			
		
	
		
			
				
					|  |  |  |  |         this.$element.addClass('active') | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果输入类型是单选按钮且已选中,则不改变状态
 | 
			
		
	
		
			
				
					|  |  |  |  |         if ($input.prop('checked')) changed = false; | 
			
		
	
		
			
				
					|  |  |  |  |         $parent.find('.active').removeClass('active'); // 移除其他按钮的激活状态
 | 
			
		
	
		
			
				
					|  |  |  |  |         this.$element.addClass('active'); // 设置当前按钮为激活状态
 | 
			
		
	
		
			
				
					|  |  |  |  |       } else if ($input.prop('type') == 'checkbox') { | 
			
		
	
		
			
				
					|  |  |  |  |         if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false | 
			
		
	
		
			
				
					|  |  |  |  |         this.$element.toggleClass('active') | 
			
		
	
		
			
				
					|  |  |  |  |         // 如果输入类型是复选框且状态与激活状态不一致,则不改变状态
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false; | 
			
		
	
		
			
				
					|  |  |  |  |         this.$element.toggleClass('active'); // 切换当前按钮的激活状态
 | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  |       $input.prop('checked', this.$element.hasClass('active')) | 
			
		
	
		
			
				
					|  |  |  |  |       if (changed) $input.trigger('change') | 
			
		
	
		
			
				
					|  |  |  |  |       $input.prop('checked', this.$element.hasClass('active')); // 同步输入元素的选中状态
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (changed) $input.trigger('change'); // 如果状态改变,触发change事件
 | 
			
		
	
		
			
				
					|  |  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |  |       this.$element.attr('aria-pressed', !this.$element.hasClass('active')) | 
			
		
	
		
			
				
					|  |  |  |  |       this.$element.toggleClass('active') | 
			
		
	
		
			
				
					|  |  |  |  |       // 如果按钮不在按钮组内,直接切换aria-pressed属性和激活状态
 | 
			
		
	
		
			
				
					|  |  |  |  |       this.$element.attr('aria-pressed', !this.$element.hasClass('active')); | 
			
		
	
		
			
				
					|  |  |  |  |       this.$element.toggleClass('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 | 
			
		
	
		
			
				
					|  |  |  |  |       var $this   = $(this); // 将当前元素包装成jQuery对象
 | 
			
		
	
		
			
				
					|  |  |  |  |       var data    = $this.data('bs.button'); // 获取元素的bs.button数据
 | 
			
		
	
		
			
				
					|  |  |  |  |       var options = typeof option == 'object' && option; // 如果option是对象,则赋值给options变量
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (!data) $this.data('bs.button', (data = new Button(this, options))) | 
			
		
	
		
			
				
					|  |  |  |  |       // 如果元素没有bs.button数据,则创建新的Button实例并存储在bs.button数据中
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (!data) $this.data('bs.button', (data = new Button(this, options))); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (option == 'toggle') data.toggle() | 
			
		
	
		
			
				
					|  |  |  |  |       else if (option) data.setState(option) | 
			
		
	
		
			
				
					|  |  |  |  |     }) | 
			
		
	
		
			
				
					|  |  |  |  |       // 如果option是toggle,则调用toggle方法;否则如果option存在,则调用setState方法
 | 
			
		
	
		
			
				
					|  |  |  |  |       if (option == 'toggle') data.toggle(); | 
			
		
	
		
			
				
					|  |  |  |  |       else if (option) data.setState(option); | 
			
		
	
		
			
				
					|  |  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   var old = $.fn.button | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.button             = Plugin | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.button.Constructor = Button | 
			
		
	
		
			
				
					|  |  |  |  |   var old = $.fn.button; // 保存旧的按钮插件定义
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.button             = Plugin; // 将Plugin函数赋值给jQuery的fn属性的button方法
 | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.button.Constructor = Button; // 将Button构造函数赋值给jQuery的fn属性的button方法的Constructor属性
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // BUTTON NO CONFLICT
 | 
			
		
	
		
			
				
					|  |  |  |  |   // ==================
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   $.fn.button.noConflict = function () { | 
			
		
	
		
			
				
					|  |  |  |  |     $.fn.button = old | 
			
		
	
		
			
				
					|  |  |  |  |     return this | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     $.fn.button = old; // 恢复旧的按钮插件定义
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this; // 返回当前对象以支持链式调用
 | 
			
		
	
		
			
				
					|  |  |  |  |   }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // BUTTON DATA-API
 | 
			
		
	
		
			
				
					|  |  |  |  |   // ===============
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   $(document) | 
			
		
	
		
			
				
					|  |  |  |  |     .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { | 
			
		
	
		
			
				
					|  |  |  |  |       var $btn = $(e.target).closest('.btn') | 
			
		
	
		
			
				
					|  |  |  |  |       Plugin.call($btn, 'toggle') | 
			
		
	
		
			
				
					|  |  |  |  |       if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { | 
			
		
	
		
			
				
					|  |  |  |  |         // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
 | 
			
		
	
		
			
				
					|  |  |  |  |         e.preventDefault() | 
			
		
	
		
			
				
					|  |  |  |  |         // The target component still receive the focus
 | 
			
		
	
		
			
				
					|  |  |  |  |         if ($btn.is('input,button')) $btn.trigger('focus') | 
			
		
	
		
			
				
					|  |  |  |  |         else $btn.find('input:visible,button:visible').first().trigger('focus') | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  |     }) | 
			
		
	
		
			
				
					|  |  |  |  |     .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)) | 
			
		
	
		
			
				
					|  |  |  |  |     }) | 
			
		
	
		
			
				
					|  |  |  |  |       .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { | 
			
		
	
		
			
				
					|  |  |  |  |         var $btn = $(e.target).closest('.btn'); // 查找点击目标最近的按钮元素
 | 
			
		
	
		
			
				
					|  |  |  |  |         Plugin.call($btn, 'toggle'); // 调用Plugin的toggle方法
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { | 
			
		
	
		
			
				
					|  |  |  |  |           // 如果点击的不是单选按钮或复选框,则阻止默认行为(防止双击)
 | 
			
		
	
		
			
				
					|  |  |  |  |           e.preventDefault(); | 
			
		
	
		
			
				
					|  |  |  |  |           // 如果目标组件是按钮或输入元素,则触发焦点事件
 | 
			
		
	
		
			
				
					|  |  |  |  |           if ($btn.is('input,button')) $btn.trigger('focus'); | 
			
		
	
		
			
				
					|  |  |  |  |           else $btn.find('input:visible,button:visible').first().trigger('focus'); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |       }) | 
			
		
	
		
			
				
					|  |  |  |  |       .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)); | 
			
		
	
		
			
				
					|  |  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |  | }(jQuery); // 立即执行函数,传入jQuery对象作为参数,确保代码在jQuery加载后执行。
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | }(jQuery); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /* ======================================================================== | 
			
		
	
		
			
				
					|  |  |  |  |  * Bootstrap: carousel.js v3.3.7 | 
			
		
	
	
		
			
				
					|  |  |  | @ -307,168 +335,182 @@ if (typeof jQuery === 'undefined') { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | +function ($) { | 
			
		
	
		
			
				
					|  |  |  |  |   'use strict'; | 
			
		
	
		
			
				
					|  |  |  |  |   'use strict'; // 使用严格模式,避免一些常见的错误
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // CAROUSEL CLASS DEFINITION
 | 
			
		
	
		
			
				
					|  |  |  |  |   // =========================
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   var Carousel = function (element, options) { | 
			
		
	
		
			
				
					|  |  |  |  |     this.$element    = $(element) | 
			
		
	
		
			
				
					|  |  |  |  |     this.$indicators = this.$element.find('.carousel-indicators') | 
			
		
	
		
			
				
					|  |  |  |  |     this.options     = options | 
			
		
	
		
			
				
					|  |  |  |  |     this.paused      = null | 
			
		
	
		
			
				
					|  |  |  |  |     this.sliding     = null | 
			
		
	
		
			
				
					|  |  |  |  |     this.interval    = null | 
			
		
	
		
			
				
					|  |  |  |  |     this.$active     = null | 
			
		
	
		
			
				
					|  |  |  |  |     this.$items      = null | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.$element    = $(element) // 将传入的元素转换为jQuery对象
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.$indicators = this.$element.find('.carousel-indicators') // 查找轮播图的指示器元素
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.options     = options // 保存传入的选项参数
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.paused      = null // 初始化暂停状态为null
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.sliding     = null // 初始化滑动状态为null
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.interval    = null // 初始化定时器为null
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.$active     = null // 初始化当前活动项为null
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.$items      = null // 初始化所有项目为null
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 如果选项中启用了键盘控制,绑定键盘事件处理函数
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 如果选项中设置了鼠标悬停暂停,并且设备不支持触摸事件,绑定鼠标进入和离开事件处理函数
 | 
			
		
	
		
			
				
					|  |  |  |  |     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)) | 
			
		
	
		
			
				
					|  |  |  |  |         .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) | 
			
		
	
		
			
				
					|  |  |  |  |         .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.VERSION  = '3.3.7' | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.VERSION  = '3.3.7' // 定义轮播组件的版本号
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.TRANSITION_DURATION = 600 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.TRANSITION_DURATION = 600 // 定义过渡动画的持续时间
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.DEFAULTS = { | 
			
		
	
		
			
				
					|  |  |  |  |     interval: 5000, | 
			
		
	
		
			
				
					|  |  |  |  |     pause: 'hover', | 
			
		
	
		
			
				
					|  |  |  |  |     wrap: true, | 
			
		
	
		
			
				
					|  |  |  |  |     keyboard: true | 
			
		
	
		
			
				
					|  |  |  |  |     interval: 5000, // 默认自动播放间隔时间为5秒
 | 
			
		
	
		
			
				
					|  |  |  |  |     pause: 'hover', // 默认在鼠标悬停时暂停
 | 
			
		
	
		
			
				
					|  |  |  |  |     wrap: true, // 默认支持循环播放
 | 
			
		
	
		
			
				
					|  |  |  |  |     keyboard: true // 默认启用键盘控制
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 键盘事件处理函数
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.prototype.keydown = function (e) { | 
			
		
	
		
			
				
					|  |  |  |  |     if (/input|textarea/i.test(e.target.tagName)) return | 
			
		
	
		
			
				
					|  |  |  |  |     if (/input|textarea/i.test(e.target.tagName)) return // 如果焦点在输入框或文本区域,不处理键盘事件
 | 
			
		
	
		
			
				
					|  |  |  |  |     switch (e.which) { | 
			
		
	
		
			
				
					|  |  |  |  |       case 37: this.prev(); break | 
			
		
	
		
			
				
					|  |  |  |  |       case 39: this.next(); break | 
			
		
	
		
			
				
					|  |  |  |  |       default: return | 
			
		
	
		
			
				
					|  |  |  |  |       case 37: this.prev(); break // 左箭头键切换到上一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |       case 39: this.next(); break // 右箭头键切换到下一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |       default: return // 其他按键不处理
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     e.preventDefault() | 
			
		
	
		
			
				
					|  |  |  |  |     e.preventDefault() // 阻止默认行为
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 开始自动播放
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.prototype.cycle = function (e) { | 
			
		
	
		
			
				
					|  |  |  |  |     e || (this.paused = false) | 
			
		
	
		
			
				
					|  |  |  |  |     e || (this.paused = false) // 如果没有传入事件对象,设置暂停状态为false
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.interval && clearInterval(this.interval) | 
			
		
	
		
			
				
					|  |  |  |  |     this.interval && clearInterval(this.interval) // 清除之前的定时器
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.options.interval | 
			
		
	
		
			
				
					|  |  |  |  |       && !this.paused | 
			
		
	
		
			
				
					|  |  |  |  |       && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) | 
			
		
	
		
			
				
					|  |  |  |  |     && !this.paused | 
			
		
	
		
			
				
					|  |  |  |  |     && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) // 根据选项中的间隔时间设置新的定时器
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this | 
			
		
	
		
			
				
					|  |  |  |  |     return this // 返回当前实例以支持链式调用
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 获取项目的索引
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.prototype.getItemIndex = function (item) { | 
			
		
	
		
			
				
					|  |  |  |  |     this.$items = item.parent().children('.item') | 
			
		
	
		
			
				
					|  |  |  |  |     return this.$items.index(item || this.$active) | 
			
		
	
		
			
				
					|  |  |  |  |     this.$items = item.parent().children('.item') // 获取所有项目
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this.$items.index(item || this.$active) // 返回指定项目的索引,如果未指定则返回当前活动的项目索引
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 根据方向获取下一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |   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) | 
			
		
	
		
			
				
					|  |  |  |  |     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) // 返回下一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 切换到指定位置的项目
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.prototype.to = function (pos) { | 
			
		
	
		
			
				
					|  |  |  |  |     var that        = this | 
			
		
	
		
			
				
					|  |  |  |  |     var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (pos > (this.$items.length - 1) || pos < 0) return | 
			
		
	
		
			
				
					|  |  |  |  |     var that        = this // 保存当前实例的引用
 | 
			
		
	
		
			
				
					|  |  |  |  |     var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) // 获取当前活动的项目索引并更新活动项目
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (activeIndex == pos) return this.pause().cycle() | 
			
		
	
		
			
				
					|  |  |  |  |     if (pos > (this.$items.length - 1) || pos < 0) return // 如果指定的位置超出范围,直接返回
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // 如果正在滑动,等待滑动完成后再切换到指定位置
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (activeIndex == pos) return this.pause().cycle() // 如果已经是指定位置,暂停并重新开始自动播放
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) | 
			
		
	
		
			
				
					|  |  |  |  |     return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) // 根据位置关系切换到指定位置的项目
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 暂停自动播放
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.prototype.pause = function (e) { | 
			
		
	
		
			
				
					|  |  |  |  |     e || (this.paused = true) | 
			
		
	
		
			
				
					|  |  |  |  |     e || (this.paused = true) // 如果没有传入事件对象,设置暂停状态为true
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (this.$element.find('.next, .prev').length && $.support.transition) { | 
			
		
	
		
			
				
					|  |  |  |  |       this.$element.trigger($.support.transition.end) | 
			
		
	
		
			
				
					|  |  |  |  |       this.cycle(true) | 
			
		
	
		
			
				
					|  |  |  |  |       this.$element.trigger($.support.transition.end) // 如果支持CSS3过渡效果,触发过渡结束事件
 | 
			
		
	
		
			
				
					|  |  |  |  |       this.cycle(true) // 重新开始自动播放
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.interval = clearInterval(this.interval) | 
			
		
	
		
			
				
					|  |  |  |  |     this.interval = clearInterval(this.interval) // 清除定时器
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this | 
			
		
	
		
			
				
					|  |  |  |  |     return this // 返回当前实例以支持链式调用
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 切换到下一个或上一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.prototype.next = function () { | 
			
		
	
		
			
				
					|  |  |  |  |     if (this.sliding) return | 
			
		
	
		
			
				
					|  |  |  |  |     return this.slide('next') | 
			
		
	
		
			
				
					|  |  |  |  |     if (this.sliding) return // 如果正在滑动,直接返回
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this.slide('next') // 切换到下一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 切换到上一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.prototype.prev = function () { | 
			
		
	
		
			
				
					|  |  |  |  |     if (this.sliding) return | 
			
		
	
		
			
				
					|  |  |  |  |     return this.slide('prev') | 
			
		
	
		
			
				
					|  |  |  |  |     if (this.sliding) return // 如果正在滑动,直接返回
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this.slide('prev') // 切换到上一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // 执行滑动操作
 | 
			
		
	
		
			
				
					|  |  |  |  |   Carousel.prototype.slide = function (type, next) { | 
			
		
	
		
			
				
					|  |  |  |  |     var $active   = this.$element.find('.item.active') | 
			
		
	
		
			
				
					|  |  |  |  |     var $next     = next || this.getItemForDirection(type, $active) | 
			
		
	
		
			
				
					|  |  |  |  |     var isCycling = this.interval | 
			
		
	
		
			
				
					|  |  |  |  |     var direction = type == 'next' ? 'left' : 'right' | 
			
		
	
		
			
				
					|  |  |  |  |     var that      = this | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if ($next.hasClass('active')) return (this.sliding = false) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     var relatedTarget = $next[0] | 
			
		
	
		
			
				
					|  |  |  |  |     var slideEvent = $.Event('slide.bs.carousel', { | 
			
		
	
		
			
				
					|  |  |  |  |       relatedTarget: relatedTarget, | 
			
		
	
		
			
				
					|  |  |  |  |       direction: direction | 
			
		
	
		
			
				
					|  |  |  |  |     var $active   = this.$element.find('.item.active') // 获取当前活动的项目
 | 
			
		
	
		
			
				
					|  |  |  |  |     var $next     = next || this.getItemForDirection(type, $active) // 获取下一个项目,如果没有指定则根据方向获取
 | 
			
		
	
		
			
				
					|  |  |  |  |     var isCycling = this.interval // 检查是否正在自动播放
 | 
			
		
	
		
			
				
					|  |  |  |  |     var direction = type == 'next' ? 'left' : 'right' // 根据类型确定滑动方向
 | 
			
		
	
		
			
				
					|  |  |  |  |     var that      = this // 保存当前实例的引用
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if ($next.hasClass('active')) return (this.sliding = false) // 如果下一个项目已经是活动状态,直接返回
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     var slideEvent = $.Event('slide.bs.carousel', { // 创建滑动事件对象
 | 
			
		
	
		
			
				
					|  |  |  |  |       relatedTarget: $next[0], // 设置相关目标为下一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |       direction: direction // 设置滑动方向
 | 
			
		
	
		
			
				
					|  |  |  |  |     }) | 
			
		
	
		
			
				
					|  |  |  |  |     this.$element.trigger(slideEvent) | 
			
		
	
		
			
				
					|  |  |  |  |     if (slideEvent.isDefaultPrevented()) return | 
			
		
	
		
			
				
					|  |  |  |  |     this.$element.trigger(slideEvent) // 触发滑动事件
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (slideEvent.isDefaultPrevented()) return // 如果事件被阻止,直接返回
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     this.sliding = true | 
			
		
	
		
			
				
					|  |  |  |  |     this.sliding = true // 设置滑动状态为true
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     isCycling && this.pause() | 
			
		
	
		
			
				
					|  |  |  |  |     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') | 
			
		
	
		
			
				
					|  |  |  |  |     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) | 
			
		
	
		
			
				
					|  |  |  |  |     var slidEvent = $.Event('slid.bs.carousel', { // 创建已滑动事件对象
 | 
			
		
	
		
			
				
					|  |  |  |  |       relatedTarget: $next[0], // 设置相关目标为下一个项目
 | 
			
		
	
		
			
				
					|  |  |  |  |       direction: direction // 设置滑动方向
 | 
			
		
	
		
			
				
					|  |  |  |  |     }) // yes, "slid"
 | 
			
		
	
		
			
				
					|  |  |  |  |     if ($.support.transition && this.$element.hasClass('slide')) { // 如果支持CSS3过渡效果且轮播图元素具有slide类名
 | 
			
		
	
		
			
				
					|  |  |  |  |       $next.addClass(type) // 添加滑动类型类名(next或prev)
 | 
			
		
	
		
			
				
					|  |  |  |  |       $next[0].offsetWidth // 强制浏览器重新计算元素的宽度和高度,以触发重绘和过渡效果
 | 
			
		
	
		
			
				
					|  |  |  |  |       $active.addClass(direction) // 添加滑动方向类名(left或right)
 | 
			
		
	
		
			
				
					|  |  |  |  |       $next.addClass(direction) // 添加滑动方向类名(left或right)
 | 
			
		
	
		
			
				
					|  |  |  |  |       $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) | 
			
		
	
		
			
				
					|  |  |  |  |           .one('bsTransitionEnd', function () { // 监听过渡结束事件
 | 
			
		
	
		
			
				
					|  |  |  |  |             $next.removeClass([type, direction].join(' ')).addClass('active') // 移除滑动类型和方向类名,添加激活状态
 | 
			
		
	
		
			
				
					|  |  |  |  |             $active.removeClass(['active', direction].join(' ')) // 移除激活状态和方向类名
 | 
			
		
	
		
			
				
					|  |  |  |  |             that.sliding = false // 设置滑动状态为false
 | 
			
		
	
		
			
				
					|  |  |  |  |             setTimeout(function () { // 延迟触发已滑动事件,以确保过渡效果完成
 | 
			
		
	
		
			
				
					|  |  |  |  |               that.$element.trigger(slidEvent) // 触发已滑动事件
 | 
			
		
	
		
			
				
					|  |  |  |  |             }, 0) | 
			
		
	
		
			
				
					|  |  |  |  |           }) | 
			
		
	
		
			
				
					|  |  |  |  |           .emulateTransitionEnd(Carousel.TRANSITION_DURATION) // 模拟过渡结束事件,以触发过渡效果
 | 
			
		
	
		
			
				
					|  |  |  |  |     } else { // 如果不支持CSS3过渡效果或轮播图元素没有slide类名
 | 
			
		
	
		
			
				
					|  |  |  |  |       $active.removeClass('active') // 移除当前活动项目的激活状态
 | 
			
		
	
		
			
				
					|  |  |  |  |       $next.addClass('active') // 添加下一个项目的激活状态
 | 
			
		
	
		
			
				
					|  |  |  |  |       this.sliding = false // 设置滑动状态为false
 | 
			
		
	
		
			
				
					|  |  |  |  |       this.$element.trigger(slidEvent) // 触发已滑动事件
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     isCycling && this.cycle() | 
			
		
	
		
			
				
					|  |  |  |  |     isCycling && this.cycle() // 如果正在自动播放,重新开始自动播放
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     return this | 
			
		
	
		
			
				
					|  |  |  |  |     return this // 返回当前实例以支持链式调用
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // CAROUSEL PLUGIN DEFINITION
 | 
			
		
	
		
			
				
					|  |  |  |  |   // ==========================
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |