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