authpartner

Clone or download

Modified Files

M js/bootstrap.js
+48 −53
/*!
/*!
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under the MIT license
* Licensed under the MIT license
*/
*/
if (typeof jQuery === 'undefined') {
if (typeof jQuery === 'undefined') {
throw new Error('Bootstrap\'s JavaScript requires jQuery')
throw new Error('Bootstrap\'s JavaScript requires jQuery')
}
}
+function ($) {
+function ($) {
'use strict';
'use strict';
var version = $.fn.jquery.split(' ')[0].split('.')
var version = $.fn.jquery.split(' ')[0].split('.')
if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
if ((version[0] < 2 && version[1] < 9) || (version[0] === 1 && version[1] === 9 && version[2] < 1) || (version[0] > 3)) {
throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
}
}
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: transition.js v3.3.7
* Bootstrap: transition.js v3.3.7
* http://getbootstrap.com/javascript/#transitions
* http://getbootstrap.com/javascript/#transitions
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
// ============================================================
// ============================================================
function transitionEnd() {
function transitionEnd() {
var el = document.createElement('bootstrap')
var el = document.createElement('bootstrap')
var transEndEventNames = {
var transEndEventNames = {
WebkitTransition : 'webkitTransitionEnd',
WebkitTransition : 'webkitTransitionEnd',
MozTransition : 'transitionend',
MozTransition : 'transitionend',
OTransition : 'oTransitionEnd otransitionend',
OTransition : 'oTransitionEnd otransitionend',
transition : 'transitionend'
transition : 'transitionend'
}
}
for (var name in transEndEventNames) {
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
if (el.style[name] !== undefined) {
return { end: transEndEventNames[name] }
return { end: transEndEventNames[name] }
}
}
}
}
return false // explicit for ie8 ( ._.)
return false // explicit for ie8 ( ._.)
}
}
// http://blog.alexmaccaw.com/css-transitions
// http://blog.alexmaccaw.com/css-transitions
$.fn.emulateTransitionEnd = function (duration) {
$.fn.emulateTransitionEnd = function (duration) {
var called = false
var called = false
var $el = this
var $el = this
$(this).one('bsTransitionEnd', function () { called = true })
$(this).one('bsTransitionEnd', function () { called = true })
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
setTimeout(callback, duration)
setTimeout(callback, duration)
return this
return this
}
}
$(function () {
$(function () {
$.support.transition = transitionEnd()
$.support.transition = transitionEnd()
if (!$.support.transition) return
if (!$.support.transition) return
$.event.special.bsTransitionEnd = {
$.event.special.bsTransitionEnd = {
bindType: $.support.transition.end,
bindType: $.support.transition.end,
delegateType: $.support.transition.end,
delegateType: $.support.transition.end,
handle: function (e) {
handle: function (e) {
if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
}
}
}
}
})
})
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: alert.js v3.3.7
* Bootstrap: alert.js v3.3.7
* http://getbootstrap.com/javascript/#alerts
* http://getbootstrap.com/javascript/#alerts
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// ALERT CLASS DEFINITION
// ALERT CLASS DEFINITION
// ======================
// ======================
var dismiss = '[data-dismiss="alert"]'
var dismiss = '[data-dismiss="alert"]'
var Alert = function (el) {
var Alert = function (el) {
$(el).on('click', dismiss, this.close)
$(el).on('click', dismiss, this.close)
}
}
Alert.VERSION = '3.3.7'
Alert.VERSION = '3.3.7'
Alert.TRANSITION_DURATION = 150
Alert.TRANSITION_DURATION = 150
Alert.prototype.close = function (e) {
Alert.prototype.close = function (e) {
var $this = $(this)
var $this = $(this)
var selector = $this.attr('data-target')
var selector = $this.attr('data-target')
if (!selector) {
if (!selector) {
selector = $this.attr('href')
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
}
var $parent = $(selector === '#' ? [] : selector)
var $parent = $(selector === '#' ? [] : selector)
if (e) e.preventDefault()
if (e) e.preventDefault()
if (!$parent.length) {
if (!$parent.length) {
$parent = $this.closest('.alert')
$parent = $this.closest('.alert')
}
}
$parent.trigger(e = $.Event('close.bs.alert'))
$parent.trigger(e = $.Event('close.bs.alert'))
if (e.isDefaultPrevented()) return
if (e.isDefaultPrevented()) return
$parent.removeClass('in')
$parent.removeClass('in')
function removeElement() {
function removeElement() {
// detach from parent, fire event then clean up data
// detach from parent, fire event then clean up data
$parent.detach().trigger('closed.bs.alert').remove()
$parent.detach().trigger('closed.bs.alert').remove()
}
}
$.support.transition && $parent.hasClass('fade') ?
$.support.transition && $parent.hasClass('fade') ?
$parent
$parent
.one('bsTransitionEnd', removeElement)
.one('bsTransitionEnd', removeElement)
.emulateTransitionEnd(Alert.TRANSITION_DURATION) :
.emulateTransitionEnd(Alert.TRANSITION_DURATION) :
removeElement()
removeElement()
}
}
// ALERT PLUGIN DEFINITION
// ALERT PLUGIN DEFINITION
// =======================
// =======================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.alert')
var data = $this.data('bs.alert')
if (!data) $this.data('bs.alert', (data = new Alert(this)))
if (!data) $this.data('bs.alert', (data = new Alert(this)))
if (typeof option == 'string') data[option].call($this)
if (typeof option == 'string') data[option].call($this)
})
})
}
}
var old = $.fn.alert
var old = $.fn.alert
$.fn.alert = Plugin
$.fn.alert = Plugin
$.fn.alert.Constructor = Alert
$.fn.alert.Constructor = Alert
// ALERT NO CONFLICT
// ALERT NO CONFLICT
// =================
// =================
$.fn.alert.noConflict = function () {
$.fn.alert.noConflict = function () {
$.fn.alert = old
$.fn.alert = old
return this
return this
}
}
// ALERT DATA-API
// ALERT DATA-API
// ==============
// ==============
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: button.js v3.3.7
* Bootstrap: button.js v3.3.7
* http://getbootstrap.com/javascript/#buttons
* http://getbootstrap.com/javascript/#buttons
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// BUTTON PUBLIC CLASS DEFINITION
// BUTTON PUBLIC CLASS DEFINITION
// ==============================
// ==============================
var Button = function (element, options) {
var Button = function (element, options) {
this.$element = $(element)
this.$element = $(element)
this.options = $.extend({}, Button.DEFAULTS, options)
this.options = $.extend({}, Button.DEFAULTS, options)
this.isLoading = false
this.isLoading = false
}
}
Button.VERSION = '3.3.7'
Button.VERSION = '3.3.7'
Button.DEFAULTS = {
Button.DEFAULTS = {
loadingText: 'loading...'
loadingText: 'loading...'
}
}
Button.prototype.setState = function (state) {
Button.prototype.setState = function (state) {
var d = 'disabled'
var d = 'disabled'
var $el = this.$element
var $el = this.$element
var val = $el.is('input') ? 'val' : 'html'
var val = $el.is('input') ? 'val' : 'html'
var data = $el.data()
var data = $el.data()
state += 'Text'
state += 'Text'
if (data.resetText == null) $el.data('resetText', $el[val]())
if (data.resetText == null) $el.data('resetText', $el[val]())
// push to event loop to allow forms to submit
// push to event loop to allow forms to submit
setTimeout($.proxy(function () {
setTimeout($.proxy(function () {
$el[val](data[state] == null ? this.options[state] : data[state])
$el[val](data[state] == null ? this.options[state] : data[state])
if (state == 'loadingText') {
if (state === 'loadingText') {
this.isLoading = true
this.isLoading = true
$el.addClass(d).attr(d, d).prop(d, true)
$el.addClass(d).attr(d, d).prop(d, true)
} else if (this.isLoading) {
} else if (this.isLoading) {
this.isLoading = false
this.isLoading = false
$el.removeClass(d).removeAttr(d).prop(d, false)
$el.removeClass(d).removeAttr(d).prop(d, false)
}
}
}, this), 0)
}, this), 0)
}
}
Button.prototype.toggle = function () {
Button.prototype.toggle = function () {
var changed = true
var changed = true
var $parent = this.$element.closest('[data-toggle="buttons"]')
var $parent = this.$element.closest('[data-toggle="buttons"]')
if ($parent.length) {
if ($parent.length) {
var $input = this.$element.find('input')
var $input = this.$element.find('input')
if ($input.prop('type') == 'radio') {
if ($input.prop('type') === 'radio') {
if ($input.prop('checked')) changed = false
if ($input.prop('checked')) changed = false
$parent.find('.active').removeClass('active')
$parent.find('.active').removeClass('active')
this.$element.addClass('active')
this.$element.addClass('active')
} else if ($input.prop('type') == 'checkbox') {
} else if ($input.prop('type') === 'checkbox') {
if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
this.$element.toggleClass('active')
this.$element.toggleClass('active')
}
}
$input.prop('checked', this.$element.hasClass('active'))
$input.prop('checked', this.$element.hasClass('active'))
if (changed) $input.trigger('change')
if (changed) $input.trigger('change')
} else {
} else {
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
this.$element.toggleClass('active')
this.$element.toggleClass('active')
}
}
}
}
// BUTTON PLUGIN DEFINITION
// BUTTON PLUGIN DEFINITION
// ========================
// ========================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.button')
var data = $this.data('bs.button')
var options = typeof option == 'object' && option
var options = typeof option == 'object' && option
if (!data) $this.data('bs.button', (data = new Button(this, options)))
if (!data) $this.data('bs.button', (data = new Button(this, options)))
if (option == 'toggle') data.toggle()
if (option === 'toggle') data.toggle()
else if (option) data.setState(option)
else if (option) data.setState(option)
})
})
}
}
var old = $.fn.button
var old = $.fn.button
$.fn.button = Plugin
$.fn.button = Plugin
$.fn.button.Constructor = Button
$.fn.button.Constructor = Button
// BUTTON NO CONFLICT
// BUTTON NO CONFLICT
// ==================
// ==================
$.fn.button.noConflict = function () {
$.fn.button.noConflict = function () {
$.fn.button = old
$.fn.button = old
return this
return this
}
}
// BUTTON DATA-API
// BUTTON DATA-API
// ===============
// ===============
$(document)
$(document)
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
var $btn = $(e.target).closest('.btn')
var $btn = $(e.target).closest('.btn')
Plugin.call($btn, 'toggle')
Plugin.call($btn, 'toggle')
if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
// Prevent double click on radios, and the double selections (so cancellation) on checkboxes
// Prevent double click on radios, and the double selections (so cancellation) on checkboxes
e.preventDefault()
e.preventDefault()
// The target component still receive the focus
// The target component still receive the focus
if ($btn.is('input,button')) $btn.trigger('focus')
if ($btn.is('input,button')) $btn.trigger('focus')
else $btn.find('input:visible,button:visible').first().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) {
.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))
$(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
})
})
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: carousel.js v3.3.7
* Bootstrap: carousel.js v3.3.7
* http://getbootstrap.com/javascript/#carousel
* http://getbootstrap.com/javascript/#carousel
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// CAROUSEL CLASS DEFINITION
// CAROUSEL CLASS DEFINITION
// =========================
// =========================
var Carousel = function (element, options) {
var Carousel = function (element, options) {
this.$element = $(element)
this.$element = $(element)
this.$indicators = this.$element.find('.carousel-indicators')
this.$indicators = this.$element.find('.carousel-indicators')
this.options = options
this.options = options
this.paused = null
this.paused = null
this.sliding = null
this.sliding = null
this.interval = null
this.interval = null
this.$active = null
this.$active = null
this.$items = null
this.$items = null
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
this.options.pause === 'hover' && !('ontouchstart' in document.documentElement) && this.$element
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
.on('mouseleave.bs.carousel', $.proxy(this.cycle, 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 = {
Carousel.DEFAULTS = {
interval: 5000,
interval: 5000,
pause: 'hover',
pause: 'hover',
wrap: true,
wrap: true,
keyboard: true
keyboard: true
}
}
Carousel.prototype.keydown = function (e) {
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) {
switch (e.which) {
case 37: this.prev(); break
case 37: this.prev(); break
case 39: this.next(); break
case 39: this.next(); break
default: return
default: return
}
}
e.preventDefault()
e.preventDefault()
}
}
Carousel.prototype.cycle = function (e) {
Carousel.prototype.cycle = function (e) {
e || (this.paused = false)
e || (this.paused = false)
this.interval && clearInterval(this.interval)
this.interval && clearInterval(this.interval)
this.options.interval
this.options.interval
&& !this.paused
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
return this
return this
}
}
Carousel.prototype.getItemIndex = function (item) {
Carousel.prototype.getItemIndex = function (item) {
this.$items = item.parent().children('.item')
this.$items = item.parent().children('.item')
return this.$items.index(item || this.$active)
return this.$items.index(item || this.$active)
}
}
Carousel.prototype.getItemForDirection = function (direction, active) {
Carousel.prototype.getItemForDirection = function (direction, active) {
var activeIndex = this.getItemIndex(active)
var activeIndex = this.getItemIndex(active)
var willWrap = (direction == 'prev' && activeIndex === 0)
var willWrap = (direction === 'prev' && activeIndex === 0)
|| (direction == 'next' && activeIndex == (this.$items.length - 1))
|| (direction === 'next' && activeIndex === (this.$items.length - 1))
if (willWrap && !this.options.wrap) return active
if (willWrap && !this.options.wrap) return active
var delta = direction == 'prev' ? -1 : 1
var delta = direction === 'prev' ? -1 : 1
var itemIndex = (activeIndex + delta) % this.$items.length
var itemIndex = (activeIndex + delta) % this.$items.length
return this.$items.eq(itemIndex)
return this.$items.eq(itemIndex)
}
}
Carousel.prototype.to = function (pos) {
Carousel.prototype.to = function (pos) {
var that = this
var that = this
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
if (pos > (this.$items.length - 1) || pos < 0) return
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 (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
if (activeIndex == pos) return this.pause().cycle()
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) {
Carousel.prototype.pause = function (e) {
e || (this.paused = true)
e || (this.paused = true)
if (this.$element.find('.next, .prev').length && $.support.transition) {
if (this.$element.find('.next, .prev').length && $.support.transition) {
this.$element.trigger($.support.transition.end)
this.$element.trigger($.support.transition.end)
this.cycle(true)
this.cycle(true)
}
}
this.interval = clearInterval(this.interval)
this.interval = clearInterval(this.interval)
return this
return this
}
}
Carousel.prototype.next = function () {
Carousel.prototype.next = function () {
if (this.sliding) return
if (this.sliding) return
return this.slide('next')
return this.slide('next')
}
}
Carousel.prototype.prev = function () {
Carousel.prototype.prev = function () {
if (this.sliding) return
if (this.sliding) return
return this.slide('prev')
return this.slide('prev')
}
}
Carousel.prototype.slide = function (type, next) {
Carousel.prototype.slide = function (type, next) {
var $active = this.$element.find('.item.active')
var $active = this.$element.find('.item.active')
var $next = next || this.getItemForDirection(type, $active)
var $next = next || this.getItemForDirection(type, $active)
var isCycling = this.interval
var isCycling = this.interval
var direction = type == 'next' ? 'left' : 'right'
var direction = type === 'next' ? 'left' : 'right'
var that = this
var that = this
if ($next.hasClass('active')) return (this.sliding = false)
if ($next.hasClass('active')) return (this.sliding = false)
var relatedTarget = $next[0]
var relatedTarget = $next[0]
var slideEvent = $.Event('slide.bs.carousel', {
var slideEvent = $.Event('slide.bs.carousel', {
relatedTarget: relatedTarget,
relatedTarget: relatedTarget,
direction: direction
direction: direction
})
})
this.$element.trigger(slideEvent)
this.$element.trigger(slideEvent)
if (slideEvent.isDefaultPrevented()) return
if (slideEvent.isDefaultPrevented()) return
this.sliding = true
this.sliding = true
isCycling && this.pause()
isCycling && this.pause()
if (this.$indicators.length) {
if (this.$indicators.length) {
this.$indicators.find('.active').removeClass('active')
this.$indicators.find('.active').removeClass('active')
var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
$nextIndicator && $nextIndicator.addClass('active')
$nextIndicator && $nextIndicator.addClass('active')
}
}
var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
if ($.support.transition && this.$element.hasClass('slide')) {
if ($.support.transition && this.$element.hasClass('slide')) {
$next.addClass(type)
$next.addClass(type)
$next[0].offsetWidth // force reflow
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$active.addClass(direction)
$next.addClass(direction)
$next.addClass(direction)
$active
$active
.one('bsTransitionEnd', function () {
.one('bsTransitionEnd', function () {
$next.removeClass([type, direction].join(' ')).addClass('active')
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
$active.removeClass(['active', direction].join(' '))
that.sliding = false
that.sliding = false
setTimeout(function () {
setTimeout(function () {
that.$element.trigger(slidEvent)
that.$element.trigger(slidEvent)
}, 0)
}, 0)
})
})
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
} else {
} else {
$active.removeClass('active')
$active.removeClass('active')
$next.addClass('active')
$next.addClass('active')
this.sliding = false
this.sliding = false
this.$element.trigger(slidEvent)
this.$element.trigger(slidEvent)
}
}
isCycling && this.cycle()
isCycling && this.cycle()
return this
return this
}
}
// CAROUSEL PLUGIN DEFINITION
// CAROUSEL PLUGIN DEFINITION
// ==========================
// ==========================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.carousel')
var data = $this.data('bs.carousel')
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
var action = typeof option == 'string' ? option : options.slide
var action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (action) data[action]()
else if (options.interval) data.pause().cycle()
else if (options.interval) data.pause().cycle()
})
})
}
}
var old = $.fn.carousel
var old = $.fn.carousel
$.fn.carousel = Plugin
$.fn.carousel = Plugin
$.fn.carousel.Constructor = Carousel
$.fn.carousel.Constructor = Carousel
// CAROUSEL NO CONFLICT
// CAROUSEL NO CONFLICT
// ====================
// ====================
$.fn.carousel.noConflict = function () {
$.fn.carousel.noConflict = function () {
$.fn.carousel = old
$.fn.carousel = old
return this
return this
}
}
// CAROUSEL DATA-API
// CAROUSEL DATA-API
// =================
// =================
var clickHandler = function (e) {
var clickHandler = function (e) {
var href
var href
var $this = $(this)
var $this = $(this)
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
if (!$target.hasClass('carousel')) return
if (!$target.hasClass('carousel')) return
var options = $.extend({}, $target.data(), $this.data())
var options = $.extend({}, $target.data(), $this.data())
var slideIndex = $this.attr('data-slide-to')
var slideIndex = $this.attr('data-slide-to')
if (slideIndex) options.interval = false
if (slideIndex) options.interval = false
Plugin.call($target, options)
Plugin.call($target, options)
if (slideIndex) {
if (slideIndex) {
$target.data('bs.carousel').to(slideIndex)
$target.data('bs.carousel').to(slideIndex)
}
}
e.preventDefault()
e.preventDefault()
}
}
$(document)
$(document)
.on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
.on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
.on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
.on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
$(window).on('load', function () {
$(window).on('load', function () {
$('[data-ride="carousel"]').each(function () {
$('[data-ride="carousel"]').each(function () {
var $carousel = $(this)
var $carousel = $(this)
Plugin.call($carousel, $carousel.data())
Plugin.call($carousel, $carousel.data())
})
})
})
})
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: collapse.js v3.3.7
* Bootstrap: collapse.js v3.3.7
* http://getbootstrap.com/javascript/#collapse
* http://getbootstrap.com/javascript/#collapse
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
/* jshint latedef: false */
/* jshint latedef: false */
+function ($) {
+function ($) {
'use strict';
'use strict';
// COLLAPSE PUBLIC CLASS DEFINITION
// COLLAPSE PUBLIC CLASS DEFINITION
// ================================
// ================================
var Collapse = function (element, options) {
var Collapse = function (element, options) {
this.$element = $(element)
this.$element = $(element)
this.options = $.extend({}, Collapse.DEFAULTS, options)
this.options = $.extend({}, Collapse.DEFAULTS, options)
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
this.transitioning = null
this.transitioning = null
if (this.options.parent) {
if (this.options.parent) {
this.$parent = this.getParent()
this.$parent = this.getParent()
} else {
} else {
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
}
}
if (this.options.toggle) this.toggle()
if (this.options.toggle) this.toggle()
}
}
Collapse.VERSION = '3.3.7'
Collapse.VERSION = '3.3.7'
Collapse.TRANSITION_DURATION = 350
Collapse.TRANSITION_DURATION = 350
Collapse.DEFAULTS = {
Collapse.DEFAULTS = {
toggle: true
toggle: true
}
}
Collapse.prototype.dimension = function () {
Collapse.prototype.dimension = function () {
var hasWidth = this.$element.hasClass('width')
var hasWidth = this.$element.hasClass('width')
return hasWidth ? 'width' : 'height'
return hasWidth ? 'width' : 'height'
}
}
Collapse.prototype.show = function () {
Collapse.prototype.show = function () {
if (this.transitioning || this.$element.hasClass('in')) return
if (this.transitioning || this.$element.hasClass('in')) return
var activesData
var activesData
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
if (actives && actives.length) {
if (actives && actives.length) {
activesData = actives.data('bs.collapse')
activesData = actives.data('bs.collapse')
if (activesData && activesData.transitioning) return
if (activesData && activesData.transitioning) return
}
}
var startEvent = $.Event('show.bs.collapse')
var startEvent = $.Event('show.bs.collapse')
this.$element.trigger(startEvent)
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
if (startEvent.isDefaultPrevented()) return
if (actives && actives.length) {
if (actives && actives.length) {
Plugin.call(actives, 'hide')
Plugin.call(actives, 'hide')
activesData || actives.data('bs.collapse', null)
activesData || actives.data('bs.collapse', null)
}
}
var dimension = this.dimension()
var dimension = this.dimension()
this.$element
this.$element
.removeClass('collapse')
.removeClass('collapse')
.addClass('collapsing')[dimension](0)
.addClass('collapsing')[dimension](0)
.attr('aria-expanded', true)
.attr('aria-expanded', true)
this.$trigger
this.$trigger
.removeClass('collapsed')
.removeClass('collapsed')
.attr('aria-expanded', true)
.attr('aria-expanded', true)
this.transitioning = 1
this.transitioning = 1
var complete = function () {
var complete = function () {
this.$element
this.$element
.removeClass('collapsing')
.removeClass('collapsing')
.addClass('collapse in')[dimension]('')
.addClass('collapse in')[dimension]('')
this.transitioning = 0
this.transitioning = 0
this.$element
this.$element
.trigger('shown.bs.collapse')
.trigger('shown.bs.collapse')
}
}
if (!$.support.transition) return complete.call(this)
if (!$.support.transition) return complete.call(this)
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
this.$element
this.$element
.one('bsTransitionEnd', $.proxy(complete, this))
.one('bsTransitionEnd', $.proxy(complete, this))
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
}
}
Collapse.prototype.hide = function () {
Collapse.prototype.hide = function () {
if (this.transitioning || !this.$element.hasClass('in')) return
if (this.transitioning || !this.$element.hasClass('in')) return
var startEvent = $.Event('hide.bs.collapse')
var startEvent = $.Event('hide.bs.collapse')
this.$element.trigger(startEvent)
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
if (startEvent.isDefaultPrevented()) return
var dimension = this.dimension()
var dimension = this.dimension()
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
this.$element
this.$element
.addClass('collapsing')
.addClass('collapsing')
.removeClass('collapse in')
.removeClass('collapse in')
.attr('aria-expanded', false)
.attr('aria-expanded', false)
this.$trigger
this.$trigger
.addClass('collapsed')
.addClass('collapsed')
.attr('aria-expanded', false)
.attr('aria-expanded', false)
this.transitioning = 1
this.transitioning = 1
var complete = function () {
var complete = function () {
this.transitioning = 0
this.transitioning = 0
this.$element
this.$element
.removeClass('collapsing')
.removeClass('collapsing')
.addClass('collapse')
.addClass('collapse')
.trigger('hidden.bs.collapse')
.trigger('hidden.bs.collapse')
}
}
if (!$.support.transition) return complete.call(this)
if (!$.support.transition) return complete.call(this)
this.$element
this.$element
[dimension](0)
[dimension](0)
.one('bsTransitionEnd', $.proxy(complete, this))
.one('bsTransitionEnd', $.proxy(complete, this))
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
}
}
Collapse.prototype.toggle = function () {
Collapse.prototype.toggle = function () {
this[this.$element.hasClass('in') ? 'hide' : 'show']()
this[this.$element.hasClass('in') ? 'hide' : 'show']()
}
}
Collapse.prototype.getParent = function () {
Collapse.prototype.getParent = function () {
return $(this.options.parent)
return $(this.options.parent)
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
.each($.proxy(function (i, element) {
.each($.proxy(function (i, element) {
var $element = $(element)
var $element = $(element)
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
}, this))
}, this))
.end()
.end()
}
}
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
var isOpen = $element.hasClass('in')
var isOpen = $element.hasClass('in')
$element.attr('aria-expanded', isOpen)
$element.attr('aria-expanded', isOpen)
$trigger
$trigger
.toggleClass('collapsed', !isOpen)
.toggleClass('collapsed', !isOpen)
.attr('aria-expanded', isOpen)
.attr('aria-expanded', isOpen)
}
}
function getTargetFromTrigger($trigger) {
function getTargetFromTrigger($trigger) {
var href
var href
var target = $trigger.attr('data-target')
var target = $trigger.attr('data-target')
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
return $(target)
return $(target)
}
}
// COLLAPSE PLUGIN DEFINITION
// COLLAPSE PLUGIN DEFINITION
// ==========================
// ==========================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.collapse')
var data = $this.data('bs.collapse')
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
if (typeof option == 'string') data[option]()
if (typeof option == 'string') data[option]()
})
})
}
}
var old = $.fn.collapse
var old = $.fn.collapse
$.fn.collapse = Plugin
$.fn.collapse = Plugin
$.fn.collapse.Constructor = Collapse
$.fn.collapse.Constructor = Collapse
// COLLAPSE NO CONFLICT
// COLLAPSE NO CONFLICT
// ====================
// ====================
$.fn.collapse.noConflict = function () {
$.fn.collapse.noConflict = function () {
$.fn.collapse = old
$.fn.collapse = old
return this
return this
}
}
// COLLAPSE DATA-API
// COLLAPSE DATA-API
// =================
// =================
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
var $this = $(this)
var $this = $(this)
if (!$this.attr('data-target')) e.preventDefault()
if (!$this.attr('data-target')) e.preventDefault()
var $target = getTargetFromTrigger($this)
var $target = getTargetFromTrigger($this)
var data = $target.data('bs.collapse')
var data = $target.data('bs.collapse')
var option = data ? 'toggle' : $this.data()
var option = data ? 'toggle' : $this.data()
Plugin.call($target, option)
Plugin.call($target, option)
})
})
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: dropdown.js v3.3.7
* Bootstrap: dropdown.js v3.3.7
* http://getbootstrap.com/javascript/#dropdowns
* http://getbootstrap.com/javascript/#dropdowns
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// DROPDOWN CLASS DEFINITION
// DROPDOWN CLASS DEFINITION
// =========================
// =========================
var backdrop = '.dropdown-backdrop'
var backdrop = '.dropdown-backdrop'
var toggle = '[data-toggle="dropdown"]'
var toggle = '[data-toggle="dropdown"]'
var Dropdown = function (element) {
var Dropdown = function (element) {
$(element).on('click.bs.dropdown', this.toggle)
$(element).on('click.bs.dropdown', this.toggle)
}
}
Dropdown.VERSION = '3.3.7'
Dropdown.VERSION = '3.3.7'
function getParent($this) {
function getParent($this) {
var selector = $this.attr('data-target')
var selector = $this.attr('data-target')
if (!selector) {
if (!selector) {
selector = $this.attr('href')
selector = $this.attr('href')
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
}
var $parent = selector && $(selector)
var $parent = selector && $(selector)
return $parent && $parent.length ? $parent : $this.parent()
return $parent && $parent.length ? $parent : $this.parent()
}
}
function clearMenus(e) {
function clearMenus(e) {
if (e && e.which === 3) return
if (e && e.which === 3) return
$(backdrop).remove()
$(backdrop).remove()
$(toggle).each(function () {
$(toggle).each(function () {
var $this = $(this)
var $this = $(this)
var $parent = getParent($this)
var $parent = getParent($this)
var relatedTarget = { relatedTarget: this }
var relatedTarget = { relatedTarget: this }
if (!$parent.hasClass('open')) return
if (!$parent.hasClass('open')) return
if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
if (e && e.type === 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
if (e.isDefaultPrevented()) return
if (e.isDefaultPrevented()) return
$this.attr('aria-expanded', 'false')
$this.attr('aria-expanded', 'false')
$parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
$parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
})
})
}
}
Dropdown.prototype.toggle = function (e) {
Dropdown.prototype.toggle = function (e) {
var $this = $(this)
var $this = $(this)
if ($this.is('.disabled, :disabled')) return
if ($this.is('.disabled, :disabled')) return
var $parent = getParent($this)
var $parent = getParent($this)
var isActive = $parent.hasClass('open')
var isActive = $parent.hasClass('open')
clearMenus()
clearMenus()
if (!isActive) {
if (!isActive) {
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
// if mobile we use a backdrop because click events don't delegate
// if mobile we use a backdrop because click events don't delegate
$(document.createElement('div'))
$(document.createElement('div'))
.addClass('dropdown-backdrop')
.addClass('dropdown-backdrop')
.insertAfter($(this))
.insertAfter($(this))
.on('click', clearMenus)
.on('click', clearMenus)
}
}
var relatedTarget = { relatedTarget: this }
var relatedTarget = { relatedTarget: this }
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
if (e.isDefaultPrevented()) return
if (e.isDefaultPrevented()) return
$this
$this
.trigger('focus')
.trigger('focus')
.attr('aria-expanded', 'true')
.attr('aria-expanded', 'true')
$parent
$parent
.toggleClass('open')
.toggleClass('open')
.trigger($.Event('shown.bs.dropdown', relatedTarget))
.trigger($.Event('shown.bs.dropdown', relatedTarget))
}
}
return false
return false
}
}
Dropdown.prototype.keydown = function (e) {
Dropdown.prototype.keydown = function (e) {
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
var $this = $(this)
var $this = $(this)
e.preventDefault()
e.preventDefault()
e.stopPropagation()
e.stopPropagation()
if ($this.is('.disabled, :disabled')) return
if ($this.is('.disabled, :disabled')) return
var $parent = getParent($this)
var $parent = getParent($this)
var isActive = $parent.hasClass('open')
var isActive = $parent.hasClass('open')
if (!isActive && e.which != 27 || isActive && e.which == 27) {
if (!isActive && e.which !== 27 || isActive && e.which === 27) {
if (e.which == 27) $parent.find(toggle).trigger('focus')
if (e.which === 27) $parent.find(toggle).trigger('focus')
return $this.trigger('click')
return $this.trigger('click')
}
}
var desc = ' li:not(.disabled):visible a'
var desc = ' li:not(.disabled):visible a'
var $items = $parent.find('.dropdown-menu' + desc)
var $items = $parent.find('.dropdown-menu' + desc)
if (!$items.length) return
if (!$items.length) return
var index = $items.index(e.target)
var index = $items.index(e.target)
if (e.which == 38 && index > 0) index-- // up
if (e.which === 38 && index > 0) index-- // up
if (e.which == 40 && index < $items.length - 1) index++ // down
if (e.which === 40 && index < $items.length - 1) index++ // down
if (!~index) index = 0
if (!~index) index = 0
$items.eq(index).trigger('focus')
$items.eq(index).trigger('focus')
}
}
// DROPDOWN PLUGIN DEFINITION
// DROPDOWN PLUGIN DEFINITION
// ==========================
// ==========================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.dropdown')
var data = $this.data('bs.dropdown')
if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
if (typeof option == 'string') data[option].call($this)
if (typeof option == 'string') data[option].call($this)
})
})
}
}
var old = $.fn.dropdown
var old = $.fn.dropdown
$.fn.dropdown = Plugin
$.fn.dropdown = Plugin
$.fn.dropdown.Constructor = Dropdown
$.fn.dropdown.Constructor = Dropdown
// DROPDOWN NO CONFLICT
// DROPDOWN NO CONFLICT
// ====================
// ====================
$.fn.dropdown.noConflict = function () {
$.fn.dropdown.noConflict = function () {
$.fn.dropdown = old
$.fn.dropdown = old
return this
return this
}
}
// APPLY TO STANDARD DROPDOWN ELEMENTS
// APPLY TO STANDARD DROPDOWN ELEMENTS
// ===================================
// ===================================
$(document)
$(document)
.on('click.bs.dropdown.data-api', clearMenus)
.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', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
.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', toggle, Dropdown.prototype.keydown)
.on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
.on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: modal.js v3.3.7
* Bootstrap: modal.js v3.3.7
* http://getbootstrap.com/javascript/#modals
* http://getbootstrap.com/javascript/#modals
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// MODAL CLASS DEFINITION
// MODAL CLASS DEFINITION
// ======================
// ======================
var Modal = function (element, options) {
var Modal = function (element, options) {
this.options = options
this.options = options
this.$body = $(document.body)
this.$body = $(document.body)
this.$element = $(element)
this.$element = $(element)
this.$dialog = this.$element.find('.modal-dialog')
this.$dialog = this.$element.find('.modal-dialog')
this.$backdrop = null
this.$backdrop = null
this.isShown = null
this.isShown = null
this.originalBodyPad = null
this.originalBodyPad = null
this.scrollbarWidth = 0
this.scrollbarWidth = 0
this.ignoreBackdropClick = false
this.ignoreBackdropClick = false
if (this.options.remote) {
if (this.options.remote) {
this.$element
this.$element
.find('.modal-content')
.find('.modal-content')
.load(this.options.remote, $.proxy(function () {
.load(this.options.remote, $.proxy(function () {
this.$element.trigger('loaded.bs.modal')
this.$element.trigger('loaded.bs.modal')
}, this))
}, this))
}
}
}
}
Modal.VERSION = '3.3.7'
Modal.VERSION = '3.3.7'
Modal.TRANSITION_DURATION = 300
Modal.TRANSITION_DURATION = 300
Modal.BACKDROP_TRANSITION_DURATION = 150
Modal.BACKDROP_TRANSITION_DURATION = 150
Modal.DEFAULTS = {
Modal.DEFAULTS = {
backdrop: true,
backdrop: true,
keyboard: true,
keyboard: true,
show: true
show: true
}
}
Modal.prototype.toggle = function (_relatedTarget) {
Modal.prototype.toggle = function (_relatedTarget) {
return this.isShown ? this.hide() : this.show(_relatedTarget)
return this.isShown ? this.hide() : this.show(_relatedTarget)
}
}
Modal.prototype.show = function (_relatedTarget) {
Modal.prototype.show = function (_relatedTarget) {
var that = this
var that = this
var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
this.$element.trigger(e)
this.$element.trigger(e)
if (this.isShown || e.isDefaultPrevented()) return
if (this.isShown || e.isDefaultPrevented()) return
this.isShown = true
this.isShown = true
this.checkScrollbar()
this.checkScrollbar()
this.setScrollbar()
this.setScrollbar()
this.$body.addClass('modal-open')
this.$body.addClass('modal-open')
this.escape()
this.escape()
this.resize()
this.resize()
this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
this.$dialog.on('mousedown.dismiss.bs.modal', function () {
this.$dialog.on('mousedown.dismiss.bs.modal', function () {
that.$element.one('mouseup.dismiss.bs.modal', function (e) {
that.$element.one('mouseup.dismiss.bs.modal', function (e) {
if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
})
})
})
})
this.backdrop(function () {
this.backdrop(function () {
var transition = $.support.transition && that.$element.hasClass('fade')
var transition = $.support.transition && that.$element.hasClass('fade')
if (!that.$element.parent().length) {
if (!that.$element.parent().length) {
that.$element.appendTo(that.$body) // don't move modals dom position
that.$element.appendTo(that.$body) // don't move modals dom position
}
}
that.$element
that.$element
.show()
.show()
.scrollTop(0)
.scrollTop(0)
that.adjustDialog()
that.adjustDialog()
if (transition) {
if (transition) {
that.$element[0].offsetWidth // force reflow
that.$element[0].offsetWidth // force reflow
}
}
that.$element.addClass('in')
that.$element.addClass('in')
that.enforceFocus()
that.enforceFocus()
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
transition ?
transition ?
that.$dialog // wait for modal to slide in
that.$dialog // wait for modal to slide in
.one('bsTransitionEnd', function () {
.one('bsTransitionEnd', function () {
that.$element.trigger('focus').trigger(e)
that.$element.trigger('focus').trigger(e)
})
})
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
that.$element.trigger('focus').trigger(e)
that.$element.trigger('focus').trigger(e)
})
})
}
}
Modal.prototype.hide = function (e) {
Modal.prototype.hide = function (e) {
if (e) e.preventDefault()
if (e) e.preventDefault()
e = $.Event('hide.bs.modal')
e = $.Event('hide.bs.modal')
this.$element.trigger(e)
this.$element.trigger(e)
if (!this.isShown || e.isDefaultPrevented()) return
if (!this.isShown || e.isDefaultPrevented()) return
this.isShown = false
this.isShown = false
this.escape()
this.escape()
this.resize()
this.resize()
$(document).off('focusin.bs.modal')
$(document).off('focusin.bs.modal')
this.$element
this.$element
.removeClass('in')
.removeClass('in')
.off('click.dismiss.bs.modal')
.off('click.dismiss.bs.modal')
.off('mouseup.dismiss.bs.modal')
.off('mouseup.dismiss.bs.modal')
this.$dialog.off('mousedown.dismiss.bs.modal')
this.$dialog.off('mousedown.dismiss.bs.modal')
$.support.transition && this.$element.hasClass('fade') ?
$.support.transition && this.$element.hasClass('fade') ?
this.$element
this.$element
.one('bsTransitionEnd', $.proxy(this.hideModal, this))
.one('bsTransitionEnd', $.proxy(this.hideModal, this))
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
this.hideModal()
this.hideModal()
}
}
Modal.prototype.enforceFocus = function () {
Modal.prototype.enforceFocus = function () {
$(document)
$(document)
.off('focusin.bs.modal') // guard against infinite focus loop
.off('focusin.bs.modal') // guard against infinite focus loop
.on('focusin.bs.modal', $.proxy(function (e) {
.on('focusin.bs.modal', $.proxy(function (e) {
if (document !== e.target &&
if (document !== e.target &&
this.$element[0] !== e.target &&
this.$element[0] !== e.target &&
!this.$element.has(e.target).length) {
!this.$element.has(e.target).length) {
this.$element.trigger('focus')
this.$element.trigger('focus')
}
}
}, this))
}, this))
}
}
Modal.prototype.escape = function () {
Modal.prototype.escape = function () {
if (this.isShown && this.options.keyboard) {
if (this.isShown && this.options.keyboard) {
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
e.which == 27 && this.hide()
e.which === 27 && this.hide()
}, this))
}, this))
} else if (!this.isShown) {
} else if (!this.isShown) {
this.$element.off('keydown.dismiss.bs.modal')
this.$element.off('keydown.dismiss.bs.modal')
}
}
}
}
Modal.prototype.resize = function () {
Modal.prototype.resize = function () {
if (this.isShown) {
if (this.isShown) {
$(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
$(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
} else {
} else {
$(window).off('resize.bs.modal')
$(window).off('resize.bs.modal')
}
}
}
}
Modal.prototype.hideModal = function () {
Modal.prototype.hideModal = function () {
var that = this
var that = this
this.$element.hide()
this.$element.hide()
this.backdrop(function () {
this.backdrop(function () {
that.$body.removeClass('modal-open')
that.$body.removeClass('modal-open')
that.resetAdjustments()
that.resetAdjustments()
that.resetScrollbar()
that.resetScrollbar()
that.$element.trigger('hidden.bs.modal')
that.$element.trigger('hidden.bs.modal')
})
})
}
}
Modal.prototype.removeBackdrop = function () {
Modal.prototype.removeBackdrop = function () {
this.$backdrop && this.$backdrop.remove()
this.$backdrop && this.$backdrop.remove()
this.$backdrop = null
this.$backdrop = null
}
}
Modal.prototype.backdrop = function (callback) {
Modal.prototype.backdrop = function (callback) {
var that = this
var that = this
var animate = this.$element.hasClass('fade') ? 'fade' : ''
var animate = this.$element.hasClass('fade') ? 'fade' : ''
if (this.isShown && this.options.backdrop) {
if (this.isShown && this.options.backdrop) {
var doAnimate = $.support.transition && animate
var doAnimate = $.support.transition && animate
this.$backdrop = $(document.createElement('div'))
this.$backdrop = $(document.createElement('div'))
.addClass('modal-backdrop ' + animate)
.addClass('modal-backdrop ' + animate)
.appendTo(this.$body)
.appendTo(this.$body)
this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
if (this.ignoreBackdropClick) {
if (this.ignoreBackdropClick) {
this.ignoreBackdropClick = false
this.ignoreBackdropClick = false
return
return
}
}
if (e.target !== e.currentTarget) return
if (e.target !== e.currentTarget) return
this.options.backdrop == 'static'
this.options.backdrop === 'static'
? this.$element[0].focus()
? this.$element[0].focus()
: this.hide()
: this.hide()
}, this))
}, this))
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
this.$backdrop.addClass('in')
this.$backdrop.addClass('in')
if (!callback) return
if (!callback) return
doAnimate ?
doAnimate ?
this.$backdrop
this.$backdrop
.one('bsTransitionEnd', callback)
.one('bsTransitionEnd', callback)
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
callback()
callback()
} else if (!this.isShown && this.$backdrop) {
} else if (!this.isShown && this.$backdrop) {
this.$backdrop.removeClass('in')
this.$backdrop.removeClass('in')
var callbackRemove = function () {
var callbackRemove = function () {
that.removeBackdrop()
that.removeBackdrop()
callback && callback()
callback && callback()
}
}
$.support.transition && this.$element.hasClass('fade') ?
$.support.transition && this.$element.hasClass('fade') ?
this.$backdrop
this.$backdrop
.one('bsTransitionEnd', callbackRemove)
.one('bsTransitionEnd', callbackRemove)
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
callbackRemove()
callbackRemove()
} else if (callback) {
} else if (callback) {
callback()
callback()
}
}
}
}
// these following methods are used to handle overflowing modals
// these following methods are used to handle overflowing modals
Modal.prototype.handleUpdate = function () {
Modal.prototype.handleUpdate = function () {
this.adjustDialog()
this.adjustDialog()
}
}
Modal.prototype.adjustDialog = function () {
Modal.prototype.adjustDialog = function () {
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
this.$element.css({
this.$element.css({
paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
})
})
}
}
Modal.prototype.resetAdjustments = function () {
Modal.prototype.resetAdjustments = function () {
this.$element.css({
this.$element.css({
paddingLeft: '',
paddingLeft: '',
paddingRight: ''
paddingRight: ''
})
})
}
}
Modal.prototype.checkScrollbar = function () {
Modal.prototype.checkScrollbar = function () {
var fullWindowWidth = window.innerWidth
var fullWindowWidth = window.innerWidth
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
var documentElementRect = document.documentElement.getBoundingClientRect()
var documentElementRect = document.documentElement.getBoundingClientRect()
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
}
}
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
this.scrollbarWidth = this.measureScrollbar()
this.scrollbarWidth = this.measureScrollbar()
}
}
Modal.prototype.setScrollbar = function () {
Modal.prototype.setScrollbar = function () {
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
this.originalBodyPad = document.body.style.paddingRight || ''
this.originalBodyPad = document.body.style.paddingRight || ''
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
}
}
Modal.prototype.resetScrollbar = function () {
Modal.prototype.resetScrollbar = function () {
this.$body.css('padding-right', this.originalBodyPad)
this.$body.css('padding-right', this.originalBodyPad)
}
}
Modal.prototype.measureScrollbar = function () { // thx walsh
Modal.prototype.measureScrollbar = function () { // thx walsh
var scrollDiv = document.createElement('div')
var scrollDiv = document.createElement('div')
scrollDiv.className = 'modal-scrollbar-measure'
scrollDiv.className = 'modal-scrollbar-measure'
this.$body.append(scrollDiv)
this.$body.append(scrollDiv)
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
this.$body[0].removeChild(scrollDiv)
this.$body[0].removeChild(scrollDiv)
return scrollbarWidth
return scrollbarWidth
}
}
// MODAL PLUGIN DEFINITION
// MODAL PLUGIN DEFINITION
// =======================
// =======================
function Plugin(option, _relatedTarget) {
function Plugin(option, _relatedTarget) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.modal')
var data = $this.data('bs.modal')
var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
if (typeof option == 'string') data[option](_relatedTarget)
if (typeof option == 'string') data[option](_relatedTarget)
else if (options.show) data.show(_relatedTarget)
else if (options.show) data.show(_relatedTarget)
})
})
}
}
var old = $.fn.modal
var old = $.fn.modal
$.fn.modal = Plugin
$.fn.modal = Plugin
$.fn.modal.Constructor = Modal
$.fn.modal.Constructor = Modal
// MODAL NO CONFLICT
// MODAL NO CONFLICT
// =================
// =================
$.fn.modal.noConflict = function () {
$.fn.modal.noConflict = function () {
$.fn.modal = old
$.fn.modal = old
return this
return this
}
}
// MODAL DATA-API
// MODAL DATA-API
// ==============
// ==============
$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
var $this = $(this)
var $this = $(this)
var href = $this.attr('href')
var href = $this.attr('href')
var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
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())
var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
if ($this.is('a')) e.preventDefault()
if ($this.is('a')) e.preventDefault()
$target.one('show.bs.modal', function (showEvent) {
$target.one('show.bs.modal', function (showEvent) {
if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
$target.one('hidden.bs.modal', function () {
$target.one('hidden.bs.modal', function () {
$this.is(':visible') && $this.trigger('focus')
$this.is(':visible') && $this.trigger('focus')
})
})
})
})
Plugin.call($target, option, this)
Plugin.call($target, option, this)
})
})
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: tooltip.js v3.3.7
* Bootstrap: tooltip.js v3.3.7
* http://getbootstrap.com/javascript/#tooltip
* http://getbootstrap.com/javascript/#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame
* Inspired by the original jQuery.tipsy by Jason Frame
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// TOOLTIP PUBLIC CLASS DEFINITION
// TOOLTIP PUBLIC CLASS DEFINITION
// ===============================
// ===============================
var Tooltip = function (element, options) {
var Tooltip = function (element, options) {
this.type = null
this.type = null
this.options = null
this.options = null
this.enabled = null
this.enabled = null
this.timeout = null
this.timeout = null
this.hoverState = null
this.hoverState = null
this.$element = null
this.$element = null
this.inState = null
this.inState = null
this.init('tooltip', element, options)
this.init('tooltip', element, options)
}
}
Tooltip.VERSION = '3.3.7'
Tooltip.VERSION = '3.3.7'
Tooltip.TRANSITION_DURATION = 150
Tooltip.TRANSITION_DURATION = 150
Tooltip.DEFAULTS = {
Tooltip.DEFAULTS = {
animation: true,
animation: true,
placement: 'top',
placement: 'top',
selector: false,
selector: false,
template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
trigger: 'hover focus',
trigger: 'hover focus',
title: '',
title: '',
delay: 0,
delay: 0,
html: false,
html: false,
container: false,
container: false,
viewport: {
viewport: {
selector: 'body',
selector: 'body',
padding: 0
padding: 0
}
}
}
}
Tooltip.prototype.init = function (type, element, options) {
Tooltip.prototype.init = function (type, element, options) {
this.enabled = true
this.enabled = true
this.type = type
this.type = type
this.$element = $(element)
this.$element = $(element)
this.options = this.getOptions(options)
this.options = this.getOptions(options)
this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
this.inState = { click: false, hover: false, focus: false }
this.inState = { click: false, hover: false, focus: false }
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
}
}
var triggers = this.options.trigger.split(' ')
var triggers = this.options.trigger.split(' ')
for (var i = triggers.length; i--;) {
for (var i = triggers.length; i--;) {
var trigger = triggers[i]
var trigger = triggers[i]
if (trigger == 'click') {
if (trigger === 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (trigger != 'manual') {
} else if (trigger !== 'manual') {
var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
var eventIn = trigger === 'hover' ? 'mouseenter' : 'focusin'
var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
var eventOut = trigger === 'hover' ? 'mouseleave' : 'focusout'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
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))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
}
}
}
this.options.selector ?
this.options.selector ?
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
this.fixTitle()
this.fixTitle()
}
}
Tooltip.prototype.getDefaults = function () {
Tooltip.prototype.getDefaults = function () {
return Tooltip.DEFAULTS
return Tooltip.DEFAULTS
}
}
Tooltip.prototype.getOptions = function (options) {
Tooltip.prototype.getOptions = function (options) {
options = $.extend({}, this.getDefaults(), this.$element.data(), options)
options = $.extend({}, this.getDefaults(), this.$element.data(), options)
if (options.delay && typeof options.delay == 'number') {
if (options.delay && typeof options.delay == 'number') {
options.delay = {
options.delay = {
show: options.delay,
show: options.delay,
hide: options.delay
hide: options.delay
}
}
}
}
return options
return options
}
}
Tooltip.prototype.getDelegateOptions = function () {
Tooltip.prototype.getDelegateOptions = function () {
var options = {}
var options = {}
var defaults = this.getDefaults()
var defaults = this.getDefaults()
this._options && $.each(this._options, function (key, value) {
this._options && $.each(this._options, function (key, value) {
if (defaults[key] != value) options[key] = value
if (defaults[key] !== value) options[key] = value
})
})
return options
return options
}
}
Tooltip.prototype.enter = function (obj) {
Tooltip.prototype.enter = function (obj) {
var self = obj instanceof this.constructor ?
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget).data('bs.' + this.type)
obj : $(obj.currentTarget).data('bs.' + this.type)
if (!self) {
if (!self) {
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
$(obj.currentTarget).data('bs.' + this.type, self)
$(obj.currentTarget).data('bs.' + this.type, self)
}
}
if (obj instanceof $.Event) {
if (obj instanceof $.Event) {
self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
self.inState[obj.type === 'focusin' ? 'focus' : 'hover'] = true
}
}
if (self.tip().hasClass('in') || self.hoverState == 'in') {
if (self.tip().hasClass('in') || self.hoverState === 'in') {
self.hoverState = 'in'
self.hoverState = 'in'
return
return
}
}
clearTimeout(self.timeout)
clearTimeout(self.timeout)
self.hoverState = 'in'
self.hoverState = 'in'
if (!self.options.delay || !self.options.delay.show) return self.show()
if (!self.options.delay || !self.options.delay.show) return self.show()
self.timeout = setTimeout(function () {
self.timeout = setTimeout(function () {
if (self.hoverState == 'in') self.show()
if (self.hoverState === 'in') self.show()
}, self.options.delay.show)
}, self.options.delay.show)
}
}
Tooltip.prototype.isInStateTrue = function () {
Tooltip.prototype.isInStateTrue = function () {
for (var key in this.inState) {
for (var key in this.inState) {
if (this.inState[key]) return true
if (this.inState[key]) return true
}
}
return false
return false
}
}
Tooltip.prototype.leave = function (obj) {
Tooltip.prototype.leave = function (obj) {
var self = obj instanceof this.constructor ?
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget).data('bs.' + this.type)
obj : $(obj.currentTarget).data('bs.' + this.type)
if (!self) {
if (!self) {
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
$(obj.currentTarget).data('bs.' + this.type, self)
$(obj.currentTarget).data('bs.' + this.type, self)
}
}
if (obj instanceof $.Event) {
if (obj instanceof $.Event) {
self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
self.inState[obj.type === 'focusout' ? 'focus' : 'hover'] = false
}
}
if (self.isInStateTrue()) return
if (self.isInStateTrue()) return
clearTimeout(self.timeout)
clearTimeout(self.timeout)
self.hoverState = 'out'
self.hoverState = 'out'
if (!self.options.delay || !self.options.delay.hide) return self.hide()
if (!self.options.delay || !self.options.delay.hide) return self.hide()
self.timeout = setTimeout(function () {
self.timeout = setTimeout(function () {
if (self.hoverState == 'out') self.hide()
if (self.hoverState === 'out') self.hide()
}, self.options.delay.hide)
}, self.options.delay.hide)
}
}
Tooltip.prototype.show = function () {
Tooltip.prototype.show = function () {
var e = $.Event('show.bs.' + this.type)
var e = $.Event('show.bs.' + this.type)
if (this.hasContent() && this.enabled) {
if (this.hasContent() && this.enabled) {
this.$element.trigger(e)
this.$element.trigger(e)
var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
if (e.isDefaultPrevented() || !inDom) return
if (e.isDefaultPrevented() || !inDom) return
var that = this
var that = this
var $tip = this.tip()
var $tip = this.tip()
var tipId = this.getUID(this.type)
var tipId = this.getUID(this.type)
this.setContent()
this.setContent()
$tip.attr('id', tipId)
$tip.attr('id', tipId)
this.$element.attr('aria-describedby', tipId)
this.$element.attr('aria-describedby', tipId)
if (this.options.animation) $tip.addClass('fade')
if (this.options.animation) $tip.addClass('fade')
var placement = typeof this.options.placement == 'function' ?
var placement = typeof this.options.placement == 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement
this.options.placement
var autoToken = /\s?auto?\s?/i
var autoToken = /\s?auto?\s?/i
var autoPlace = autoToken.test(placement)
var autoPlace = autoToken.test(placement)
if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
$tip
$tip
.detach()
.detach()
.css({ top: 0, left: 0, display: 'block' })
.css({ top: 0, left: 0, display: 'block' })
.addClass(placement)
.addClass(placement)
.data('bs.' + this.type, this)
.data('bs.' + this.type, this)
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
this.$element.trigger('inserted.bs.' + this.type)
this.$element.trigger('inserted.bs.' + this.type)
var pos = this.getPosition()
var pos = this.getPosition()
var actualWidth = $tip[0].offsetWidth
var actualWidth = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
var actualHeight = $tip[0].offsetHeight
if (autoPlace) {
if (autoPlace) {
var orgPlacement = placement
var orgPlacement = placement
var viewportDim = this.getPosition(this.$viewport)
var viewportDim = this.getPosition(this.$viewport)
placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
placement = placement === 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
placement === 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
placement === 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
placement === 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
placement
placement
$tip
$tip
.removeClass(orgPlacement)
.removeClass(orgPlacement)
.addClass(placement)
.addClass(placement)
}
}
var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
this.applyPlacement(calculatedOffset, placement)
this.applyPlacement(calculatedOffset, placement)
var complete = function () {
var complete = function () {
var prevHoverState = that.hoverState
var prevHoverState = that.hoverState
that.$element.trigger('shown.bs.' + that.type)
that.$element.trigger('shown.bs.' + that.type)
that.hoverState = null
that.hoverState = null
if (prevHoverState == 'out') that.leave(that)
if (prevHoverState === 'out') that.leave(that)
}
}
$.support.transition && this.$tip.hasClass('fade') ?
$.support.transition && this.$tip.hasClass('fade') ?
$tip
$tip
.one('bsTransitionEnd', complete)
.one('bsTransitionEnd', complete)
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete()
complete()
}
}
}
}
Tooltip.prototype.applyPlacement = function (offset, placement) {
Tooltip.prototype.applyPlacement = function (offset, placement) {
var $tip = this.tip()
var $tip = this.tip()
var width = $tip[0].offsetWidth
var width = $tip[0].offsetWidth
var height = $tip[0].offsetHeight
var height = $tip[0].offsetHeight
// manually read margins because getBoundingClientRect includes difference
// manually read margins because getBoundingClientRect includes difference
var marginTop = parseInt($tip.css('margin-top'), 10)
var marginTop = parseInt($tip.css('margin-top'), 10)
var marginLeft = parseInt($tip.css('margin-left'), 10)
var marginLeft = parseInt($tip.css('margin-left'), 10)
// we must check for NaN for ie 8/9
// we must check for NaN for ie 8/9
if (isNaN(marginTop)) marginTop = 0
if (isNaN(marginTop)) marginTop = 0
if (isNaN(marginLeft)) marginLeft = 0
if (isNaN(marginLeft)) marginLeft = 0
offset.top += marginTop
offset.top += marginTop
offset.left += marginLeft
offset.left += marginLeft
// $.fn.offset doesn't round pixel values
// $.fn.offset doesn't round pixel values
// so we use setOffset directly with our own function B-0
// so we use setOffset directly with our own function B-0
$.offset.setOffset($tip[0], $.extend({
$.offset.setOffset($tip[0], $.extend({
using: function (props) {
using: function (props) {
$tip.css({
$tip.css({
top: Math.round(props.top),
top: Math.round(props.top),
left: Math.round(props.left)
left: Math.round(props.left)
})
})
}
}
}, offset), 0)
}, offset), 0)
$tip.addClass('in')
$tip.addClass('in')
// check to see if placing tip in new offset caused the tip to resize itself
// check to see if placing tip in new offset caused the tip to resize itself
var actualWidth = $tip[0].offsetWidth
var actualWidth = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
var actualHeight = $tip[0].offsetHeight
if (placement == 'top' && actualHeight != height) {
if (placement === 'top' && actualHeight != height) {
offset.top = offset.top + height - actualHeight
offset.top = offset.top + height - actualHeight
}
}
var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
if (delta.left) offset.left += delta.left
if (delta.left) offset.left += delta.left
else offset.top += delta.top
else offset.top += delta.top
var isVertical = /top|bottom/.test(placement)
var isVertical = /top|bottom/.test(placement)
var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
$tip.offset(offset)
$tip.offset(offset)
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
}
}
Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
this.arrow()
this.arrow()
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isVertical ? 'top' : 'left', '')
.css(isVertical ? 'top' : 'left', '')
}
}
Tooltip.prototype.setContent = function () {
Tooltip.prototype.setContent = function () {
var $tip = this.tip()
var $tip = this.tip()
var title = this.getTitle()
var title = this.getTitle()
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
$tip.removeClass('fade in top bottom left right')
$tip.removeClass('fade in top bottom left right')
}
}
Tooltip.prototype.hide = function (callback) {
Tooltip.prototype.hide = function (callback) {
var that = this
var that = this
var $tip = $(this.$tip)
var $tip = $(this.$tip)
var e = $.Event('hide.bs.' + this.type)
var e = $.Event('hide.bs.' + this.type)
function complete() {
function complete() {
if (that.hoverState != 'in') $tip.detach()
if (that.hoverState !== 'in') $tip.detach()
if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
that.$element
that.$element
.removeAttr('aria-describedby')
.removeAttr('aria-describedby')
.trigger('hidden.bs.' + that.type)
.trigger('hidden.bs.' + that.type)
}
}
callback && callback()
callback && callback()
}
}
this.$element.trigger(e)
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
if (e.isDefaultPrevented()) return
$tip.removeClass('in')
$tip.removeClass('in')
$.support.transition && $tip.hasClass('fade') ?
$.support.transition && $tip.hasClass('fade') ?
$tip
$tip
.one('bsTransitionEnd', complete)
.one('bsTransitionEnd', complete)
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete()
complete()
this.hoverState = null
this.hoverState = null
return this
return this
}
}
Tooltip.prototype.fixTitle = function () {
Tooltip.prototype.fixTitle = function () {
var $e = this.$element
var $e = this.$element
if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
}
}
}
}
Tooltip.prototype.hasContent = function () {
Tooltip.prototype.hasContent = function () {
return this.getTitle()
return this.getTitle()
}
}
Tooltip.prototype.getPosition = function ($element) {
Tooltip.prototype.getPosition = function ($element) {
$element = $element || this.$element
$element = $element || this.$element
var el = $element[0]
var el = $element[0]
var isBody = el.tagName == 'BODY'
var isBody = el.tagName === 'BODY'
var elRect = el.getBoundingClientRect()
var elRect = el.getBoundingClientRect()
if (elRect.width == null) {
if (elRect.width == null) {
// width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
// 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 })
elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
}
}
var isSvg = window.SVGElement && el instanceof window.SVGElement
var isSvg = window.SVGElement && el instanceof window.SVGElement
// Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
// Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
// See https://github.com/twbs/bootstrap/issues/20280
// See https://github.com/twbs/bootstrap/issues/20280
var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
return $.extend({}, elRect, scroll, outerDims, elOffset)
return $.extend({}, elRect, scroll, outerDims, elOffset)
}
}
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
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 === '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 === '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 }
/* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
}
}
Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
var delta = { top: 0, left: 0 }
var delta = { top: 0, left: 0 }
if (!this.$viewport) return delta
if (!this.$viewport) return delta
var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
var viewportDimensions = this.getPosition(this.$viewport)
var viewportDimensions = this.getPosition(this.$viewport)
if (/right|left/.test(placement)) {
if (/right|left/.test(placement)) {
var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
if (topEdgeOffset < viewportDimensions.top) { // top overflow
if (topEdgeOffset < viewportDimensions.top) { // top overflow
delta.top = viewportDimensions.top - topEdgeOffset
delta.top = viewportDimensions.top - topEdgeOffset
} else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
} else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
}
}
} else {
} else {
var leftEdgeOffset = pos.left - viewportPadding
var leftEdgeOffset = pos.left - viewportPadding
var rightEdgeOffset = pos.left + viewportPadding + actualWidth
var rightEdgeOffset = pos.left + viewportPadding + actualWidth
if (leftEdgeOffset < viewportDimensions.left) { // left overflow
if (leftEdgeOffset < viewportDimensions.left) { // left overflow
delta.left = viewportDimensions.left - leftEdgeOffset
delta.left = viewportDimensions.left - leftEdgeOffset
} else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
} else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
}
}
}
}
return delta
return delta
}
}
Tooltip.prototype.getTitle = function () {
Tooltip.prototype.getTitle = function () {
var title
var title
var $e = this.$element
var $e = this.$element
var o = this.options
var o = this.options
title = $e.attr('data-original-title')
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
return title
return title
}
}
Tooltip.prototype.getUID = function (prefix) {
Tooltip.prototype.getUID = function (prefix) {
do prefix += ~~(Math.random() * 1000000)
do prefix += ~~(Math.random() * 1000000)
while (document.getElementById(prefix))
while (document.getElementById(prefix))
return prefix
return prefix
}
}
Tooltip.prototype.tip = function () {
Tooltip.prototype.tip = function () {
if (!this.$tip) {
if (!this.$tip) {
this.$tip = $(this.options.template)
this.$tip = $(this.options.template)
if (this.$tip.length != 1) {
if (this.$tip.length !== 1) {
throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
}
}
}
}
return this.$tip
return this.$tip
}
}
Tooltip.prototype.arrow = function () {
Tooltip.prototype.arrow = function () {
return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
}
}
Tooltip.prototype.enable = function () {
Tooltip.prototype.enable = function () {
this.enabled = true
this.enabled = true
}
}
Tooltip.prototype.disable = function () {
Tooltip.prototype.disable = function () {
this.enabled = false
this.enabled = false
}
}
Tooltip.prototype.toggleEnabled = function () {
Tooltip.prototype.toggleEnabled = function () {
this.enabled = !this.enabled
this.enabled = !this.enabled
}
}
Tooltip.prototype.toggle = function (e) {
Tooltip.prototype.toggle = function (e) {
var self = this
var self = this
if (e) {
if (e) {
self = $(e.currentTarget).data('bs.' + this.type)
self = $(e.currentTarget).data('bs.' + this.type)
if (!self) {
if (!self) {
self = new this.constructor(e.currentTarget, this.getDelegateOptions())
self = new this.constructor(e.currentTarget, this.getDelegateOptions())
$(e.currentTarget).data('bs.' + this.type, self)
$(e.currentTarget).data('bs.' + this.type, self)
}
}
}
}
if (e) {
if (e) {
self.inState.click = !self.inState.click
self.inState.click = !self.inState.click
if (self.isInStateTrue()) self.enter(self)
if (self.isInStateTrue()) self.enter(self)
else self.leave(self)
else self.leave(self)
} else {
} else {
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
}
}
}
}
Tooltip.prototype.destroy = function () {
Tooltip.prototype.destroy = function () {
var that = this
var that = this
clearTimeout(this.timeout)
clearTimeout(this.timeout)
this.hide(function () {
this.hide(function () {
that.$element.off('.' + that.type).removeData('bs.' + that.type)
that.$element.off('.' + that.type).removeData('bs.' + that.type)
if (that.$tip) {
if (that.$tip) {
that.$tip.detach()
that.$tip.detach()
}
}
that.$tip = null
that.$tip = null
that.$arrow = null
that.$arrow = null
that.$viewport = null
that.$viewport = null
that.$element = null
that.$element = null
})
})
}
}
// TOOLTIP PLUGIN DEFINITION
// TOOLTIP PLUGIN DEFINITION
// =========================
// =========================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.tooltip')
var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option
var options = typeof option == 'object' && option
if (!data && /destroy|hide/.test(option)) return
if (!data && /destroy|hide/.test(option)) return
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]()
if (typeof option == 'string') data[option]()
})
})
}
}
var old = $.fn.tooltip
var old = $.fn.tooltip
$.fn.tooltip = Plugin
$.fn.tooltip = Plugin
$.fn.tooltip.Constructor = Tooltip
$.fn.tooltip.Constructor = Tooltip
// TOOLTIP NO CONFLICT
// TOOLTIP NO CONFLICT
// ===================
// ===================
$.fn.tooltip.noConflict = function () {
$.fn.tooltip.noConflict = function () {
$.fn.tooltip = old
$.fn.tooltip = old
return this
return this
}
}
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: popover.js v3.3.7
* Bootstrap: popover.js v3.3.7
* http://getbootstrap.com/javascript/#popovers
* http://getbootstrap.com/javascript/#popovers
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// POPOVER PUBLIC CLASS DEFINITION
// POPOVER PUBLIC CLASS DEFINITION
// ===============================
// ===============================
var Popover = function (element, options) {
var Popover = function (element, options) {
this.init('popover', element, options)
this.init('popover', element, options)
}
}
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
Popover.VERSION = '3.3.7'
Popover.VERSION = '3.3.7'
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
placement: 'right',
placement: 'right',
trigger: 'click',
trigger: 'click',
content: '',
content: '',
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
})
})
// NOTE: POPOVER EXTENDS tooltip.js
// NOTE: POPOVER EXTENDS tooltip.js
// ================================
// ================================
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
Popover.prototype.constructor = Popover
Popover.prototype.constructor = Popover
Popover.prototype.getDefaults = function () {
Popover.prototype.getDefaults = function () {
return Popover.DEFAULTS
return Popover.DEFAULTS
}
}
Popover.prototype.setContent = function () {
Popover.prototype.setContent = function () {
var $tip = this.tip()
var $tip = this.tip()
var title = this.getTitle()
var title = this.getTitle()
var content = this.getContent()
var content = this.getContent()
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
$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
$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'
this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
](content)
](content)
$tip.removeClass('fade top bottom left right in')
$tip.removeClass('fade top bottom left right in')
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
// this manually by checking the contents.
// this manually by checking the contents.
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
}
}
Popover.prototype.hasContent = function () {
Popover.prototype.hasContent = function () {
return this.getTitle() || this.getContent()
return this.getTitle() || this.getContent()
}
}
Popover.prototype.getContent = function () {
Popover.prototype.getContent = function () {
var $e = this.$element
var $e = this.$element
var o = this.options
var o = this.options
return $e.attr('data-content')
return $e.attr('data-content')
|| (typeof o.content == 'function' ?
|| (typeof o.content == 'function' ?
o.content.call($e[0]) :
o.content.call($e[0]) :
o.content)
o.content)
}
}
Popover.prototype.arrow = function () {
Popover.prototype.arrow = function () {
return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
}
}
// POPOVER PLUGIN DEFINITION
// POPOVER PLUGIN DEFINITION
// =========================
// =========================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.popover')
var data = $this.data('bs.popover')
var options = typeof option == 'object' && option
var options = typeof option == 'object' && option
if (!data && /destroy|hide/.test(option)) return
if (!data && /destroy|hide/.test(option)) return
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
if (typeof option == 'string') data[option]()
if (typeof option == 'string') data[option]()
})
})
}
}
var old = $.fn.popover
var old = $.fn.popover
$.fn.popover = Plugin
$.fn.popover = Plugin
$.fn.popover.Constructor = Popover
$.fn.popover.Constructor = Popover
// POPOVER NO CONFLICT
// POPOVER NO CONFLICT
// ===================
// ===================
$.fn.popover.noConflict = function () {
$.fn.popover.noConflict = function () {
$.fn.popover = old
$.fn.popover = old
return this
return this
}
}
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: scrollspy.js v3.3.7
* Bootstrap: scrollspy.js v3.3.7
* http://getbootstrap.com/javascript/#scrollspy
* http://getbootstrap.com/javascript/#scrollspy
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// SCROLLSPY CLASS DEFINITION
// SCROLLSPY CLASS DEFINITION
// ==========================
// ==========================
function ScrollSpy(element, options) {
function ScrollSpy(element, options) {
this.$body = $(document.body)
this.$body = $(document.body)
this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
this.selector = (this.options.target || '') + ' .nav li > a'
this.selector = (this.options.target || '') + ' .nav li > a'
this.offsets = []
this.offsets = []
this.targets = []
this.targets = []
this.activeTarget = null
this.activeTarget = null
this.scrollHeight = 0
this.scrollHeight = 0
this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
this.refresh()
this.refresh()
this.process()
this.process()
}
}
ScrollSpy.VERSION = '3.3.7'
ScrollSpy.VERSION = '3.3.7'
ScrollSpy.DEFAULTS = {
ScrollSpy.DEFAULTS = {
offset: 10
offset: 10
}
}
ScrollSpy.prototype.getScrollHeight = function () {
ScrollSpy.prototype.getScrollHeight = function () {
return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
}
}
ScrollSpy.prototype.refresh = function () {
ScrollSpy.prototype.refresh = function () {
var that = this
var that = this
var offsetMethod = 'offset'
var offsetMethod = 'offset'
var offsetBase = 0
var offsetBase = 0
this.offsets = []
this.offsets = []
this.targets = []
this.targets = []
this.scrollHeight = this.getScrollHeight()
this.scrollHeight = this.getScrollHeight()
if (!$.isWindow(this.$scrollElement[0])) {
if (!$.isWindow(this.$scrollElement[0])) {
offsetMethod = 'position'
offsetMethod = 'position'
offsetBase = this.$scrollElement.scrollTop()
offsetBase = this.$scrollElement.scrollTop()
}
}
this.$body
this.$body
.find(this.selector)
.find(this.selector)
.map(function () {
.map(function () {
var $el = $(this)
var $el = $(this)
var href = $el.data('target') || $el.attr('href')
var href = $el.data('target') || $el.attr('href')
var $href = /^#./.test(href) && $(href)
var $href = /^#./.test(href) && $(href)
return ($href
return ($href
&& $href.length
&& $href.length
&& $href.is(':visible')
&& $href.is(':visible')
&& [[$href[offsetMethod]().top + offsetBase, href]]) || null
&& [[$href[offsetMethod]().top + offsetBase, href]]) || null
})
})
.sort(function (a, b) { return a[0] - b[0] })
.sort(function (a, b) { return a[0] - b[0] })
.each(function () {
.each(function () {
that.offsets.push(this[0])
that.offsets.push(this[0])
that.targets.push(this[1])
that.targets.push(this[1])
})
})
}
}
ScrollSpy.prototype.process = function () {
ScrollSpy.prototype.process = function () {
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
var scrollHeight = this.getScrollHeight()
var scrollHeight = this.getScrollHeight()
var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
var offsets = this.offsets
var offsets = this.offsets
var targets = this.targets
var targets = this.targets
var activeTarget = this.activeTarget
var activeTarget = this.activeTarget
var i
var i
if (this.scrollHeight != scrollHeight) {
if (this.scrollHeight !== scrollHeight) {
this.refresh()
this.refresh()
}
}
if (scrollTop >= maxScroll) {
if (scrollTop >= maxScroll) {
return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
return activeTarget !== (i = targets[targets.length - 1]) && this.activate(i)
}
}
if (activeTarget && scrollTop < offsets[0]) {
if (activeTarget && scrollTop < offsets[0]) {
this.activeTarget = null
this.activeTarget = null
return this.clear()
return this.clear()
}
}
for (i = offsets.length; i--;) {
for (i = offsets.length; i--;) {
activeTarget != targets[i]
activeTarget !== targets[i]
&& scrollTop >= offsets[i]
&& scrollTop >= offsets[i]
&& (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
&& (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
&& this.activate(targets[i])
&& this.activate(targets[i])
}
}
}
}
ScrollSpy.prototype.activate = function (target) {
ScrollSpy.prototype.activate = function (target) {
this.activeTarget = target
this.activeTarget = target
this.clear()
this.clear()
var selector = this.selector +
var selector = this.selector +
'[data-target="' + target + '"],' +
'[data-target="' + target + '"],' +
this.selector + '[href="' + target + '"]'
this.selector + '[href="' + target + '"]'
var active = $(selector)
var active = $(selector)
.parents('li')
.parents('li')
.addClass('active')
.addClass('active')
if (active.parent('.dropdown-menu').length) {
if (active.parent('.dropdown-menu').length) {
active = active
active = active
.closest('li.dropdown')
.closest('li.dropdown')
.addClass('active')
.addClass('active')
}
}
active.trigger('activate.bs.scrollspy')
active.trigger('activate.bs.scrollspy')
}
}
ScrollSpy.prototype.clear = function () {
ScrollSpy.prototype.clear = function () {
$(this.selector)
$(this.selector)
.parentsUntil(this.options.target, '.active')
.parentsUntil(this.options.target, '.active')
.removeClass('active')
.removeClass('active')
}
}
// SCROLLSPY PLUGIN DEFINITION
// SCROLLSPY PLUGIN DEFINITION
// ===========================
// ===========================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.scrollspy')
var data = $this.data('bs.scrollspy')
var options = typeof option == 'object' && option
var options = typeof option == 'object' && option
if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
if (typeof option == 'string') data[option]()
if (typeof option == 'string') data[option]()
})
})
}
}
var old = $.fn.scrollspy
var old = $.fn.scrollspy
$.fn.scrollspy = Plugin
$.fn.scrollspy = Plugin
$.fn.scrollspy.Constructor = ScrollSpy
$.fn.scrollspy.Constructor = ScrollSpy
// SCROLLSPY NO CONFLICT
// SCROLLSPY NO CONFLICT
// =====================
// =====================
$.fn.scrollspy.noConflict = function () {
$.fn.scrollspy.noConflict = function () {
$.fn.scrollspy = old
$.fn.scrollspy = old
return this
return this
}
}
// SCROLLSPY DATA-API
// SCROLLSPY DATA-API
// ==================
// ==================
$(window).on('load.bs.scrollspy.data-api', function () {
$(window).on('load.bs.scrollspy.data-api', function () {
$('[data-spy="scroll"]').each(function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
var $spy = $(this)
Plugin.call($spy, $spy.data())
Plugin.call($spy, $spy.data())
})
})
})
})
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: tab.js v3.3.7
* Bootstrap: tab.js v3.3.7
* http://getbootstrap.com/javascript/#tabs
* http://getbootstrap.com/javascript/#tabs
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// TAB CLASS DEFINITION
// TAB CLASS DEFINITION
// ====================
// ====================
var Tab = function (element) {
var Tab = function (element) {
// jscs:disable requireDollarBeforejQueryAssignment
// jscs:disable requireDollarBeforejQueryAssignment
this.element = $(element)
this.element = $(element)
// jscs:enable requireDollarBeforejQueryAssignment
// jscs:enable requireDollarBeforejQueryAssignment
}
}
Tab.VERSION = '3.3.7'
Tab.VERSION = '3.3.7'
Tab.TRANSITION_DURATION = 150
Tab.TRANSITION_DURATION = 150
Tab.prototype.show = function () {
Tab.prototype.show = function () {
var $this = this.element
var $this = this.element
var $ul = $this.closest('ul:not(.dropdown-menu)')
var $ul = $this.closest('ul:not(.dropdown-menu)')
var selector = $this.data('target')
var selector = $this.data('target')
if (!selector) {
if (!selector) {
selector = $this.attr('href')
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
}
if ($this.parent('li').hasClass('active')) return
if ($this.parent('li').hasClass('active')) return
var $previous = $ul.find('.active:last a')
var $previous = $ul.find('.active:last a')
var hideEvent = $.Event('hide.bs.tab', {
var hideEvent = $.Event('hide.bs.tab', {
relatedTarget: $this[0]
relatedTarget: $this[0]
})
})
var showEvent = $.Event('show.bs.tab', {
var showEvent = $.Event('show.bs.tab', {
relatedTarget: $previous[0]
relatedTarget: $previous[0]
})
})
$previous.trigger(hideEvent)
$previous.trigger(hideEvent)
$this.trigger(showEvent)
$this.trigger(showEvent)
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
var $target = $(selector)
var $target = $(selector)
this.activate($this.closest('li'), $ul)
this.activate($this.closest('li'), $ul)
this.activate($target, $target.parent(), function () {
this.activate($target, $target.parent(), function () {
$previous.trigger({
$previous.trigger({
type: 'hidden.bs.tab',
type: 'hidden.bs.tab',
relatedTarget: $this[0]
relatedTarget: $this[0]
})
})
$this.trigger({
$this.trigger({
type: 'shown.bs.tab',
type: 'shown.bs.tab',
relatedTarget: $previous[0]
relatedTarget: $previous[0]
})
})
})
})
}
}
Tab.prototype.activate = function (element, container, callback) {
Tab.prototype.activate = function (element, container, callback) {
var $active = container.find('> .active')
var $active = container.find('> .active')
var transition = callback
var transition = callback
&& $.support.transition
&& $.support.transition
&& ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
&& ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
function next() {
function next() {
$active
$active
.removeClass('active')
.removeClass('active')
.find('> .dropdown-menu > .active')
.find('> .dropdown-menu > .active')
.removeClass('active')
.removeClass('active')
.end()
.end()
.find('[data-toggle="tab"]')
.find('[data-toggle="tab"]')
.attr('aria-expanded', false)
.attr('aria-expanded', false)
element
element
.addClass('active')
.addClass('active')
.find('[data-toggle="tab"]')
.find('[data-toggle="tab"]')
.attr('aria-expanded', true)
.attr('aria-expanded', true)
if (transition) {
if (transition) {
element[0].offsetWidth // reflow for transition
element[0].offsetWidth // reflow for transition
element.addClass('in')
element.addClass('in')
} else {
} else {
element.removeClass('fade')
element.removeClass('fade')
}
}
if (element.parent('.dropdown-menu').length) {
if (element.parent('.dropdown-menu').length) {
element
element
.closest('li.dropdown')
.closest('li.dropdown')
.addClass('active')
.addClass('active')
.end()
.end()
.find('[data-toggle="tab"]')
.find('[data-toggle="tab"]')
.attr('aria-expanded', true)
.attr('aria-expanded', true)
}
}
callback && callback()
callback && callback()
}
}
$active.length && transition ?
$active.length && transition ?
$active
$active
.one('bsTransitionEnd', next)
.one('bsTransitionEnd', next)
.emulateTransitionEnd(Tab.TRANSITION_DURATION) :
.emulateTransitionEnd(Tab.TRANSITION_DURATION) :
next()
next()
$active.removeClass('in')
$active.removeClass('in')
}
}
// TAB PLUGIN DEFINITION
// TAB PLUGIN DEFINITION
// =====================
// =====================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.tab')
var data = $this.data('bs.tab')
if (!data) $this.data('bs.tab', (data = new Tab(this)))
if (!data) $this.data('bs.tab', (data = new Tab(this)))
if (typeof option == 'string') data[option]()
if (typeof option == 'string') data[option]()
})
})
}
}
var old = $.fn.tab
var old = $.fn.tab
$.fn.tab = Plugin
$.fn.tab = Plugin
$.fn.tab.Constructor = Tab
$.fn.tab.Constructor = Tab
// TAB NO CONFLICT
// TAB NO CONFLICT
// ===============
// ===============
$.fn.tab.noConflict = function () {
$.fn.tab.noConflict = function () {
$.fn.tab = old
$.fn.tab = old
return this
return this
}
}
// TAB DATA-API
// TAB DATA-API
// ============
// ============
var clickHandler = function (e) {
var clickHandler = function (e) {
e.preventDefault()
e.preventDefault()
Plugin.call($(this), 'show')
Plugin.call($(this), 'show')
}
}
$(document)
$(document)
.on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
.on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
.on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
.on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
}(jQuery);
}(jQuery);
/* ========================================================================
/* ========================================================================
* Bootstrap: affix.js v3.3.7
* Bootstrap: affix.js v3.3.7
* http://getbootstrap.com/javascript/#affix
* http://getbootstrap.com/javascript/#affix
* ========================================================================
* ========================================================================
* Copyright 2011-2016 Twitter, Inc.
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
* ======================================================================== */
+function ($) {
+function ($) {
'use strict';
'use strict';
// AFFIX CLASS DEFINITION
// AFFIX CLASS DEFINITION
// ======================
// ======================
var Affix = function (element, options) {
var Affix = function (element, options) {
this.options = $.extend({}, Affix.DEFAULTS, options)
this.options = $.extend({}, Affix.DEFAULTS, options)
this.$target = $(this.options.target)
this.$target = $(this.options.target)
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
this.$element = $(element)
this.$element = $(element)
this.affixed = null
this.affixed = null
this.unpin = null
this.unpin = null
this.pinnedOffset = null
this.pinnedOffset = null
this.checkPosition()
this.checkPosition()
}
}
Affix.VERSION = '3.3.7'
Affix.VERSION = '3.3.7'
Affix.RESET = 'affix affix-top affix-bottom'
Affix.RESET = 'affix affix-top affix-bottom'
Affix.DEFAULTS = {
Affix.DEFAULTS = {
offset: 0,
offset: 0,
target: window
target: window
}
}
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
var scrollTop = this.$target.scrollTop()
var scrollTop = this.$target.scrollTop()
var position = this.$element.offset()
var position = this.$element.offset()
var targetHeight = this.$target.height()
var targetHeight = this.$target.height()
if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
if (offsetTop != null && this.affixed === 'top') return scrollTop < offsetTop ? 'top' : false
if (this.affixed == 'bottom') {
if (this.affixed === 'bottom') {
if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
}
}
var initializing = this.affixed == null
var initializing = this.affixed == null
var colliderTop = initializing ? scrollTop : position.top
var colliderTop = initializing ? scrollTop : position.top
var colliderHeight = initializing ? targetHeight : height
var colliderHeight = initializing ? targetHeight : height
if (offsetTop != null && scrollTop <= offsetTop) return 'top'
if (offsetTop != null && scrollTop <= offsetTop) return 'top'
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
return false
return false
}
}
Affix.prototype.getPinnedOffset = function () {
Affix.prototype.getPinnedOffset = function () {
if (this.pinnedOffset) return this.pinnedOffset
if (this.pinnedOffset) return this.pinnedOffset
this.$element.removeClass(Affix.RESET).addClass('affix')
this.$element.removeClass(Affix.RESET).addClass('affix')
var scrollTop = this.$target.scrollTop()
var scrollTop = this.$target.scrollTop()
var position = this.$element.offset()
var position = this.$element.offset()
return (this.pinnedOffset = position.top - scrollTop)
return (this.pinnedOffset = position.top - scrollTop)
}
}
Affix.prototype.checkPositionWithEventLoop = function () {
Affix.prototype.checkPositionWithEventLoop = function () {
setTimeout($.proxy(this.checkPosition, this), 1)
setTimeout($.proxy(this.checkPosition, this), 1)
}
}
Affix.prototype.checkPosition = function () {
Affix.prototype.checkPosition = function () {
if (!this.$element.is(':visible')) return
if (!this.$element.is(':visible')) return
var height = this.$element.height()
var height = this.$element.height()
var offset = this.options.offset
var offset = this.options.offset
var offsetTop = offset.top
var offsetTop = offset.top
var offsetBottom = offset.bottom
var offsetBottom = offset.bottom
var scrollHeight = Math.max($(document).height(), $(document.body).height())
var scrollHeight = Math.max($(document).height(), $(document.body).height())
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
if (this.affixed != affix) {
if (this.affixed !== affix) {
if (this.unpin != null) this.$element.css('top', '')
if (this.unpin != null) this.$element.css('top', '')
var affixType = 'affix' + (affix ? '-' + affix : '')
var affixType = 'affix' + (affix ? '-' + affix : '')
var e = $.Event(affixType + '.bs.affix')
var e = $.Event(affixType + '.bs.affix')
this.$element.trigger(e)
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
if (e.isDefaultPrevented()) return
this.affixed = affix
this.affixed = affix
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
this.unpin = affix === 'bottom' ? this.getPinnedOffset() : null
this.$element
this.$element
.removeClass(Affix.RESET)
.removeClass(Affix.RESET)
.addClass(affixType)
.addClass(affixType)
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
}
}
if (affix == 'bottom') {
if (affix === 'bottom') {
this.$element.offset({
this.$element.offset({
top: scrollHeight - height - offsetBottom
top: scrollHeight - height - offsetBottom
})
})
}
}
}
}
// AFFIX PLUGIN DEFINITION
// AFFIX PLUGIN DEFINITION
// =======================
// =======================
function Plugin(option) {
function Plugin(option) {
return this.each(function () {
return this.each(function () {
var $this = $(this)
var $this = $(this)
var data = $this.data('bs.affix')
var data = $this.data('bs.affix')
var options = typeof option == 'object' && option
var options = typeof option == 'object' && option
if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
if (typeof option == 'string') data[option]()
if (typeof option == 'string') data[option]()
})
})
}
}
var old = $.fn.affix
var old = $.fn.affix
$.fn.affix = Plugin
$.fn.affix = Plugin
$.fn.affix.Constructor = Affix
$.fn.affix.Constructor = Affix
// AFFIX NO CONFLICT
// AFFIX NO CONFLICT
// =================
// =================
$.fn.affix.noConflict = function () {
$.fn.affix.noConflict = function () {
$.fn.affix = old
$.fn.affix = old
return this
return this
}
}
// AFFIX DATA-API
// AFFIX DATA-API
// ==============
// ==============
$(window).on('load', function () {
$(window).on('load', function () {
$('[data-spy="affix"]').each(function () {
$('[data-spy="affix"]').each(function () {
var $spy = $(this)
var $spy = $(this)
var data = $spy.data()
var data = $spy.data()
data.offset = data.offset || {}
data.offset = data.offset || {}
if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
if (data.offsetTop != null) data.offset.top = data.offsetTop
if (data.offsetTop != null) data.offset.top = data.offsetTop
Plugin.call($spy, data)
Plugin.call($spy, data)
})
})
})
})
}(jQuery);
}(jQuery);
M js/modernizr.js
+3 −9
window.Modernizr = (function( window, document, undefined ) {
window.Modernizr = (function( window, document, undefined ) {
var version = '2.8.2',
var version = '2.8.2',
Modernizr = {},
Modernizr = {},
/*>>cssclasses*/
/*>>cssclasses*/
// option for enabling the HTML classes to be added
// option for enabling the HTML classes to be added
enableClasses = true,
enableClasses = true,
/*>>cssclasses*/
/*>>cssclasses*/
docElement = document.documentElement,
docElement = document.documentElement,
/**
/**
* Create our "modernizr" element that we do most feature tests on.
* Create our "modernizr" element that we do most feature tests on.
*/
*/
mod = 'modernizr',
mod = 'modernizr',
modElem = document.createElement(mod),
modElem = document.createElement(mod),
mStyle = modElem.style,
mStyle = modElem.style,
/**
/**
* Create the input element for various Web Forms feature tests.
* Create the input element for various Web Forms feature tests.
*/
*/
inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ ,
inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ ,
/*>>smile*/
/*>>smile*/
smile = ':)',
smile = ':)',
/*>>smile*/
/*>>smile*/
toString = {}.toString,
toString = {}.toString,
// TODO :: make the prefixes more granular
// TODO :: make the prefixes more granular
/*>>prefixes*/
/*>>prefixes*/
// List of property values to set for css tests. See ticket #21
// List of property values to set for css tests. See ticket #21
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
/*>>prefixes*/
/*>>prefixes*/
/*>>domprefixes*/
/*>>domprefixes*/
// Following spec is to expose vendor-specific style properties as:
// Following spec is to expose vendor-specific style properties as:
// elem.style.WebkitBorderRadius
// elem.style.WebkitBorderRadius
// and the following would be incorrect:
// and the following would be incorrect:
// elem.style.webkitBorderRadius
// elem.style.webkitBorderRadius
// Webkit ghosts their properties in lowercase but Opera & Moz do not.
// Webkit ghosts their properties in lowercase but Opera & Moz do not.
// Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
// Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
// erik.eae.net/archives/2008/03/10/21.48.10/
// erik.eae.net/archives/2008/03/10/21.48.10/
// More here: github.com/Modernizr/Modernizr/issues/issue/21
// More here: github.com/Modernizr/Modernizr/issues/issue/21
omPrefixes = 'Webkit Moz O ms',
omPrefixes = 'Webkit Moz O ms',
cssomPrefixes = omPrefixes.split(' '),
cssomPrefixes = omPrefixes.split(' '),
domPrefixes = omPrefixes.toLowerCase().split(' '),
domPrefixes = omPrefixes.toLowerCase().split(' '),
/*>>domprefixes*/
/*>>domprefixes*/
/*>>ns*/
/*>>ns*/
ns = {'svg': 'http://www.w3.org/2000/svg'},
ns = {'svg': 'http://www.w3.org/2000/svg'},
/*>>ns*/
/*>>ns*/
tests = {},
tests = {},
inputs = {},
inputs = {},
attrs = {},
attrs = {},
classes = [],
classes = [],
slice = classes.slice,
slice = classes.slice,
featureName, // used in testing loop
featureName, // used in testing loop
/*>>teststyles*/
/*>>teststyles*/
// Inject element with style element and some CSS rules
// Inject element with style element and some CSS rules
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
var style, ret, node, docOverflow,
var style, ret, node, docOverflow,
div = document.createElement('div'),
div = document.createElement('div'),
// After page load injecting a fake body doesn't work so check if body exists
// After page load injecting a fake body doesn't work so check if body exists
body = document.body,
body = document.body,
// IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
// IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
fakeBody = body || document.createElement('body');
fakeBody = body || document.createElement('body');
if ( parseInt(nodes, 10) ) {
if ( parseInt(nodes, 10) ) {
// In order not to give false positives we create a node for each test
// In order not to give false positives we create a node for each test
// This also allows the method to scale for unspecified uses
// This also allows the method to scale for unspecified uses
while ( nodes-- ) {
while ( nodes-- ) {
node = document.createElement('div');
node = document.createElement('div');
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
div.appendChild(node);
div.appendChild(node);
}
}
}
}
// <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
// <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
// when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
// when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
// with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
// with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
// msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
// msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
// Documents served as xml will throw if using &shy; so use xml friendly encoded version. See issue #277
// Documents served as xml will throw if using &shy; so use xml friendly encoded version. See issue #277
style = ['&#173;','<style id="s', mod, '">', rule, '</style>'].join('');
style = ['&#173;','<style id="s', mod, '">', rule, '</style>'].join('');
div.id = mod;
div.id = mod;
// IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
// IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
// Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
// Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
(body ? div : fakeBody).innerHTML += style;
(body ? div : fakeBody).innerHTML += style;
fakeBody.appendChild(div);
fakeBody.appendChild(div);
if ( !body ) {
if ( !body ) {
//avoid crashing IE8, if background image is used
//avoid crashing IE8, if background image is used
fakeBody.style.background = '';
fakeBody.style.background = '';
//Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
//Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
fakeBody.style.overflow = 'hidden';
fakeBody.style.overflow = 'hidden';
docOverflow = docElement.style.overflow;
docOverflow = docElement.style.overflow;
docElement.style.overflow = 'hidden';
docElement.style.overflow = 'hidden';
docElement.appendChild(fakeBody);
docElement.appendChild(fakeBody);
}
}
ret = callback(div, rule);
ret = callback(div, rule);
// If this is done after page load we don't want to remove the body so check if body exists
// If this is done after page load we don't want to remove the body so check if body exists
if ( !body ) {
if ( !body ) {
fakeBody.parentNode.removeChild(fakeBody);
fakeBody.parentNode.removeChild(fakeBody);
docElement.style.overflow = docOverflow;
docElement.style.overflow = docOverflow;
} else {
} else {
div.parentNode.removeChild(div);
div.parentNode.removeChild(div);
}
}
return !!ret;
return !!ret;
},
},
/*>>teststyles*/
/*>>teststyles*/
/*>>mq*/
/*>>mq*/
// adapted from matchMedia polyfill
// adapted from matchMedia polyfill
// by Scott Jehl and Paul Irish
// by Scott Jehl and Paul Irish
// gist.github.com/786768
// gist.github.com/786768
testMediaQuery = function( mq ) {
testMediaQuery = function( mq ) {
var matchMedia = window.matchMedia || window.msMatchMedia;
var matchMedia = window.matchMedia || window.msMatchMedia;
if ( matchMedia ) {
if ( matchMedia ) {
return matchMedia(mq) && matchMedia(mq).matches || false;
return matchMedia(mq) && matchMedia(mq).matches || false;
}
}
var bool;
var bool;
injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
bool = (window.getComputedStyle ?
bool = (window.getComputedStyle ?
getComputedStyle(node, null) :
getComputedStyle(node, null) :
node.currentStyle)['position'] === 'absolute';
node.currentStyle)['position'] === 'absolute';
});
});
return bool;
return bool;
},
},
/*>>mq*/
/*>>mq*/
/*>>hasevent*/
/*>>hasevent*/
//
//
// isEventSupported determines if a given element supports the given event
// isEventSupported determines if a given element supports the given event
// kangax.github.com/iseventsupported/
// kangax.github.com/iseventsupported/
//
//
// The following results are known incorrects:
// The following results are known incorrects:
// Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative
// Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative
// Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333
// Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333
// ...
// ...
isEventSupported = (function() {
isEventSupported = (function() {
var TAGNAMES = {
var TAGNAMES = {
'select': 'input', 'change': 'input',
'select': 'input', 'change': 'input',
'submit': 'form', 'reset': 'form',
'submit': 'form', 'reset': 'form',
'error': 'img', 'load': 'img', 'abort': 'img'
'error': 'img', 'load': 'img', 'abort': 'img'
};
};
function isEventSupported( eventName, element ) {
function isEventSupported( eventName, element ) {
element = element || document.createElement(TAGNAMES[eventName] || 'div');
element = element || document.createElement(TAGNAMES[eventName] || 'div');
eventName = 'on' + eventName;
eventName = 'on' + eventName;
// When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
// When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
var isSupported = eventName in element;
var isSupported = eventName in element;
if ( !isSupported ) {
if ( !isSupported ) {
// If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
// If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
if ( !element.setAttribute ) {
if ( !element.setAttribute ) {
element = document.createElement('div');
element = document.createElement('div');
}
}
if ( element.setAttribute && element.removeAttribute ) {
if ( element.setAttribute && element.removeAttribute ) {
element.setAttribute(eventName, '');
element.setAttribute(eventName, '');
isSupported = is(element[eventName], 'function');
isSupported = is(element[eventName], 'function');
// If property was created, "remove it" (by setting value to `undefined`)
// If property was created, "remove it" (by setting value to `undefined`)
if ( !is(element[eventName], 'undefined') ) {
if ( !is(element[eventName], 'undefined') ) {
element[eventName] = undefined;
element[eventName] = undefined;
}
}
element.removeAttribute(eventName);
element.removeAttribute(eventName);
}
}
}
}
element = null;
element = null;
return isSupported;
return isSupported;
}
}
return isEventSupported;
return isEventSupported;
})(),
})(),
/*>>hasevent*/
/*>>hasevent*/
// TODO :: Add flag for hasownprop ? didn't last time
// TODO :: Add flag for hasownprop ? didn't last time
// hasOwnProperty shim by kangax needed for Safari 2.0 support
// hasOwnProperty shim by kangax needed for Safari 2.0 support
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
hasOwnProp = function (object, property) {
hasOwnProp = function (object, property) {
return _hasOwnProperty.call(object, property);
return _hasOwnProperty.call(object, property);
};
};
}
}
else {
else {
hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
};
};
}
}
// Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
// Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
// es5.github.com/#x15.3.4.5
// es5.github.com/#x15.3.4.5
if (!Function.prototype.bind) {
if (!Function.prototype.bind) {
Function.prototype.bind = function bind(that) {
Function.prototype.bind = function bind(that) {
var target = this;
var target = this;
if (typeof target != "function") {
if (typeof target != "function") {
throw new TypeError();
throw new TypeError();
}
}
var args = slice.call(arguments, 1),
var args = slice.call(arguments, 1),
bound = function () {
bound = function () {
if (this instanceof bound) {
if (this instanceof bound) {
var F = function(){};
var F = function(){};
F.prototype = target.prototype;
F.prototype = target.prototype;
var self = new F();
var self = new F();
var result = target.apply(
var result = target.apply(
self,
self,
args.concat(slice.call(arguments))
args.concat(slice.call(arguments))
);
);
if (Object(result) === result) {
if (Object(result) === result) {
return result;
return result;
}
}
return self;
return self;
} else {
} else {
return target.apply(
return target.apply(
that,
that,
args.concat(slice.call(arguments))
args.concat(slice.call(arguments))
);
);
}
}
};
};
return bound;
return bound;
};
};
}
}
/**
/**
* setCss applies given styles to the Modernizr DOM node.
* setCss applies given styles to the Modernizr DOM node.
*/
*/
function setCss( str ) {
function setCss( str ) {
mStyle.cssText = str;
mStyle.cssText = str;
}
}
/**
/**
* setCssAll extrapolates all vendor-specific css strings.
* setCssAll extrapolates all vendor-specific css strings.
*/
*/
function setCssAll( str1, str2 ) {
function setCssAll( str1, str2 ) {
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
}
}
/**
/**
* is returns a boolean for if typeof obj is exactly type.
* is returns a boolean for if typeof obj is exactly type.
*/
*/
function is( obj, type ) {
function is( obj, type ) {
return typeof obj === type;
return typeof obj === type;
}
}
/**
/**
* contains returns a boolean for if substr is found within str.
* contains returns a boolean for if substr is found within str.
*/
*/
function contains( str, substr ) {
function contains( str, substr ) {
if(('' + str).indexOf(substr) == -1) {
if(('' + str).indexOf(substr) == -1) {
return false;
return false;
} else{
} else{
return true;
return true;
}
}
//return !!~('' + str).indexOf(substr);
//return !!~('' + str).indexOf(substr);
}
}
/*>>testprop*/
/*>>testprop*/
// testProps is a generic CSS / DOM property test.
// testProps is a generic CSS / DOM property test.
// In testing support for a given CSS property, it's legit to test:
// In testing support for a given CSS property, it's legit to test:
// `elem.style[styleName] !== undefined`
// `elem.style[styleName] !== undefined`
// If the property is supported it will return an empty string,
// If the property is supported it will return an empty string,
// if unsupported it will return undefined.
// if unsupported it will return undefined.
// We'll take advantage of this quick test and skip setting a style
// We'll take advantage of this quick test and skip setting a style
// on our modernizr element, but instead just testing undefined vs
// on our modernizr element, but instead just testing undefined vs
// empty string.
// empty string.
// Because the testing of the CSS property names (with "-", as
// Because the testing of the CSS property names (with "-", as
// opposed to the camelCase DOM properties) is non-portable and
// opposed to the camelCase DOM properties) is non-portable and
// non-standard but works in WebKit and IE (but not Gecko or Opera),
// non-standard but works in WebKit and IE (but not Gecko or Opera),
// we explicitly reject properties with dashes so that authors
// we explicitly reject properties with dashes so that authors
// developing in WebKit or IE first don't end up with
// developing in WebKit or IE first don't end up with
// browser-specific content by accident.
// browser-specific content by accident.
function testProps( props, prefixed ) {
function testProps( props, prefixed ) {
for ( var i in props ) {
for ( var i in props ) {
var prop = props[i];
var prop = props[i];
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
return prefixed === 'pfx' ? prop : true;
return prefixed === 'pfx' ? prop : true;
}
}
}
}
return false;
return false;
}
}
/*>>testprop*/
/*>>testprop*/
// TODO :: add testDOMProps
// TODO :: add testDOMProps
/**
/**
* testDOMProps is a generic DOM property test; if a browser supports
* testDOMProps is a generic DOM property test; if a browser supports
* a certain property, it won't return undefined for it.
* a certain property, it won't return undefined for it.
*/
*/
function testDOMProps( props, obj, elem ) {
function testDOMProps( props, obj, elem ) {
for ( var i in props ) {
for ( var i in props ) {
var item = obj[props[i]];
var item = obj[props[i]];
if ( item !== undefined) {
if ( item !== undefined) {
// return the property name as a string
// return the property name as a string
if (elem === false) return props[i];
if (elem === false) return props[i];
// let's bind a function
// let's bind a function
if (is(item, 'function')){
if (is(item, 'function')){
// default to autobind unless override
// default to autobind unless override
return item.bind(elem || obj);
return item.bind(elem || obj);
}
}
// return the unbound function or obj or value
// return the unbound function or obj or value
return item;
return item;
}
}
}
}
return false;
return false;
}
}
/*>>testallprops*/
/*>>testallprops*/
/**
/**
* testPropsAll tests a list of DOM properties we want to check against.
* testPropsAll tests a list of DOM properties we want to check against.
* We specify literally ALL possible (known and/or likely) properties on
* We specify literally ALL possible (known and/or likely) properties on
* the element including the non-vendor prefixed one, for forward-
* the element including the non-vendor prefixed one, for forward-
* compatibility.
* compatibility.
*/
*/
function testPropsAll( prop, prefixed, elem ) {
function testPropsAll( prop, prefixed, elem ) {
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
// did they call .prefixed('boxSizing') or are we just testing a prop?
// did they call .prefixed('boxSizing') or are we just testing a prop?
if(is(prefixed, "string") || is(prefixed, "undefined")) {
if(is(prefixed, "string") || is(prefixed, "undefined")) {
return testProps(props, prefixed);
return testProps(props, prefixed);
// otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
// otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
} else {
} else {
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
return testDOMProps(props, prefixed, elem);
return testDOMProps(props, prefixed, elem);
}
}
}
}
/*>>testallprops*/
/*>>testallprops*/
/**
/**
* Tests
* Tests
* -----
* -----
*/
*/
// The *new* flexbox
// The *new* flexbox
// dev.w3.org/csswg/css3-flexbox
// dev.w3.org/csswg/css3-flexbox
tests['flexbox'] = function() {
tests['flexbox'] = function() {
return testPropsAll('flexWrap');
return testPropsAll('flexWrap');
};
};
// The *old* flexbox
// The *old* flexbox
// www.w3.org/TR/2009/WD-css3-flexbox-20090723/
// www.w3.org/TR/2009/WD-css3-flexbox-20090723/
tests['flexboxlegacy'] = function() {
tests['flexboxlegacy'] = function() {
return testPropsAll('boxDirection');
return testPropsAll('boxDirection');
};
};
// On the S60 and BB Storm, getContext exists, but always returns undefined
// On the S60 and BB Storm, getContext exists, but always returns undefined
// so we actually have to call getContext() to verify
// so we actually have to call getContext() to verify
// github.com/Modernizr/Modernizr/issues/issue/97/
// github.com/Modernizr/Modernizr/issues/issue/97/
tests['canvas'] = function() {
tests['canvas'] = function() {
var elem = document.createElement('canvas');
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
return !!(elem.getContext && elem.getContext('2d'));
};
};
tests['canvastext'] = function() {
tests['canvastext'] = function() {
return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
};
};
// webk.it/70117 is tracking a legit WebGL feature detect proposal
// webk.it/70117 is tracking a legit WebGL feature detect proposal
// We do a soft detect which may false positive in order to avoid
// We do a soft detect which may false positive in order to avoid
// an expensive context creation: bugzil.la/732441
// an expensive context creation: bugzil.la/732441
tests['webgl'] = function() {
tests['webgl'] = function() {
return !!window.WebGLRenderingContext;
return !!window.WebGLRenderingContext;
};
};
/*
/*
* The Modernizr.touch test only indicates if the browser supports
* The Modernizr.touch test only indicates if the browser supports
* touch events, which does not necessarily reflect a touchscreen
* touch events, which does not necessarily reflect a touchscreen
* device, as evidenced by tablets running Windows 7 or, alas,
* device, as evidenced by tablets running Windows 7 or, alas,
* the Palm Pre / WebOS (touch) phones.
* the Palm Pre / WebOS (touch) phones.
*
*
* Additionally, Chrome (desktop) used to lie about its support on this,
* Additionally, Chrome (desktop) used to lie about its support on this,
* but that has since been rectified: crbug.com/36415
* but that has since been rectified: crbug.com/36415
*
*
* We also test for Firefox 4 Multitouch Support.
* We also test for Firefox 4 Multitouch Support.
*
*
* For more info, see: modernizr.github.com/Modernizr/touch.html
* For more info, see: modernizr.github.com/Modernizr/touch.html
*/
*/
tests['touch'] = function() {
tests['touch'] = function() {
var bool;
var bool;
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
bool = true;
} else {
} else {
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
bool = node.offsetTop === 9;
bool = node.offsetTop === 9;
});
});
}
}
return bool;
return bool;
};
};
// geolocation is often considered a trivial feature detect...
// geolocation is often considered a trivial feature detect...
// Turns out, it's quite tricky to get right:
// Turns out, it's quite tricky to get right:
//
//
// Using !!navigator.geolocation does two things we don't want. It:
// Using !!navigator.geolocation does two things we don't want. It:
// 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
// 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
// 2. Disables page caching in WebKit: webk.it/43956
// 2. Disables page caching in WebKit: webk.it/43956
//
//
// Meanwhile, in Firefox < 8, an about:config setting could expose
// Meanwhile, in Firefox < 8, an about:config setting could expose
// a false positive that would throw an exception: bugzil.la/688158
// a false positive that would throw an exception: bugzil.la/688158
tests['geolocation'] = function() {
tests['geolocation'] = function() {
return 'geolocation' in navigator;
return 'geolocation' in navigator;
};
};
tests['postmessage'] = function() {
tests['postmessage'] = function() {
return !!window.postMessage;
return !!window.postMessage;
};
};
// Chrome incognito mode used to throw an exception when using openDatabase
// Chrome incognito mode used to throw an exception when using openDatabase
// It doesn't anymore.
// It doesn't anymore.
tests['websqldatabase'] = function() {
tests['websqldatabase'] = function() {
return !!window.openDatabase;
return !!window.openDatabase;
};
};
// Vendors had inconsistent prefixing with the experimental Indexed DB:
// Vendors had inconsistent prefixing with the experimental Indexed DB:
// - Webkit's implementation is accessible through webkitIndexedDB
// - Webkit's implementation is accessible through webkitIndexedDB
// - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
// - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
// For speed, we don't test the legacy (and beta-only) indexedDB
// For speed, we don't test the legacy (and beta-only) indexedDB
tests['indexedDB'] = function() {
tests['indexedDB'] = function() {
return !!testPropsAll("indexedDB", window);
return !!testPropsAll("indexedDB", window);
};
};
// documentMode logic from YUI to filter out IE8 Compat Mode
// documentMode logic from YUI to filter out IE8 Compat Mode
// which false positives.
// which false positives.
tests['hashchange'] = function() {
tests['hashchange'] = function() {
return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
};
};
// Per 1.6:
// Per 1.6:
// This used to be Modernizr.historymanagement but the longer
// This used to be Modernizr.historymanagement but the longer
// name has been deprecated in favor of a shorter and property-matching one.
// name has been deprecated in favor of a shorter and property-matching one.
// The old API is still available in 1.6, but as of 2.0 will throw a warning,
// The old API is still available in 1.6, but as of 2.0 will throw a warning,
// and in the first release thereafter disappear entirely.
// and in the first release thereafter disappear entirely.
tests['history'] = function() {
tests['history'] = function() {
return !!(window.history && history.pushState);
return !!(window.history && history.pushState);
};
};
tests['draganddrop'] = function() {
tests['draganddrop'] = function() {
var div = document.createElement('div');
var div = document.createElement('div');
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
};
};
// FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10
// FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10
// will be supported until FF19 (2/12/13), at which time, ESR becomes FF17.
// will be supported until FF19 (2/12/13), at which time, ESR becomes FF17.
// FF10 still uses prefixes, so check for it until then.
// FF10 still uses prefixes, so check for it until then.
// for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/
// for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/
tests['websockets'] = function() {
tests['websockets'] = function() {
return 'WebSocket' in window || 'MozWebSocket' in window;
return 'WebSocket' in window || 'MozWebSocket' in window;
};
};
// css-tricks.com/rgba-browser-support/
// css-tricks.com/rgba-browser-support/
tests['rgba'] = function() {
tests['rgba'] = function() {
// Set an rgba() color and check the returned value
// Set an rgba() color and check the returned value
setCss('background-color:rgba(150,255,150,.5)');
setCss('background-color:rgba(150,255,150,.5)');
return contains(mStyle.backgroundColor, 'rgba');
return contains(mStyle.backgroundColor, 'rgba');
};
};
tests['hsla'] = function() {
tests['hsla'] = function() {
// Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
// Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
// except IE9 who retains it as hsla
// except IE9 who retains it as hsla
setCss('background-color:hsla(120,40%,100%,.5)');
setCss('background-color:hsla(120,40%,100%,.5)');
return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
};
};
tests['multiplebgs'] = function() {
tests['multiplebgs'] = function() {
// Setting multiple images AND a color on the background shorthand property
// Setting multiple images AND a color on the background shorthand property
// and then querying the style.background property value for the number of
// and then querying the style.background property value for the number of
// occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
// occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
setCss('background:url(https://),url(https://),red url(https://)');
setCss('background:url(https://),url(https://),red url(https://)');
// If the UA supports multiple backgrounds, there should be three occurrences
// If the UA supports multiple backgrounds, there should be three occurrences
// of the string "url(" in the return value for elemStyle.background
// of the string "url(" in the return value for elemStyle.background
return (/(url\s*\(.*?){3}/).test(mStyle.background);
return (/(url\s*\(.*?){3}/).test(mStyle.background);
};
};
// this will false positive in Opera Mini
// this will false positive in Opera Mini
// github.com/Modernizr/Modernizr/issues/396
// github.com/Modernizr/Modernizr/issues/396
tests['backgroundsize'] = function() {
tests['backgroundsize'] = function() {
return testPropsAll('backgroundSize');
return testPropsAll('backgroundSize');
};
};
tests['borderimage'] = function() {
tests['borderimage'] = function() {
return testPropsAll('borderImage');
return testPropsAll('borderImage');
};
};
// Super comprehensive table about all the unique implementations of
// Super comprehensive table about all the unique implementations of
// border-radius: muddledramblings.com/table-of-css3-border-radius-compliance
// border-radius: muddledramblings.com/table-of-css3-border-radius-compliance
tests['borderradius'] = function() {
tests['borderradius'] = function() {
return testPropsAll('borderRadius');
return testPropsAll('borderRadius');
};
};
// WebOS unfortunately false positives on this test.
// WebOS unfortunately false positives on this test.
tests['boxshadow'] = function() {
tests['boxshadow'] = function() {
return testPropsAll('boxShadow');
return testPropsAll('boxShadow');
};
};
// FF3.0 will false positive on this test
// FF3.0 will false positive on this test
tests['textshadow'] = function() {
tests['textshadow'] = function() {
return document.createElement('div').style.textShadow === '';
return document.createElement('div').style.textShadow === '';
};
};
tests['opacity'] = function() {
tests['opacity'] = function() {
// Browsers that actually have CSS Opacity implemented have done so
// Browsers that actually have CSS Opacity implemented have done so
// according to spec, which means their return values are within the
// according to spec, which means their return values are within the
// range of [0.0,1.0] - including the leading zero.
// range of [0.0,1.0] - including the leading zero.
setCssAll('opacity:.55');
setCssAll('opacity:.55');
// The non-literal . in this regex is intentional:
// The non-literal . in this regex is intentional:
// German Chrome returns this value as 0,55
// German Chrome returns this value as 0,55
// github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
// github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
return (/^0.55$/).test(mStyle.opacity);
return (/^0.55$/).test(mStyle.opacity);
};
};
// Note, Android < 4 will pass this test, but can only animate
// Note, Android < 4 will pass this test, but can only animate
// a single property at a time
// a single property at a time
// goo.gl/v3V4Gp
// goo.gl/v3V4Gp
tests['cssanimations'] = function() {
tests['cssanimations'] = function() {
return testPropsAll('animationName');
return testPropsAll('animationName');
};
};
tests['csscolumns'] = function() {
tests['csscolumns'] = function() {
return testPropsAll('columnCount');
return testPropsAll('columnCount');
};
};
tests['cssgradients'] = function() {
tests['cssgradients'] = function() {
/**
/**
* For CSS Gradients syntax, please see:
* For CSS Gradients syntax, please see:
* webkit.org/blog/175/introducing-css-gradients/
* webkit.org/blog/175/introducing-css-gradients/
* developer.mozilla.org/en/CSS/-moz-linear-gradient
* developer.mozilla.org/en/CSS/-moz-linear-gradient
* developer.mozilla.org/en/CSS/-moz-radial-gradient
* developer.mozilla.org/en/CSS/-moz-radial-gradient
* dev.w3.org/csswg/css3-images/#gradients-
* dev.w3.org/csswg/css3-images/#gradients-
*/
*/
var str1 = 'background-image:',
var str1 = 'background-image:',
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
str3 = 'linear-gradient(left top,#9f9, white);';
str3 = 'linear-gradient(left top,#9f9, white);';
setCss(
setCss(
// legacy webkit syntax (FIXME: remove when syntax not in use anymore)
// legacy webkit syntax (FIXME: remove when syntax not in use anymore)
(str1 + '-webkit- '.split(' ').join(str2 + str1) +
(str1 + '-webkit- '.split(' ').join(str2 + str1) +
// standard syntax // trailing 'background-image:'
// standard syntax // trailing 'background-image:'
prefixes.join(str3 + str1)).slice(0, -str1.length)
prefixes.join(str3 + str1)).slice(0, -str1.length)
);
);
return contains(mStyle.backgroundImage, 'gradient');
return contains(mStyle.backgroundImage, 'gradient');
};
};
tests['cssreflections'] = function() {
tests['cssreflections'] = function() {
return testPropsAll('boxReflect');
return testPropsAll('boxReflect');
};
};
tests['csstransforms'] = function() {
tests['csstransforms'] = function() {
return !!testPropsAll('transform');
return !!testPropsAll('transform');
};
};
tests['csstransforms3d'] = function() {
tests['csstransforms3d'] = function() {
var ret = !!testPropsAll('perspective');
var ret = !!testPropsAll('perspective');
// Webkit's 3D transforms are passed off to the browser's own graphics renderer.
// Webkit's 3D transforms are passed off to the browser's own graphics renderer.
// It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
// It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
// some conditions. As a result, Webkit typically recognizes the syntax but
// some conditions. As a result, Webkit typically recognizes the syntax but
// will sometimes throw a false positive, thus we must do a more thorough check:
// will sometimes throw a false positive, thus we must do a more thorough check:
if ( ret && 'webkitPerspective' in docElement.style ) {
if ( ret && 'webkitPerspective' in docElement.style ) {
// Webkit allows this media query to succeed only if the feature is enabled.
// Webkit allows this media query to succeed only if the feature is enabled.
// `@media (transform-3d),(-webkit-transform-3d){ ... }`
// `@media (transform-3d),(-webkit-transform-3d){ ... }`
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
});
});
}
}
return ret;
return ret;
};
};
tests['csstransitions'] = function() {
tests['csstransitions'] = function() {
return testPropsAll('transition');
return testPropsAll('transition');
};
};
/*>>fontface*/
/*>>fontface*/
// @font-face detection routine by Diego Perini
// @font-face detection routine by Diego Perini
// javascript.nwbox.com/CSSSupport/
// javascript.nwbox.com/CSSSupport/
// false positives:
// false positives:
// WebOS github.com/Modernizr/Modernizr/issues/342
// WebOS github.com/Modernizr/Modernizr/issues/342
// WP7 github.com/Modernizr/Modernizr/issues/538
// WP7 github.com/Modernizr/Modernizr/issues/538
tests['fontface'] = function() {
tests['fontface'] = function() {
var bool;
var bool;
injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) {
injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) {
var style = document.getElementById('smodernizr'),
var style = document.getElementById('smodernizr'),
sheet = style.sheet || style.styleSheet,
sheet = style.sheet || style.styleSheet,
cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
});
});
return bool;
return bool;
};
};
/*>>fontface*/
/*>>fontface*/
// CSS generated content detection
// CSS generated content detection
tests['generatedcontent'] = function() {
tests['generatedcontent'] = function() {
var bool;
var bool;
injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) {
injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) {
bool = node.offsetHeight >= 3;
bool = node.offsetHeight >= 3;
});
});
return bool;
return bool;
};
};
// These tests evaluate support of the video/audio elements, as well as
// These tests evaluate support of the video/audio elements, as well as
// testing what types of content they support.
// testing what types of content they support.
//
//
// We're using the Boolean constructor here, so that we can extend the value
// We're using the Boolean constructor here, so that we can extend the value
// e.g. Modernizr.video // true
// e.g. Modernizr.video // true
// Modernizr.video.ogg // 'probably'
// Modernizr.video.ogg // 'probably'
//
//
// Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
// Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
// thx to NielsLeenheer and zcorpan
// thx to NielsLeenheer and zcorpan
// Note: in some older browsers, "no" was a return value instead of empty string.
// Note: in some older browsers, "no" was a return value instead of empty string.
// It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
// It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
// It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
// It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
tests['video'] = function() {
tests['video'] = function() {
var elem = document.createElement('video'),
var elem = document.createElement('video'),
bool = false;
bool = false;
// IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
// IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
try {
try {
if ( bool = !!elem.canPlayType ) {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
// Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
// Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
}
}
} catch(e) { }
} catch(e) { }
return bool;
return bool;
};
};
tests['audio'] = function() {
tests['audio'] = function() {
var elem = document.createElement('audio'),
var elem = document.createElement('audio'),
bool = false;
bool = false;
try {
try {
if ( bool = !!elem.canPlayType ) {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
// Mimetypes accepted:
// Mimetypes accepted:
// developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
// developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
// bit.ly/iphoneoscodecs
// bit.ly/iphoneoscodecs
bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
}
}
} catch(e) { }
} catch(e) { }
return bool;
return bool;
};
};
// In FF4, if disabled, window.localStorage should === null.
// In FF4, if disabled, window.localStorage should === null.
// Normally, we could not test that directly and need to do a
// Normally, we could not test that directly and need to do a
// `('localStorage' in window) && ` test first because otherwise Firefox will
// `('localStorage' in window) && ` test first because otherwise Firefox will
// throw bugzil.la/365772 if cookies are disabled
// throw bugzil.la/365772 if cookies are disabled
// Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
// Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
// will throw the exception:
// will throw the exception:
// QUOTA_EXCEEDED_ERRROR DOM Exception 22.
// QUOTA_EXCEEDED_ERRROR DOM Exception 22.
// Peculiarly, getItem and removeItem calls do not throw.
// Peculiarly, getItem and removeItem calls do not throw.
// Because we are forced to try/catch this, we'll go aggressive.
// Because we are forced to try/catch this, we'll go aggressive.
// Just FWIW: IE8 Compat mode supports these features completely:
// Just FWIW: IE8 Compat mode supports these features completely:
// www.quirksmode.org/dom/html5.html
// www.quirksmode.org/dom/html5.html
// But IE8 doesn't support either with local files
// But IE8 doesn't support either with local files
tests['localstorage'] = function() {
tests['localstorage'] = function() {
try {
try {
localStorage.setItem(mod, mod);
localStorage.setItem(mod, mod);
localStorage.removeItem(mod);
localStorage.removeItem(mod);
return true;
return true;
} catch(e) {
} catch(e) {
return false;
return false;
}
}
};
};
tests['sessionstorage'] = function() {
tests['sessionstorage'] = function() {
try {
try {
sessionStorage.setItem(mod, mod);
sessionStorage.setItem(mod, mod);
sessionStorage.removeItem(mod);
sessionStorage.removeItem(mod);
return true;
return true;
} catch(e) {
} catch(e) {
return false;
return false;
}
}
};
};
tests['webworkers'] = function() {
tests['webworkers'] = function() {
return !!window.Worker;
return !!window.Worker;
};
};
tests['applicationcache'] = function() {
tests['applicationcache'] = function() {
return !!window.applicationCache;
return !!window.applicationCache;
};
};
tests['svg'] = function() {
tests['svg'] = function() {
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
};
};
// specifically for SVG inline in HTML, not within XHTML
// specifically for SVG inline in HTML, not within XHTML
// test page: paulirish.com/demo/inline-svg
// test page: paulirish.com/demo/inline-svg
tests['inlinesvg'] = function() {
tests['inlinesvg'] = function() {
var div = document.createElement('div');
var div = document.createElement('div');
div.innerHTML = '<svg/>';
div.innerHTML = '<svg/>';
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
return (div.firstChild && div.firstChild.namespaceURI) === ns.svg;
};
};
// SVG SMIL animation
// SVG SMIL animation
tests['smil'] = function() {
tests['smil'] = function() {
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
};
};
// This test is only for clip paths in SVG proper, not clip paths on HTML content
// This test is only for clip paths in SVG proper, not clip paths on HTML content
// demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg
// demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg
// However read the comments to dig into applying SVG clippaths to HTML content here:
// However read the comments to dig into applying SVG clippaths to HTML content here:
// github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491
// github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491
tests['svgclippaths'] = function() {
tests['svgclippaths'] = function() {
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
};
};
/*>>webforms*/
/*>>webforms*/
// input features and input types go directly onto the ret object, bypassing the tests loop.
// input features and input types go directly onto the ret object, bypassing the tests loop.
// Hold this guy to execute in a moment.
// Hold this guy to execute in a moment.
function webforms() {
function webforms() {
/*>>input*/
/*>>input*/
// Run through HTML5's new input attributes to see if the UA understands any.
// Run through HTML5's new input attributes to see if the UA understands any.
// We're using f which is the <input> element created early on
// We're using f which is the <input> element created early on
// Mike Taylr has created a comprehensive resource for testing these attributes
// Mike Taylr has created a comprehensive resource for testing these attributes
// when applied to all input types:
// when applied to all input types:
// miketaylr.com/code/input-type-attr.html
// miketaylr.com/code/input-type-attr.html
// spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
// spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
// Only input placeholder is tested while textarea's placeholder is not.
// Only input placeholder is tested while textarea's placeholder is not.
// Currently Safari 4 and Opera 11 have support only for the input placeholder
// Currently Safari 4 and Opera 11 have support only for the input placeholder
// Both tests are available in feature-detects/forms-placeholder.js
// Both tests are available in feature-detects/forms-placeholder.js
Modernizr['input'] = (function( props ) {
Modernizr['input'] = (function( props ) {
for ( var i = 0, len = props.length; i < len; i++ ) {
for ( var i = 0, len = props.length; i < len; i++ ) {
attrs[ props[i] ] = !!(props[i] in inputElem);
attrs[ props[i] ] = !!(props[i] in inputElem);
}
}
if (attrs.list){
if (attrs.list){
// safari false positive's on datalist: webk.it/74252
// safari false positive's on datalist: webk.it/74252
// see also github.com/Modernizr/Modernizr/issues/146
// see also github.com/Modernizr/Modernizr/issues/146
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
}
}
return attrs;
return attrs;
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
/*>>input*/
/*>>input*/
/*>>inputtypes*/
/*>>inputtypes*/
// Run through HTML5's new input types to see if the UA understands any.
// Run through HTML5's new input types to see if the UA understands any.
// This is put behind the tests runloop because it doesn't return a
// This is put behind the tests runloop because it doesn't return a
// true/false like all the other tests; instead, it returns an object
// true/false like all the other tests; instead, it returns an object
// containing each input type with its corresponding true/false value
// containing each input type with its corresponding true/false value
// Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
// Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
Modernizr['inputtypes'] = (function(props) {
Modernizr['inputtypes'] = (function(props) {
for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
inputElem.setAttribute('type', inputElemType = props[i]);
inputElem.setAttribute('type', inputElemType = props[i]);
bool = inputElem.type !== 'text';
bool = inputElem.type !== 'text';
// We first check to see if the type we give it sticks..
// We first check to see if the type we give it sticks..
// If the type does, we feed it a textual value, which shouldn't be valid.
// If the type does, we feed it a textual value, which shouldn't be valid.
// If the value doesn't stick, we know there's input sanitization which infers a custom UI
// If the value doesn't stick, we know there's input sanitization which infers a custom UI
if ( bool ) {
if ( bool ) {
inputElem.value = smile;
inputElem.value = smile;
inputElem.style.cssText = 'position:absolute;visibility:hidden;';
inputElem.style.cssText = 'position:absolute;visibility:hidden;';
if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
docElement.appendChild(inputElem);
docElement.appendChild(inputElem);
defaultView = document.defaultView;
defaultView = document.defaultView;
// Safari 2-4 allows the smiley as a value, despite making a slider
// Safari 2-4 allows the smiley as a value, despite making a slider
bool = defaultView.getComputedStyle &&
bool = defaultView.getComputedStyle &&
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
// Mobile android web browser has false positive, so must
// Mobile android web browser has false positive, so must
// check the height to see if the widget is actually there.
// check the height to see if the widget is actually there.
(inputElem.offsetHeight !== 0);
(inputElem.offsetHeight !== 0);
docElement.removeChild(inputElem);
docElement.removeChild(inputElem);
} else if ( /^(search|tel)$/.test(inputElemType) ){
} else if ( /^(search|tel)$/.test(inputElemType) ){
// Spec doesn't define any special parsing or detectable UI
// Spec doesn't define any special parsing or detectable UI
// behaviors so we pass these through as true
// behaviors so we pass these through as true
// Interestingly, opera fails the earlier test, so it doesn't
// Interestingly, opera fails the earlier test, so it doesn't
// even make it here.
// even make it here.
} else if ( /^(url|email)$/.test(inputElemType) ) {
} else if ( /^(url|email)$/.test(inputElemType) ) {
// Real url and email support comes with prebaked validation.
// Real url and email support comes with prebaked validation.
bool = inputElem.checkValidity && inputElem.checkValidity() === false;
bool = inputElem.checkValidity && inputElem.checkValidity() === false;
} else {
} else {
// If the upgraded input compontent rejects the :) text, we got a winner
// If the upgraded input compontent rejects the :) text, we got a winner
bool = inputElem.value != smile;
bool = inputElem.value !== smile;
}
}
}
}
inputs[ props[i] ] = !!bool;
inputs[ props[i] ] = !!bool;
}
}
return inputs;
return inputs;
})('search tel url email datetime date month week time datetime-local number range color'.split(' '));
})('search tel url email datetime date month week time datetime-local number range color'.split(' '));
/*>>inputtypes*/
/*>>inputtypes*/
}
}
for ( var feature in tests ) {
for ( var feature in tests ) {
if ( hasOwnProp(tests, feature) ) {
if ( hasOwnProp(tests, feature) ) {
// run the test, throw the return value into the Modernizr,
// run the test, throw the return value into the Modernizr,
// then based on that boolean, define an appropriate className
// then based on that boolean, define an appropriate className
// and push it into an array of classes we'll join later.
// and push it into an array of classes we'll join later.
featureName = feature.toLowerCase();
featureName = feature.toLowerCase();
Modernizr[featureName] = tests[feature]();
Modernizr[featureName] = tests[feature]();
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
}
}
}
}
Modernizr.input || webforms();
Modernizr.input || webforms();
/*>>webforms*/
/*>>webforms*/
/**
/**
* addTest allows the user to define their own feature tests
* addTest allows the user to define their own feature tests
* the result will be added onto the Modernizr object,
* the result will be added onto the Modernizr object,
* as well as an appropriate className set on the html element
* as well as an appropriate className set on the html element
*
*
* @param feature - String naming the feature
* @param feature - String naming the feature
* @param test - Function returning true if feature is supported, false if not
* @param test - Function returning true if feature is supported, false if not
*/
*/
Modernizr.addTest = function ( feature, test ) {
Modernizr.addTest = function ( feature, test ) {
if ( typeof feature == 'object' ) {
if ( typeof feature == 'object' ) {
for ( var key in feature ) {
for ( var key in feature ) {
if ( hasOwnProp( feature, key ) ) {
if ( hasOwnProp( feature, key ) ) {
Modernizr.addTest( key, feature[ key ] );
Modernizr.addTest( key, feature[ key ] );
}
}
}
}
} else {
} else {
feature = feature.toLowerCase();
feature = feature.toLowerCase();
if ( Modernizr[feature] !== undefined ) {
if ( Modernizr[feature] !== undefined ) {
// we're going to quit if you're trying to overwrite an existing test
// we're going to quit if you're trying to overwrite an existing test
// if we were to allow it, we'd do this:
// if we were to allow it, we'd do this:
// var re = new RegExp("\\b(no-)?" + feature + "\\b");
// docElement.className = docElement.className.replace( re, '' );
// but, no rly, stuff 'em.
// but, no rly, stuff 'em.
return Modernizr;
return Modernizr;
}
}
test = typeof test == 'function' ? test() : test;
test = typeof test == 'function' ? test() : test;
if (typeof enableClasses !== "undefined" && enableClasses) {
if (typeof enableClasses !== "undefined" && enableClasses) {
docElement.className += ' ' + (test ? '' : 'no-') + feature;
docElement.className += ' ' + (test ? '' : 'no-') + feature;
}
}
Modernizr[feature] = test;
Modernizr[feature] = test;
}
}
return Modernizr; // allow chaining.
return Modernizr; // allow chaining.
};
};
// Reset modElem.cssText to nothing to reduce memory footprint.
// Reset modElem.cssText to nothing to reduce memory footprint.
setCss('');
setCss('');
modElem = inputElem = null;
modElem = inputElem = null;
/*>>shiv*/
/*>>shiv*/
/**
/**
* @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
* @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
*/
;(function(window, document) {
;(function(window, document) {
/*jshint evil:true */
/*jshint evil:true */
/** version */
/** version */
var version = '3.7.0';
var version = '3.7.0';
/** Preset options */
/** Preset options */
var options = window.html5 || {};
var options = window.html5 || {};
/** Used to skip problem elements */
/** Used to skip problem elements */
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
/** Not all elements can be cloned in IE **/
/** Not all elements can be cloned in IE **/
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
/** Detect whether the browser supports default html5 styles */
/** Detect whether the browser supports default html5 styles */
var supportsHtml5Styles;
var supportsHtml5Styles;
/** Name of the expando, to work with multiple documents or to re-shiv one document */
/** Name of the expando, to work with multiple documents or to re-shiv one document */
var expando = '_html5shiv';
var expando = '_html5shiv';
/** The id for the the documents expando */
/** The id for the the documents expando */
var expanID = 0;
var expanID = 0;
/** Cached data for each document */
/** Cached data for each document */
var expandoData = {};
var expandoData = {};
var supportsUnknownElements;
var supportsUnknownElements;
(function() {
(function() {
try {
try {
var a = document.createElement('a');
var a = document.createElement('a');
a.innerHTML = '<xyz></xyz>';
a.innerHTML = '<xyz></xyz>';
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
supportsHtml5Styles = ('hidden' in a);
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
supportsUnknownElements = a.childNodes.length === 1 || (function() {
// assign a false positive if unable to shiv
// assign a false positive if unable to shiv
(document.createElement)('a');
(document.createElement)('a');
var frag = document.createDocumentFragment();
var frag = document.createDocumentFragment();
return (
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
typeof frag.createElement == 'undefined'
);
);
}());
}());
} catch(e) {
} catch(e) {
// assign a false positive if detection fails => unable to shiv
// assign a false positive if detection fails => unable to shiv
supportsHtml5Styles = true;
supportsHtml5Styles = true;
supportsUnknownElements = true;
supportsUnknownElements = true;
}
}
}());
}());
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/**
/**
* Creates a style sheet with the given CSS text and adds it to the document.
* Creates a style sheet with the given CSS text and adds it to the document.
* @private
* @private
* @param {Document} ownerDocument The document.
* @param {Document} ownerDocument The document.
* @param {String} cssText The CSS text.
* @param {String} cssText The CSS text.
* @returns {StyleSheet} The style element.
* @returns {StyleSheet} The style element.
*/
*/
function addStyleSheet(ownerDocument, cssText) {
function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x<style>' + cssText + '</style>';
p.innerHTML = 'x<style>' + cssText + '</style>';
return parent.insertBefore(p.lastChild, parent.firstChild);
return parent.insertBefore(p.lastChild, parent.firstChild);
}
}
/**
/**
* Returns the value of `html5.elements` as an array.
* Returns the value of `html5.elements` as an array.
* @private
* @private
* @returns {Array} An array of shived element node names.
* @returns {Array} An array of shived element node names.
*/
*/
function getElements() {
function getElements() {
var elements = html5.elements;
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
}
/**
/**
* Returns the data associated to the given document
* Returns the data associated to the given document
* @private
* @private
* @param {Document} ownerDocument The document.
* @param {Document} ownerDocument The document.
* @returns {Object} An object of data.
* @returns {Object} An object of data.
*/
*/
function getExpandoData(ownerDocument) {
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
var data = expandoData[ownerDocument[expando]];
if (!data) {
if (!data) {
data = {};
data = {};
expanID++;
expanID++;
ownerDocument[expando] = expanID;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
expandoData[expanID] = data;
}
}
return data;
return data;
}
}
/**
/**
* returns a shived element for the given nodeName and document
* returns a shived element for the given nodeName and document
* @memberOf html5
* @memberOf html5
* @param {String} nodeName name of the element
* @param {String} nodeName name of the element
* @param {Document} ownerDocument The context document.
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived element.
* @returns {Object} The shived element.
*/
*/
function createElement(nodeName, ownerDocument, data){
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
ownerDocument = document;
}
}
if(supportsUnknownElements){
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
return ownerDocument.createElement(nodeName);
}
}
if (!data) {
if (!data) {
data = getExpandoData(ownerDocument);
data = getExpandoData(ownerDocument);
}
}
var node;
var node;
if (data.cache[nodeName]) {
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
} else {
node = data.createElem(nodeName);
node = data.createElem(nodeName);
}
}
// Avoid adding some elements to fragments in IE < 9 because
// Avoid adding some elements to fragments in IE < 9 because
// * Attributes like `name` or `type` cannot be set/changed once an element
// * Attributes like `name` or `type` cannot be set/changed once an element
// is inserted into a document/fragment
// is inserted into a document/fragment
// * Link elements with `src` attributes that are inaccessible, as with
// * Link elements with `src` attributes that are inaccessible, as with
// a 403 response, will cause the tab/window to crash
// a 403 response, will cause the tab/window to crash
// * Script elements appended to fragments will execute when their `src`
// * Script elements appended to fragments will execute when their `src`
// or `text` property is set
// or `text` property is set
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
}
}
/**
/**
* returns a shived DocumentFragment for the given document
* returns a shived DocumentFragment for the given document
* @memberOf html5
* @memberOf html5
* @param {Document} ownerDocument The context document.
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived DocumentFragment.
* @returns {Object} The shived DocumentFragment.
*/
*/
function createDocumentFragment(ownerDocument, data){
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
ownerDocument = document;
}
}
if(supportsUnknownElements){
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
return ownerDocument.createDocumentFragment();
}
}
data = data || getExpandoData(ownerDocument);
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
var clone = data.frag.cloneNode(),
i = 0,
i = 0,
elems = getElements(),
elems = getElements(),
l = elems.length;
l = elems.length;
for(;i<l;i++){
for(;i<l;i++){
clone.createElement(elems[i]);
clone.createElement(elems[i]);
}
}
return clone;
return clone;
}
}
/**
/**
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
* @private
* @private
* @param {Document|DocumentFragment} ownerDocument The document.
* @param {Document|DocumentFragment} ownerDocument The document.
* @param {Object} data of the document.
* @param {Object} data of the document.
*/
*/
function shivMethods(ownerDocument, data) {
function shivMethods(ownerDocument, data) {
if (!data.cache) {
if (!data.cache) {
data.cache = {};
data.cache = {};
data.createElem = ownerDocument.createElement;
data.createElem = ownerDocument.createElement;
data.createFrag = ownerDocument.createDocumentFragment;
data.createFrag = ownerDocument.createDocumentFragment;
data.frag = data.createFrag();
data.frag = data.createFrag();
}
}
ownerDocument.createElement = function(nodeName) {
ownerDocument.createElement = function(nodeName) {
//abort shiv
//abort shiv
if (!html5.shivMethods) {
if (!html5.shivMethods) {
return data.createElem(nodeName);
return data.createElem(nodeName);
}
}
return createElement(nodeName, ownerDocument, data);
return createElement(nodeName, ownerDocument, data);
};
};
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
'var n=f.cloneNode(),c=n.createElement;' +
'var n=f.cloneNode(),c=n.createElement;' +
'h.shivMethods&&(' +
'h.shivMethods&&(' +
// unroll the `createElement` calls
// unroll the `createElement` calls
getElements().join().replace(/[\w\-]+/g, function(nodeName) {
getElements().join().replace(/[\w\-]+/g, function(nodeName) {
data.createElem(nodeName);
data.createElem(nodeName);
data.frag.createElement(nodeName);
data.frag.createElement(nodeName);
return 'c("' + nodeName + '")';
return 'c("' + nodeName + '")';
}) +
}) +
');return n}'
');return n}'
)(html5, data.frag);
)(html5, data.frag);
}
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/**
/**
* Shivs the given document.
* Shivs the given document.
* @memberOf html5
* @memberOf html5
* @param {Document} ownerDocument The document to shiv.
* @param {Document} ownerDocument The document to shiv.
* @returns {Document} The shived document.
* @returns {Document} The shived document.
*/
*/
function shivDocument(ownerDocument) {
function shivDocument(ownerDocument) {
if (!ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
ownerDocument = document;
}
}
var data = getExpandoData(ownerDocument);
var data = getExpandoData(ownerDocument);
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
data.hasCSS = !!addStyleSheet(ownerDocument,
data.hasCSS = !!addStyleSheet(ownerDocument,
// corrects block display not defined in IE6/7/8/9
// corrects block display not defined in IE6/7/8/9
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
// adds styling not present in IE6/7/8/9
// adds styling not present in IE6/7/8/9
'mark{background:#FF0;color:#000}' +
'mark{background:#FF0;color:#000}' +
// hides non-rendered elements
// hides non-rendered elements
'template{display:none}'
'template{display:none}'
);
);
}
}
if (!supportsUnknownElements) {
if (!supportsUnknownElements) {
shivMethods(ownerDocument, data);
shivMethods(ownerDocument, data);
}
}
return ownerDocument;
return ownerDocument;
}
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/**
/**
* The `html5` object is exposed so that more elements can be shived and
* The `html5` object is exposed so that more elements can be shived and
* existing shiving can be detected on iframes.
* existing shiving can be detected on iframes.
* @type Object
* @type Object
* @example
* @example
*
*
* // options can be changed before the script is included
* // options can be changed before the script is included
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
*/
*/
var html5 = {
var html5 = {
/**
/**
* An array or space separated string of node names of the elements to shiv.
* An array or space separated string of node names of the elements to shiv.
* @memberOf html5
* @memberOf html5
* @type Array|String
* @type Array|String
*/
*/
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
/**
/**
* current version of html5shiv
* current version of html5shiv
*/
*/
'version': version,
'version': version,
/**
/**
* A flag to indicate that the HTML5 style sheet should be inserted.
* A flag to indicate that the HTML5 style sheet should be inserted.
* @memberOf html5
* @memberOf html5
* @type Boolean
* @type Boolean
*/
*/
'shivCSS': (options.shivCSS !== false),
'shivCSS': (options.shivCSS !== false),
/**
/**
* Is equal to true if a browser supports creating unknown/HTML5 elements
* Is equal to true if a browser supports creating unknown/HTML5 elements
* @memberOf html5
* @memberOf html5
* @type boolean
* @type boolean
*/
*/
'supportsUnknownElements': supportsUnknownElements,
'supportsUnknownElements': supportsUnknownElements,
/**
/**
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
* methods should be overwritten.
* methods should be overwritten.
* @memberOf html5
* @memberOf html5
* @type Boolean
* @type Boolean
*/
*/
'shivMethods': (options.shivMethods !== false),
'shivMethods': (options.shivMethods !== false),
/**
/**
* A string to describe the type of `html5` object ("default" or "default print").
* A string to describe the type of `html5` object ("default" or "default print").
* @memberOf html5
* @memberOf html5
* @type String
* @type String
*/
*/
'type': 'default',
'type': 'default',
// shivs the document according to the specified `html5` object options
// shivs the document according to the specified `html5` object options
'shivDocument': shivDocument,
'shivDocument': shivDocument,
//creates a shived element
//creates a shived element
createElement: createElement,
createElement: createElement,
//creates a shived documentFragment
//creates a shived documentFragment
createDocumentFragment: createDocumentFragment
createDocumentFragment: createDocumentFragment
};
};
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// expose html5
// expose html5
window.html5 = html5;
window.html5 = html5;
// shiv the document
// shiv the document
shivDocument(document);
shivDocument(document);
}(this, document));
}(this, document));
/*>>shiv*/
/*>>shiv*/
// Assign private properties to the return object with prefix
// Assign private properties to the return object with prefix
Modernizr._version = version;
Modernizr._version = version;
// expose these for the plugin API. Look in the source for how to join() them against your input
// expose these for the plugin API. Look in the source for how to join() them against your input
/*>>prefixes*/
/*>>prefixes*/
Modernizr._prefixes = prefixes;
Modernizr._prefixes = prefixes;
/*>>prefixes*/
/*>>prefixes*/
/*>>domprefixes*/
/*>>domprefixes*/
Modernizr._domPrefixes = domPrefixes;
Modernizr._domPrefixes = domPrefixes;
Modernizr._cssomPrefixes = cssomPrefixes;
Modernizr._cssomPrefixes = cssomPrefixes;
/*>>domprefixes*/
/*>>domprefixes*/
/*>>mq*/
/*>>mq*/
// Modernizr.mq tests a given media query, live against the current state of the window
// Modernizr.mq tests a given media query, live against the current state of the window
// A few important notes:
// A few important notes:
// * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
// * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
// * A max-width or orientation query will be evaluated against the current state, which may change later.
// * A max-width or orientation query will be evaluated against the current state, which may change later.
// * You must specify values. Eg. If you are testing support for the min-width media query use:
// * You must specify values. Eg. If you are testing support for the min-width media query use:
// Modernizr.mq('(min-width:0)')
// Modernizr.mq('(min-width:0)')
// usage:
// usage:
// Modernizr.mq('only screen and (max-width:768)')
// Modernizr.mq('only screen and (max-width:768)')
Modernizr.mq = testMediaQuery;
Modernizr.mq = testMediaQuery;
/*>>mq*/
/*>>mq*/
/*>>hasevent*/
/*>>hasevent*/
// Modernizr.hasEvent() detects support for a given event, with an optional element to test on
// Modernizr.hasEvent() detects support for a given event, with an optional element to test on
// Modernizr.hasEvent('gesturestart', elem)
// Modernizr.hasEvent('gesturestart', elem)
Modernizr.hasEvent = isEventSupported;
Modernizr.hasEvent = isEventSupported;
/*>>hasevent*/
/*>>hasevent*/
/*>>testprop*/
/*>>testprop*/
// Modernizr.testProp() investigates whether a given style property is recognized
// Modernizr.testProp() investigates whether a given style property is recognized
// Note that the property names must be provided in the camelCase variant.
// Note that the property names must be provided in the camelCase variant.
// Modernizr.testProp('pointerEvents')
// Modernizr.testProp('pointerEvents')
Modernizr.testProp = function(prop){
Modernizr.testProp = function(prop){
return testProps([prop]);
return testProps([prop]);
};
};
/*>>testprop*/
/*>>testprop*/
/*>>testallprops*/
/*>>testallprops*/
// Modernizr.testAllProps() investigates whether a given style property,
// Modernizr.testAllProps() investigates whether a given style property,
// or any of its vendor-prefixed variants, is recognized
// or any of its vendor-prefixed variants, is recognized
// Note that the property names must be provided in the camelCase variant.
// Note that the property names must be provided in the camelCase variant.
// Modernizr.testAllProps('boxSizing')
// Modernizr.testAllProps('boxSizing')
Modernizr.testAllProps = testPropsAll;
Modernizr.testAllProps = testPropsAll;
/*>>testallprops*/
/*>>testallprops*/
/*>>teststyles*/
/*>>teststyles*/
// Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
// Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
// Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
// Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
Modernizr.testStyles = injectElementWithStyles;
Modernizr.testStyles = injectElementWithStyles;
/*>>teststyles*/
/*>>teststyles*/
/*>>prefixed*/
/*>>prefixed*/
// Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
// Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
// Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
// Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
// Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
// Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
// Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
// Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
//
// str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
// If you're trying to ascertain which transition end event to bind to, you might do something like...
// If you're trying to ascertain which transition end event to bind to, you might do something like...
//
//
// var transEndEventNames = {
// 'WebkitTransition' : 'webkitTransitionEnd',
// 'WebkitTransition' : 'webkitTransitionEnd',
// 'MozTransition' : 'transitionend',
// 'MozTransition' : 'transitionend',
// 'OTransition' : 'oTransitionEnd',
// 'OTransition' : 'oTransitionEnd',
// 'msTransition' : 'MSTransitionEnd',
// 'msTransition' : 'MSTransitionEnd',
// 'transition' : 'transitionend'
// 'transition' : 'transitionend'
// },
// },
// transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
Modernizr.prefixed = function(prop, obj, elem){
Modernizr.prefixed = function(prop, obj, elem){
if(!obj) {
if(!obj) {
return testPropsAll(prop, 'pfx');
return testPropsAll(prop, 'pfx');
} else {
} else {
// Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
// Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
return testPropsAll(prop, obj, elem);
return testPropsAll(prop, obj, elem);
}
}
};
};
/*>>prefixed*/
/*>>prefixed*/
/*>>cssclasses*/
/*>>cssclasses*/
// Remove "no-js" class from <html> element, if it exists:
// Remove "no-js" class from <html> element, if it exists:
docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
// Add the new classes to the <html> element.
// Add the new classes to the <html> element.
(enableClasses ? ' js ' + classes.join(' ') : '');
(enableClasses ? ' js ' + classes.join(' ') : '');
/*>>cssclasses*/
/*>>cssclasses*/
return Modernizr;
return Modernizr;
})(this, this.document);
})(this, this.document);