logman 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +45 -0
  5. data/Rakefile +1 -0
  6. data/config.ru +9 -0
  7. data/lib/console/auth.rb +39 -0
  8. data/lib/console/base.rb +22 -0
  9. data/lib/console/bucket_api.rb +50 -0
  10. data/lib/console/log_api.rb +38 -0
  11. data/lib/console/static/app/api_guide/index.html +57 -0
  12. data/lib/console/static/app/bucket/add_edit.html +40 -0
  13. data/lib/console/static/app/bucket/bucket.js +149 -0
  14. data/lib/console/static/app/bucket/log-details.html +37 -0
  15. data/lib/console/static/app/bucket/logs.html +23 -0
  16. data/lib/console/static/app/logman.js +25 -0
  17. data/lib/console/static/app/user/list.html +33 -0
  18. data/lib/console/static/app/user/user-modal.html +34 -0
  19. data/lib/console/static/app/user/user.js +69 -0
  20. data/lib/console/static/css/bootstrap.css +7118 -0
  21. data/lib/console/static/css/bootstrap.min.css +7 -0
  22. data/lib/console/static/css/jsontree.css +64 -0
  23. data/lib/console/static/css/logman.css +59 -0
  24. data/lib/console/static/css/plugins/dataTables/dataTables.bootstrap.css +233 -0
  25. data/lib/console/static/css/plugins/morris/morris-0.4.3.min.css +2 -0
  26. data/lib/console/static/css/plugins/social-buttons/social-buttons.css +68 -0
  27. data/lib/console/static/css/plugins/timeline/timeline.css +144 -0
  28. data/lib/console/static/css/sb-admin.css +317 -0
  29. data/lib/console/static/font-awesome/css/font-awesome.css +1338 -0
  30. data/lib/console/static/font-awesome/css/font-awesome.min.css +4 -0
  31. data/lib/console/static/font-awesome/fonts/FontAwesome.otf +0 -0
  32. data/lib/console/static/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  33. data/lib/console/static/font-awesome/fonts/fontawesome-webfont.svg +414 -0
  34. data/lib/console/static/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  35. data/lib/console/static/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  36. data/lib/console/static/font-awesome/less/bordered-pulled.less +16 -0
  37. data/lib/console/static/font-awesome/less/core.less +12 -0
  38. data/lib/console/static/font-awesome/less/fixed-width.less +6 -0
  39. data/lib/console/static/font-awesome/less/font-awesome.less +17 -0
  40. data/lib/console/static/font-awesome/less/icons.less +412 -0
  41. data/lib/console/static/font-awesome/less/larger.less +13 -0
  42. data/lib/console/static/font-awesome/less/list.less +19 -0
  43. data/lib/console/static/font-awesome/less/mixins.less +20 -0
  44. data/lib/console/static/font-awesome/less/path.less +14 -0
  45. data/lib/console/static/font-awesome/less/rotated-flipped.less +9 -0
  46. data/lib/console/static/font-awesome/less/spinning.less +30 -0
  47. data/lib/console/static/font-awesome/less/stacked.less +20 -0
  48. data/lib/console/static/font-awesome/less/variables.less +381 -0
  49. data/lib/console/static/font-awesome/scss/_bordered-pulled.scss +16 -0
  50. data/lib/console/static/font-awesome/scss/_core.scss +12 -0
  51. data/lib/console/static/font-awesome/scss/_fixed-width.scss +6 -0
  52. data/lib/console/static/font-awesome/scss/_icons.scss +412 -0
  53. data/lib/console/static/font-awesome/scss/_larger.scss +13 -0
  54. data/lib/console/static/font-awesome/scss/_list.scss +19 -0
  55. data/lib/console/static/font-awesome/scss/_mixins.scss +20 -0
  56. data/lib/console/static/font-awesome/scss/_path.scss +14 -0
  57. data/lib/console/static/font-awesome/scss/_rotated-flipped.scss +9 -0
  58. data/lib/console/static/font-awesome/scss/_spinning.scss +30 -0
  59. data/lib/console/static/font-awesome/scss/_stacked.scss +20 -0
  60. data/lib/console/static/font-awesome/scss/_variables.scss +381 -0
  61. data/lib/console/static/font-awesome/scss/font-awesome.scss +17 -0
  62. data/lib/console/static/fonts/glyphicons-halflings-regular.eot +0 -0
  63. data/lib/console/static/fonts/glyphicons-halflings-regular.svg +229 -0
  64. data/lib/console/static/fonts/glyphicons-halflings-regular.ttf +0 -0
  65. data/lib/console/static/fonts/glyphicons-halflings-regular.woff +0 -0
  66. data/lib/console/static/js/angular-resource.min.js +13 -0
  67. data/lib/console/static/js/angular-route.min.js +14 -0
  68. data/lib/console/static/js/angular.min.js +202 -0
  69. data/lib/console/static/js/bootstrap.js +2006 -0
  70. data/lib/console/static/js/bootstrap.min.js +7 -0
  71. data/lib/console/static/js/demo/dashboard-demo.js +117 -0
  72. data/lib/console/static/js/demo/flot-demo.js +1242 -0
  73. data/lib/console/static/js/demo/morris-demo.js +155 -0
  74. data/lib/console/static/js/jquery-1.10.2.js +6 -0
  75. data/lib/console/static/js/jsontree.js +77 -0
  76. data/lib/console/static/js/plugins/dataTables/dataTables.bootstrap.js +245 -0
  77. data/lib/console/static/js/plugins/dataTables/jquery.dataTables.js +14013 -0
  78. data/lib/console/static/js/plugins/flot/excanvas.min.js +1 -0
  79. data/lib/console/static/js/plugins/flot/jquery.flot.js +2599 -0
  80. data/lib/console/static/js/plugins/flot/jquery.flot.pie.js +750 -0
  81. data/lib/console/static/js/plugins/flot/jquery.flot.resize.js +60 -0
  82. data/lib/console/static/js/plugins/flot/jquery.flot.tooltip.min.js +12 -0
  83. data/lib/console/static/js/plugins/metisMenu/jquery.metisMenu.js +45 -0
  84. data/lib/console/static/js/plugins/morris/morris.js +1888 -0
  85. data/lib/console/static/js/plugins/morris/raphael-2.1.0.min.js +10 -0
  86. data/lib/console/static/js/sb-admin.js +31 -0
  87. data/lib/console/static/js/ui-bootstrap-tpls-0.10.0.min.js +9 -0
  88. data/lib/console/user_api.rb +51 -0
  89. data/lib/console/views/app.erb +144 -0
  90. data/lib/console/views/dashboard.erb +30 -0
  91. data/lib/console/views/login.erb +89 -0
  92. data/lib/console/web_console.rb +24 -0
  93. data/lib/logman.rb +3 -0
  94. data/lib/logman/server.rb +9 -0
  95. data/lib/logman/system.rb +53 -0
  96. data/lib/logman/version.rb +3 -0
  97. data/lib/models/bucket.rb +38 -0
  98. data/lib/models/log.rb +41 -0
  99. data/lib/models/user.rb +33 -0
  100. data/lib/modules/log_writer.rb +27 -0
  101. data/lib/modules/secure_password.rb +122 -0
  102. data/logman.gemspec +30 -0
  103. metadata +261 -0
@@ -0,0 +1,2006 @@
1
+ /*!
2
+ * Bootstrap v3.0.3 (http://getbootstrap.com)
3
+ * Copyright 2013 Twitter, Inc.
4
+ * Licensed under http://www.apache.org/licenses/LICENSE-2.0
5
+ */
6
+
7
+ if (typeof jQuery === "undefined") { throw new Error("Bootstrap requires jQuery") }
8
+
9
+ /* ========================================================================
10
+ * Bootstrap: transition.js v3.0.3
11
+ * http://getbootstrap.com/javascript/#transitions
12
+ * ========================================================================
13
+ * Copyright 2013 Twitter, Inc.
14
+ *
15
+ * Licensed under the Apache License, Version 2.0 (the "License");
16
+ * you may not use this file except in compliance with the License.
17
+ * You may obtain a copy of the License at
18
+ *
19
+ * http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software
22
+ * distributed under the License is distributed on an "AS IS" BASIS,
23
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+ * See the License for the specific language governing permissions and
25
+ * limitations under the License.
26
+ * ======================================================================== */
27
+
28
+
29
+ +function ($) { "use strict";
30
+
31
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
32
+ // ============================================================
33
+
34
+ function transitionEnd() {
35
+ var el = document.createElement('bootstrap')
36
+
37
+ var transEndEventNames = {
38
+ 'WebkitTransition' : 'webkitTransitionEnd'
39
+ , 'MozTransition' : 'transitionend'
40
+ , 'OTransition' : 'oTransitionEnd otransitionend'
41
+ , 'transition' : 'transitionend'
42
+ }
43
+
44
+ for (var name in transEndEventNames) {
45
+ if (el.style[name] !== undefined) {
46
+ return { end: transEndEventNames[name] }
47
+ }
48
+ }
49
+ }
50
+
51
+ // http://blog.alexmaccaw.com/css-transitions
52
+ $.fn.emulateTransitionEnd = function (duration) {
53
+ var called = false, $el = this
54
+ $(this).one($.support.transition.end, function () { called = true })
55
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
56
+ setTimeout(callback, duration)
57
+ return this
58
+ }
59
+
60
+ $(function () {
61
+ $.support.transition = transitionEnd()
62
+ })
63
+
64
+ }(jQuery);
65
+
66
+ /* ========================================================================
67
+ * Bootstrap: alert.js v3.0.3
68
+ * http://getbootstrap.com/javascript/#alerts
69
+ * ========================================================================
70
+ * Copyright 2013 Twitter, Inc.
71
+ *
72
+ * Licensed under the Apache License, Version 2.0 (the "License");
73
+ * you may not use this file except in compliance with the License.
74
+ * You may obtain a copy of the License at
75
+ *
76
+ * http://www.apache.org/licenses/LICENSE-2.0
77
+ *
78
+ * Unless required by applicable law or agreed to in writing, software
79
+ * distributed under the License is distributed on an "AS IS" BASIS,
80
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81
+ * See the License for the specific language governing permissions and
82
+ * limitations under the License.
83
+ * ======================================================================== */
84
+
85
+
86
+ +function ($) { "use strict";
87
+
88
+ // ALERT CLASS DEFINITION
89
+ // ======================
90
+
91
+ var dismiss = '[data-dismiss="alert"]'
92
+ var Alert = function (el) {
93
+ $(el).on('click', dismiss, this.close)
94
+ }
95
+
96
+ Alert.prototype.close = function (e) {
97
+ var $this = $(this)
98
+ var selector = $this.attr('data-target')
99
+
100
+ if (!selector) {
101
+ selector = $this.attr('href')
102
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
103
+ }
104
+
105
+ var $parent = $(selector)
106
+
107
+ if (e) e.preventDefault()
108
+
109
+ if (!$parent.length) {
110
+ $parent = $this.hasClass('alert') ? $this : $this.parent()
111
+ }
112
+
113
+ $parent.trigger(e = $.Event('close.bs.alert'))
114
+
115
+ if (e.isDefaultPrevented()) return
116
+
117
+ $parent.removeClass('in')
118
+
119
+ function removeElement() {
120
+ $parent.trigger('closed.bs.alert').remove()
121
+ }
122
+
123
+ $.support.transition && $parent.hasClass('fade') ?
124
+ $parent
125
+ .one($.support.transition.end, removeElement)
126
+ .emulateTransitionEnd(150) :
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
+ var data = $this.data('bs.alert')
140
+
141
+ if (!data) $this.data('bs.alert', (data = new Alert(this)))
142
+ if (typeof option == 'string') data[option].call($this)
143
+ })
144
+ }
145
+
146
+ $.fn.alert.Constructor = Alert
147
+
148
+
149
+ // ALERT NO CONFLICT
150
+ // =================
151
+
152
+ $.fn.alert.noConflict = function () {
153
+ $.fn.alert = old
154
+ return this
155
+ }
156
+
157
+
158
+ // ALERT DATA-API
159
+ // ==============
160
+
161
+ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
162
+
163
+ }(jQuery);
164
+
165
+ /* ========================================================================
166
+ * Bootstrap: button.js v3.0.3
167
+ * http://getbootstrap.com/javascript/#buttons
168
+ * ========================================================================
169
+ * Copyright 2013 Twitter, Inc.
170
+ *
171
+ * Licensed under the Apache License, Version 2.0 (the "License");
172
+ * you may not use this file except in compliance with the License.
173
+ * You may obtain a copy of the License at
174
+ *
175
+ * http://www.apache.org/licenses/LICENSE-2.0
176
+ *
177
+ * Unless required by applicable law or agreed to in writing, software
178
+ * distributed under the License is distributed on an "AS IS" BASIS,
179
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
180
+ * See the License for the specific language governing permissions and
181
+ * limitations under the License.
182
+ * ======================================================================== */
183
+
184
+
185
+ +function ($) { "use strict";
186
+
187
+ // BUTTON PUBLIC CLASS DEFINITION
188
+ // ==============================
189
+
190
+ var Button = function (element, options) {
191
+ this.$element = $(element)
192
+ this.options = $.extend({}, Button.DEFAULTS, options)
193
+ }
194
+
195
+ Button.DEFAULTS = {
196
+ loadingText: 'loading...'
197
+ }
198
+
199
+ Button.prototype.setState = function (state) {
200
+ var d = 'disabled'
201
+ var $el = this.$element
202
+ var val = $el.is('input') ? 'val' : 'html'
203
+ var data = $el.data()
204
+
205
+ state = state + 'Text'
206
+
207
+ if (!data.resetText) $el.data('resetText', $el[val]())
208
+
209
+ $el[val](data[state] || this.options[state])
210
+
211
+ // push to event loop to allow forms to submit
212
+ setTimeout(function () {
213
+ state == 'loadingText' ?
214
+ $el.addClass(d).attr(d, d) :
215
+ $el.removeClass(d).removeAttr(d);
216
+ }, 0)
217
+ }
218
+
219
+ Button.prototype.toggle = function () {
220
+ var $parent = this.$element.closest('[data-toggle="buttons"]')
221
+ var changed = true
222
+
223
+ if ($parent.length) {
224
+ var $input = this.$element.find('input')
225
+ if ($input.prop('type') === 'radio') {
226
+ // see if clicking on current one
227
+ if ($input.prop('checked') && this.$element.hasClass('active'))
228
+ changed = false
229
+ else
230
+ $parent.find('.active').removeClass('active')
231
+ }
232
+ if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
233
+ }
234
+
235
+ if (changed) this.$element.toggleClass('active')
236
+ }
237
+
238
+
239
+ // BUTTON PLUGIN DEFINITION
240
+ // ========================
241
+
242
+ var old = $.fn.button
243
+
244
+ $.fn.button = function (option) {
245
+ return this.each(function () {
246
+ var $this = $(this)
247
+ var data = $this.data('bs.button')
248
+ var options = typeof option == 'object' && option
249
+
250
+ if (!data) $this.data('bs.button', (data = new Button(this, options)))
251
+
252
+ if (option == 'toggle') data.toggle()
253
+ else if (option) data.setState(option)
254
+ })
255
+ }
256
+
257
+ $.fn.button.Constructor = Button
258
+
259
+
260
+ // BUTTON NO CONFLICT
261
+ // ==================
262
+
263
+ $.fn.button.noConflict = function () {
264
+ $.fn.button = old
265
+ return this
266
+ }
267
+
268
+
269
+ // BUTTON DATA-API
270
+ // ===============
271
+
272
+ $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
273
+ var $btn = $(e.target)
274
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
275
+ $btn.button('toggle')
276
+ e.preventDefault()
277
+ })
278
+
279
+ }(jQuery);
280
+
281
+ /* ========================================================================
282
+ * Bootstrap: carousel.js v3.0.3
283
+ * http://getbootstrap.com/javascript/#carousel
284
+ * ========================================================================
285
+ * Copyright 2013 Twitter, Inc.
286
+ *
287
+ * Licensed under the Apache License, Version 2.0 (the "License");
288
+ * you may not use this file except in compliance with the License.
289
+ * You may obtain a copy of the License at
290
+ *
291
+ * http://www.apache.org/licenses/LICENSE-2.0
292
+ *
293
+ * Unless required by applicable law or agreed to in writing, software
294
+ * distributed under the License is distributed on an "AS IS" BASIS,
295
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
296
+ * See the License for the specific language governing permissions and
297
+ * limitations under the License.
298
+ * ======================================================================== */
299
+
300
+
301
+ +function ($) { "use strict";
302
+
303
+ // CAROUSEL CLASS DEFINITION
304
+ // =========================
305
+
306
+ var Carousel = function (element, options) {
307
+ this.$element = $(element)
308
+ this.$indicators = this.$element.find('.carousel-indicators')
309
+ this.options = options
310
+ this.paused =
311
+ this.sliding =
312
+ this.interval =
313
+ this.$active =
314
+ this.$items = null
315
+
316
+ this.options.pause == 'hover' && this.$element
317
+ .on('mouseenter', $.proxy(this.pause, this))
318
+ .on('mouseleave', $.proxy(this.cycle, this))
319
+ }
320
+
321
+ Carousel.DEFAULTS = {
322
+ interval: 5000
323
+ , pause: 'hover'
324
+ , wrap: true
325
+ }
326
+
327
+ Carousel.prototype.cycle = function (e) {
328
+ e || (this.paused = false)
329
+
330
+ this.interval && clearInterval(this.interval)
331
+
332
+ this.options.interval
333
+ && !this.paused
334
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
335
+
336
+ return this
337
+ }
338
+
339
+ Carousel.prototype.getActiveIndex = function () {
340
+ this.$active = this.$element.find('.item.active')
341
+ this.$items = this.$active.parent().children()
342
+
343
+ return this.$items.index(this.$active)
344
+ }
345
+
346
+ Carousel.prototype.to = function (pos) {
347
+ var that = this
348
+ var activeIndex = this.getActiveIndex()
349
+
350
+ if (pos > (this.$items.length - 1) || pos < 0) return
351
+
352
+ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) })
353
+ if (activeIndex == pos) return this.pause().cycle()
354
+
355
+ return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
356
+ }
357
+
358
+ Carousel.prototype.pause = function (e) {
359
+ e || (this.paused = true)
360
+
361
+ if (this.$element.find('.next, .prev').length && $.support.transition.end) {
362
+ this.$element.trigger($.support.transition.end)
363
+ this.cycle(true)
364
+ }
365
+
366
+ this.interval = clearInterval(this.interval)
367
+
368
+ return this
369
+ }
370
+
371
+ Carousel.prototype.next = function () {
372
+ if (this.sliding) return
373
+ return this.slide('next')
374
+ }
375
+
376
+ Carousel.prototype.prev = function () {
377
+ if (this.sliding) return
378
+ return this.slide('prev')
379
+ }
380
+
381
+ Carousel.prototype.slide = function (type, next) {
382
+ var $active = this.$element.find('.item.active')
383
+ var $next = next || $active[type]()
384
+ var isCycling = this.interval
385
+ var direction = type == 'next' ? 'left' : 'right'
386
+ var fallback = type == 'next' ? 'first' : 'last'
387
+ var that = this
388
+
389
+ if (!$next.length) {
390
+ if (!this.options.wrap) return
391
+ $next = this.$element.find('.item')[fallback]()
392
+ }
393
+
394
+ this.sliding = true
395
+
396
+ isCycling && this.pause()
397
+
398
+ var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })
399
+
400
+ if ($next.hasClass('active')) return
401
+
402
+ if (this.$indicators.length) {
403
+ this.$indicators.find('.active').removeClass('active')
404
+ this.$element.one('slid.bs.carousel', function () {
405
+ var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
406
+ $nextIndicator && $nextIndicator.addClass('active')
407
+ })
408
+ }
409
+
410
+ if ($.support.transition && this.$element.hasClass('slide')) {
411
+ this.$element.trigger(e)
412
+ if (e.isDefaultPrevented()) return
413
+ $next.addClass(type)
414
+ $next[0].offsetWidth // force reflow
415
+ $active.addClass(direction)
416
+ $next.addClass(direction)
417
+ $active
418
+ .one($.support.transition.end, function () {
419
+ $next.removeClass([type, direction].join(' ')).addClass('active')
420
+ $active.removeClass(['active', direction].join(' '))
421
+ that.sliding = false
422
+ setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0)
423
+ })
424
+ .emulateTransitionEnd(600)
425
+ } else {
426
+ this.$element.trigger(e)
427
+ if (e.isDefaultPrevented()) return
428
+ $active.removeClass('active')
429
+ $next.addClass('active')
430
+ this.sliding = false
431
+ this.$element.trigger('slid.bs.carousel')
432
+ }
433
+
434
+ isCycling && this.cycle()
435
+
436
+ return this
437
+ }
438
+
439
+
440
+ // CAROUSEL PLUGIN DEFINITION
441
+ // ==========================
442
+
443
+ var old = $.fn.carousel
444
+
445
+ $.fn.carousel = function (option) {
446
+ return this.each(function () {
447
+ var $this = $(this)
448
+ var data = $this.data('bs.carousel')
449
+ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
450
+ var action = typeof option == 'string' ? option : options.slide
451
+
452
+ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
453
+ if (typeof option == 'number') data.to(option)
454
+ else if (action) data[action]()
455
+ else if (options.interval) data.pause().cycle()
456
+ })
457
+ }
458
+
459
+ $.fn.carousel.Constructor = Carousel
460
+
461
+
462
+ // CAROUSEL NO CONFLICT
463
+ // ====================
464
+
465
+ $.fn.carousel.noConflict = function () {
466
+ $.fn.carousel = old
467
+ return this
468
+ }
469
+
470
+
471
+ // CAROUSEL DATA-API
472
+ // =================
473
+
474
+ $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
475
+ var $this = $(this), href
476
+ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
477
+ var options = $.extend({}, $target.data(), $this.data())
478
+ var slideIndex = $this.attr('data-slide-to')
479
+ if (slideIndex) options.interval = false
480
+
481
+ $target.carousel(options)
482
+
483
+ if (slideIndex = $this.attr('data-slide-to')) {
484
+ $target.data('bs.carousel').to(slideIndex)
485
+ }
486
+
487
+ e.preventDefault()
488
+ })
489
+
490
+ $(window).on('load', function () {
491
+ $('[data-ride="carousel"]').each(function () {
492
+ var $carousel = $(this)
493
+ $carousel.carousel($carousel.data())
494
+ })
495
+ })
496
+
497
+ }(jQuery);
498
+
499
+ /* ========================================================================
500
+ * Bootstrap: collapse.js v3.0.3
501
+ * http://getbootstrap.com/javascript/#collapse
502
+ * ========================================================================
503
+ * Copyright 2013 Twitter, Inc.
504
+ *
505
+ * Licensed under the Apache License, Version 2.0 (the "License");
506
+ * you may not use this file except in compliance with the License.
507
+ * You may obtain a copy of the License at
508
+ *
509
+ * http://www.apache.org/licenses/LICENSE-2.0
510
+ *
511
+ * Unless required by applicable law or agreed to in writing, software
512
+ * distributed under the License is distributed on an "AS IS" BASIS,
513
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
514
+ * See the License for the specific language governing permissions and
515
+ * limitations under the License.
516
+ * ======================================================================== */
517
+
518
+
519
+ +function ($) { "use strict";
520
+
521
+ // COLLAPSE PUBLIC CLASS DEFINITION
522
+ // ================================
523
+
524
+ var Collapse = function (element, options) {
525
+ this.$element = $(element)
526
+ this.options = $.extend({}, Collapse.DEFAULTS, options)
527
+ this.transitioning = null
528
+
529
+ if (this.options.parent) this.$parent = $(this.options.parent)
530
+ if (this.options.toggle) this.toggle()
531
+ }
532
+
533
+ Collapse.DEFAULTS = {
534
+ toggle: true
535
+ }
536
+
537
+ Collapse.prototype.dimension = function () {
538
+ var hasWidth = this.$element.hasClass('width')
539
+ return hasWidth ? 'width' : 'height'
540
+ }
541
+
542
+ Collapse.prototype.show = function () {
543
+ if (this.transitioning || this.$element.hasClass('in')) return
544
+
545
+ var startEvent = $.Event('show.bs.collapse')
546
+ this.$element.trigger(startEvent)
547
+ if (startEvent.isDefaultPrevented()) return
548
+
549
+ var actives = this.$parent && this.$parent.find('> .panel > .in')
550
+
551
+ if (actives && actives.length) {
552
+ var hasData = actives.data('bs.collapse')
553
+ if (hasData && hasData.transitioning) return
554
+ actives.collapse('hide')
555
+ hasData || actives.data('bs.collapse', null)
556
+ }
557
+
558
+ var dimension = this.dimension()
559
+
560
+ this.$element
561
+ .removeClass('collapse')
562
+ .addClass('collapsing')
563
+ [dimension](0)
564
+
565
+ this.transitioning = 1
566
+
567
+ var complete = function () {
568
+ this.$element
569
+ .removeClass('collapsing')
570
+ .addClass('in')
571
+ [dimension]('auto')
572
+ this.transitioning = 0
573
+ this.$element.trigger('shown.bs.collapse')
574
+ }
575
+
576
+ if (!$.support.transition) return complete.call(this)
577
+
578
+ var scrollSize = $.camelCase(['scroll', dimension].join('-'))
579
+
580
+ this.$element
581
+ .one($.support.transition.end, $.proxy(complete, this))
582
+ .emulateTransitionEnd(350)
583
+ [dimension](this.$element[0][scrollSize])
584
+ }
585
+
586
+ Collapse.prototype.hide = function () {
587
+ if (this.transitioning || !this.$element.hasClass('in')) return
588
+
589
+ var startEvent = $.Event('hide.bs.collapse')
590
+ this.$element.trigger(startEvent)
591
+ if (startEvent.isDefaultPrevented()) return
592
+
593
+ var dimension = this.dimension()
594
+
595
+ this.$element
596
+ [dimension](this.$element[dimension]())
597
+ [0].offsetHeight
598
+
599
+ this.$element
600
+ .addClass('collapsing')
601
+ .removeClass('collapse')
602
+ .removeClass('in')
603
+
604
+ this.transitioning = 1
605
+
606
+ var complete = function () {
607
+ this.transitioning = 0
608
+ this.$element
609
+ .trigger('hidden.bs.collapse')
610
+ .removeClass('collapsing')
611
+ .addClass('collapse')
612
+ }
613
+
614
+ if (!$.support.transition) return complete.call(this)
615
+
616
+ this.$element
617
+ [dimension](0)
618
+ .one($.support.transition.end, $.proxy(complete, this))
619
+ .emulateTransitionEnd(350)
620
+ }
621
+
622
+ Collapse.prototype.toggle = function () {
623
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
624
+ }
625
+
626
+
627
+ // COLLAPSE PLUGIN DEFINITION
628
+ // ==========================
629
+
630
+ var old = $.fn.collapse
631
+
632
+ $.fn.collapse = function (option) {
633
+ return this.each(function () {
634
+ var $this = $(this)
635
+ var data = $this.data('bs.collapse')
636
+ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
637
+
638
+ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
639
+ if (typeof option == 'string') data[option]()
640
+ })
641
+ }
642
+
643
+ $.fn.collapse.Constructor = Collapse
644
+
645
+
646
+ // COLLAPSE NO CONFLICT
647
+ // ====================
648
+
649
+ $.fn.collapse.noConflict = function () {
650
+ $.fn.collapse = old
651
+ return this
652
+ }
653
+
654
+
655
+ // COLLAPSE DATA-API
656
+ // =================
657
+
658
+ $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
659
+ var $this = $(this), href
660
+ var target = $this.attr('data-target')
661
+ || e.preventDefault()
662
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
663
+ var $target = $(target)
664
+ var data = $target.data('bs.collapse')
665
+ var option = data ? 'toggle' : $this.data()
666
+ var parent = $this.attr('data-parent')
667
+ var $parent = parent && $(parent)
668
+
669
+ if (!data || !data.transitioning) {
670
+ if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
671
+ $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
672
+ }
673
+
674
+ $target.collapse(option)
675
+ })
676
+
677
+ }(jQuery);
678
+
679
+ /* ========================================================================
680
+ * Bootstrap: dropdown.js v3.0.3
681
+ * http://getbootstrap.com/javascript/#dropdowns
682
+ * ========================================================================
683
+ * Copyright 2013 Twitter, Inc.
684
+ *
685
+ * Licensed under the Apache License, Version 2.0 (the "License");
686
+ * you may not use this file except in compliance with the License.
687
+ * You may obtain a copy of the License at
688
+ *
689
+ * http://www.apache.org/licenses/LICENSE-2.0
690
+ *
691
+ * Unless required by applicable law or agreed to in writing, software
692
+ * distributed under the License is distributed on an "AS IS" BASIS,
693
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
694
+ * See the License for the specific language governing permissions and
695
+ * limitations under the License.
696
+ * ======================================================================== */
697
+
698
+
699
+ +function ($) { "use strict";
700
+
701
+ // DROPDOWN CLASS DEFINITION
702
+ // =========================
703
+
704
+ var backdrop = '.dropdown-backdrop'
705
+ var toggle = '[data-toggle=dropdown]'
706
+ var Dropdown = function (element) {
707
+ $(element).on('click.bs.dropdown', this.toggle)
708
+ }
709
+
710
+ Dropdown.prototype.toggle = function (e) {
711
+ var $this = $(this)
712
+
713
+ if ($this.is('.disabled, :disabled')) return
714
+
715
+ var $parent = getParent($this)
716
+ var isActive = $parent.hasClass('open')
717
+
718
+ clearMenus()
719
+
720
+ if (!isActive) {
721
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
722
+ // if mobile we use a backdrop because click events don't delegate
723
+ $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
724
+ }
725
+
726
+ $parent.trigger(e = $.Event('show.bs.dropdown'))
727
+
728
+ if (e.isDefaultPrevented()) return
729
+
730
+ $parent
731
+ .toggleClass('open')
732
+ .trigger('shown.bs.dropdown')
733
+
734
+ $this.focus()
735
+ }
736
+
737
+ return false
738
+ }
739
+
740
+ Dropdown.prototype.keydown = function (e) {
741
+ if (!/(38|40|27)/.test(e.keyCode)) return
742
+
743
+ var $this = $(this)
744
+
745
+ e.preventDefault()
746
+ e.stopPropagation()
747
+
748
+ if ($this.is('.disabled, :disabled')) return
749
+
750
+ var $parent = getParent($this)
751
+ var isActive = $parent.hasClass('open')
752
+
753
+ if (!isActive || (isActive && e.keyCode == 27)) {
754
+ if (e.which == 27) $parent.find(toggle).focus()
755
+ return $this.click()
756
+ }
757
+
758
+ var $items = $('[role=menu] li:not(.divider):visible a', $parent)
759
+
760
+ if (!$items.length) return
761
+
762
+ var index = $items.index($items.filter(':focus'))
763
+
764
+ if (e.keyCode == 38 && index > 0) index-- // up
765
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
766
+ if (!~index) index=0
767
+
768
+ $items.eq(index).focus()
769
+ }
770
+
771
+ function clearMenus() {
772
+ $(backdrop).remove()
773
+ $(toggle).each(function (e) {
774
+ var $parent = getParent($(this))
775
+ if (!$parent.hasClass('open')) return
776
+ $parent.trigger(e = $.Event('hide.bs.dropdown'))
777
+ if (e.isDefaultPrevented()) return
778
+ $parent.removeClass('open').trigger('hidden.bs.dropdown')
779
+ })
780
+ }
781
+
782
+ function getParent($this) {
783
+ var selector = $this.attr('data-target')
784
+
785
+ if (!selector) {
786
+ selector = $this.attr('href')
787
+ selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
788
+ }
789
+
790
+ var $parent = selector && $(selector)
791
+
792
+ return $parent && $parent.length ? $parent : $this.parent()
793
+ }
794
+
795
+
796
+ // DROPDOWN PLUGIN DEFINITION
797
+ // ==========================
798
+
799
+ var old = $.fn.dropdown
800
+
801
+ $.fn.dropdown = function (option) {
802
+ return this.each(function () {
803
+ var $this = $(this)
804
+ var data = $this.data('bs.dropdown')
805
+
806
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
807
+ if (typeof option == 'string') data[option].call($this)
808
+ })
809
+ }
810
+
811
+ $.fn.dropdown.Constructor = Dropdown
812
+
813
+
814
+ // DROPDOWN NO CONFLICT
815
+ // ====================
816
+
817
+ $.fn.dropdown.noConflict = function () {
818
+ $.fn.dropdown = old
819
+ return this
820
+ }
821
+
822
+
823
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
824
+ // ===================================
825
+
826
+ $(document)
827
+ .on('click.bs.dropdown.data-api', clearMenus)
828
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
829
+ .on('click.bs.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
830
+ .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
831
+
832
+ }(jQuery);
833
+
834
+ /* ========================================================================
835
+ * Bootstrap: modal.js v3.0.3
836
+ * http://getbootstrap.com/javascript/#modals
837
+ * ========================================================================
838
+ * Copyright 2013 Twitter, Inc.
839
+ *
840
+ * Licensed under the Apache License, Version 2.0 (the "License");
841
+ * you may not use this file except in compliance with the License.
842
+ * You may obtain a copy of the License at
843
+ *
844
+ * http://www.apache.org/licenses/LICENSE-2.0
845
+ *
846
+ * Unless required by applicable law or agreed to in writing, software
847
+ * distributed under the License is distributed on an "AS IS" BASIS,
848
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
849
+ * See the License for the specific language governing permissions and
850
+ * limitations under the License.
851
+ * ======================================================================== */
852
+
853
+
854
+ +function ($) { "use strict";
855
+
856
+ // MODAL CLASS DEFINITION
857
+ // ======================
858
+
859
+ var Modal = function (element, options) {
860
+ this.options = options
861
+ this.$element = $(element)
862
+ this.$backdrop =
863
+ this.isShown = null
864
+
865
+ if (this.options.remote) this.$element.load(this.options.remote)
866
+ }
867
+
868
+ Modal.DEFAULTS = {
869
+ backdrop: true
870
+ , keyboard: true
871
+ , show: true
872
+ }
873
+
874
+ Modal.prototype.toggle = function (_relatedTarget) {
875
+ return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
876
+ }
877
+
878
+ Modal.prototype.show = function (_relatedTarget) {
879
+ var that = this
880
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
881
+
882
+ this.$element.trigger(e)
883
+
884
+ if (this.isShown || e.isDefaultPrevented()) return
885
+
886
+ this.isShown = true
887
+
888
+ this.escape()
889
+
890
+ this.$element.on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
891
+
892
+ this.backdrop(function () {
893
+ var transition = $.support.transition && that.$element.hasClass('fade')
894
+
895
+ if (!that.$element.parent().length) {
896
+ that.$element.appendTo(document.body) // don't move modals dom position
897
+ }
898
+
899
+ that.$element.show()
900
+
901
+ if (transition) {
902
+ that.$element[0].offsetWidth // force reflow
903
+ }
904
+
905
+ that.$element
906
+ .addClass('in')
907
+ .attr('aria-hidden', false)
908
+
909
+ that.enforceFocus()
910
+
911
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
912
+
913
+ transition ?
914
+ that.$element.find('.modal-dialog') // wait for modal to slide in
915
+ .one($.support.transition.end, function () {
916
+ that.$element.focus().trigger(e)
917
+ })
918
+ .emulateTransitionEnd(300) :
919
+ that.$element.focus().trigger(e)
920
+ })
921
+ }
922
+
923
+ Modal.prototype.hide = function (e) {
924
+ if (e) e.preventDefault()
925
+
926
+ e = $.Event('hide.bs.modal')
927
+
928
+ this.$element.trigger(e)
929
+
930
+ if (!this.isShown || e.isDefaultPrevented()) return
931
+
932
+ this.isShown = false
933
+
934
+ this.escape()
935
+
936
+ $(document).off('focusin.bs.modal')
937
+
938
+ this.$element
939
+ .removeClass('in')
940
+ .attr('aria-hidden', true)
941
+ .off('click.dismiss.modal')
942
+
943
+ $.support.transition && this.$element.hasClass('fade') ?
944
+ this.$element
945
+ .one($.support.transition.end, $.proxy(this.hideModal, this))
946
+ .emulateTransitionEnd(300) :
947
+ this.hideModal()
948
+ }
949
+
950
+ Modal.prototype.enforceFocus = function () {
951
+ $(document)
952
+ .off('focusin.bs.modal') // guard against infinite focus loop
953
+ .on('focusin.bs.modal', $.proxy(function (e) {
954
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
955
+ this.$element.focus()
956
+ }
957
+ }, this))
958
+ }
959
+
960
+ Modal.prototype.escape = function () {
961
+ if (this.isShown && this.options.keyboard) {
962
+ this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
963
+ e.which == 27 && this.hide()
964
+ }, this))
965
+ } else if (!this.isShown) {
966
+ this.$element.off('keyup.dismiss.bs.modal')
967
+ }
968
+ }
969
+
970
+ Modal.prototype.hideModal = function () {
971
+ var that = this
972
+ this.$element.hide()
973
+ this.backdrop(function () {
974
+ that.removeBackdrop()
975
+ that.$element.trigger('hidden.bs.modal')
976
+ })
977
+ }
978
+
979
+ Modal.prototype.removeBackdrop = function () {
980
+ this.$backdrop && this.$backdrop.remove()
981
+ this.$backdrop = null
982
+ }
983
+
984
+ Modal.prototype.backdrop = function (callback) {
985
+ var that = this
986
+ var animate = this.$element.hasClass('fade') ? 'fade' : ''
987
+
988
+ if (this.isShown && this.options.backdrop) {
989
+ var doAnimate = $.support.transition && animate
990
+
991
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
992
+ .appendTo(document.body)
993
+
994
+ this.$element.on('click.dismiss.modal', $.proxy(function (e) {
995
+ if (e.target !== e.currentTarget) return
996
+ this.options.backdrop == 'static'
997
+ ? this.$element[0].focus.call(this.$element[0])
998
+ : this.hide.call(this)
999
+ }, this))
1000
+
1001
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
1002
+
1003
+ this.$backdrop.addClass('in')
1004
+
1005
+ if (!callback) return
1006
+
1007
+ doAnimate ?
1008
+ this.$backdrop
1009
+ .one($.support.transition.end, callback)
1010
+ .emulateTransitionEnd(150) :
1011
+ callback()
1012
+
1013
+ } else if (!this.isShown && this.$backdrop) {
1014
+ this.$backdrop.removeClass('in')
1015
+
1016
+ $.support.transition && this.$element.hasClass('fade')?
1017
+ this.$backdrop
1018
+ .one($.support.transition.end, callback)
1019
+ .emulateTransitionEnd(150) :
1020
+ callback()
1021
+
1022
+ } else if (callback) {
1023
+ callback()
1024
+ }
1025
+ }
1026
+
1027
+
1028
+ // MODAL PLUGIN DEFINITION
1029
+ // =======================
1030
+
1031
+ var old = $.fn.modal
1032
+
1033
+ $.fn.modal = function (option, _relatedTarget) {
1034
+ return this.each(function () {
1035
+ var $this = $(this)
1036
+ var data = $this.data('bs.modal')
1037
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
1038
+
1039
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
1040
+ if (typeof option == 'string') data[option](_relatedTarget)
1041
+ else if (options.show) data.show(_relatedTarget)
1042
+ })
1043
+ }
1044
+
1045
+ $.fn.modal.Constructor = Modal
1046
+
1047
+
1048
+ // MODAL NO CONFLICT
1049
+ // =================
1050
+
1051
+ $.fn.modal.noConflict = function () {
1052
+ $.fn.modal = old
1053
+ return this
1054
+ }
1055
+
1056
+
1057
+ // MODAL DATA-API
1058
+ // ==============
1059
+
1060
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
1061
+ var $this = $(this)
1062
+ var href = $this.attr('href')
1063
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
1064
+ var option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
1065
+
1066
+ e.preventDefault()
1067
+
1068
+ $target
1069
+ .modal(option, this)
1070
+ .one('hide', function () {
1071
+ $this.is(':visible') && $this.focus()
1072
+ })
1073
+ })
1074
+
1075
+ $(document)
1076
+ .on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })
1077
+ .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })
1078
+
1079
+ }(jQuery);
1080
+
1081
+ /* ========================================================================
1082
+ * Bootstrap: tooltip.js v3.0.3
1083
+ * http://getbootstrap.com/javascript/#tooltip
1084
+ * Inspired by the original jQuery.tipsy by Jason Frame
1085
+ * ========================================================================
1086
+ * Copyright 2013 Twitter, Inc.
1087
+ *
1088
+ * Licensed under the Apache License, Version 2.0 (the "License");
1089
+ * you may not use this file except in compliance with the License.
1090
+ * You may obtain a copy of the License at
1091
+ *
1092
+ * http://www.apache.org/licenses/LICENSE-2.0
1093
+ *
1094
+ * Unless required by applicable law or agreed to in writing, software
1095
+ * distributed under the License is distributed on an "AS IS" BASIS,
1096
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1097
+ * See the License for the specific language governing permissions and
1098
+ * limitations under the License.
1099
+ * ======================================================================== */
1100
+
1101
+
1102
+ +function ($) { "use strict";
1103
+
1104
+ // TOOLTIP PUBLIC CLASS DEFINITION
1105
+ // ===============================
1106
+
1107
+ var Tooltip = function (element, options) {
1108
+ this.type =
1109
+ this.options =
1110
+ this.enabled =
1111
+ this.timeout =
1112
+ this.hoverState =
1113
+ this.$element = null
1114
+
1115
+ this.init('tooltip', element, options)
1116
+ }
1117
+
1118
+ Tooltip.DEFAULTS = {
1119
+ animation: true
1120
+ , placement: 'top'
1121
+ , selector: false
1122
+ , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
1123
+ , trigger: 'hover focus'
1124
+ , title: ''
1125
+ , delay: 0
1126
+ , html: false
1127
+ , container: false
1128
+ }
1129
+
1130
+ Tooltip.prototype.init = function (type, element, options) {
1131
+ this.enabled = true
1132
+ this.type = type
1133
+ this.$element = $(element)
1134
+ this.options = this.getOptions(options)
1135
+
1136
+ var triggers = this.options.trigger.split(' ')
1137
+
1138
+ for (var i = triggers.length; i--;) {
1139
+ var trigger = triggers[i]
1140
+
1141
+ if (trigger == 'click') {
1142
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
1143
+ } else if (trigger != 'manual') {
1144
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
1145
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
1146
+
1147
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
1148
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
1149
+ }
1150
+ }
1151
+
1152
+ this.options.selector ?
1153
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
1154
+ this.fixTitle()
1155
+ }
1156
+
1157
+ Tooltip.prototype.getDefaults = function () {
1158
+ return Tooltip.DEFAULTS
1159
+ }
1160
+
1161
+ Tooltip.prototype.getOptions = function (options) {
1162
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
1163
+
1164
+ if (options.delay && typeof options.delay == 'number') {
1165
+ options.delay = {
1166
+ show: options.delay
1167
+ , hide: options.delay
1168
+ }
1169
+ }
1170
+
1171
+ return options
1172
+ }
1173
+
1174
+ Tooltip.prototype.getDelegateOptions = function () {
1175
+ var options = {}
1176
+ var defaults = this.getDefaults()
1177
+
1178
+ this._options && $.each(this._options, function (key, value) {
1179
+ if (defaults[key] != value) options[key] = value
1180
+ })
1181
+
1182
+ return options
1183
+ }
1184
+
1185
+ Tooltip.prototype.enter = function (obj) {
1186
+ var self = obj instanceof this.constructor ?
1187
+ obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
1188
+
1189
+ clearTimeout(self.timeout)
1190
+
1191
+ self.hoverState = 'in'
1192
+
1193
+ if (!self.options.delay || !self.options.delay.show) return self.show()
1194
+
1195
+ self.timeout = setTimeout(function () {
1196
+ if (self.hoverState == 'in') self.show()
1197
+ }, self.options.delay.show)
1198
+ }
1199
+
1200
+ Tooltip.prototype.leave = function (obj) {
1201
+ var self = obj instanceof this.constructor ?
1202
+ obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
1203
+
1204
+ clearTimeout(self.timeout)
1205
+
1206
+ self.hoverState = 'out'
1207
+
1208
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
1209
+
1210
+ self.timeout = setTimeout(function () {
1211
+ if (self.hoverState == 'out') self.hide()
1212
+ }, self.options.delay.hide)
1213
+ }
1214
+
1215
+ Tooltip.prototype.show = function () {
1216
+ var e = $.Event('show.bs.'+ this.type)
1217
+
1218
+ if (this.hasContent() && this.enabled) {
1219
+ this.$element.trigger(e)
1220
+
1221
+ if (e.isDefaultPrevented()) return
1222
+
1223
+ var $tip = this.tip()
1224
+
1225
+ this.setContent()
1226
+
1227
+ if (this.options.animation) $tip.addClass('fade')
1228
+
1229
+ var placement = typeof this.options.placement == 'function' ?
1230
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
1231
+ this.options.placement
1232
+
1233
+ var autoToken = /\s?auto?\s?/i
1234
+ var autoPlace = autoToken.test(placement)
1235
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
1236
+
1237
+ $tip
1238
+ .detach()
1239
+ .css({ top: 0, left: 0, display: 'block' })
1240
+ .addClass(placement)
1241
+
1242
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
1243
+
1244
+ var pos = this.getPosition()
1245
+ var actualWidth = $tip[0].offsetWidth
1246
+ var actualHeight = $tip[0].offsetHeight
1247
+
1248
+ if (autoPlace) {
1249
+ var $parent = this.$element.parent()
1250
+
1251
+ var orgPlacement = placement
1252
+ var docScroll = document.documentElement.scrollTop || document.body.scrollTop
1253
+ var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth()
1254
+ var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
1255
+ var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left
1256
+
1257
+ placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
1258
+ placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
1259
+ placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
1260
+ placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
1261
+ placement
1262
+
1263
+ $tip
1264
+ .removeClass(orgPlacement)
1265
+ .addClass(placement)
1266
+ }
1267
+
1268
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
1269
+
1270
+ this.applyPlacement(calculatedOffset, placement)
1271
+ this.$element.trigger('shown.bs.' + this.type)
1272
+ }
1273
+ }
1274
+
1275
+ Tooltip.prototype.applyPlacement = function(offset, placement) {
1276
+ var replace
1277
+ var $tip = this.tip()
1278
+ var width = $tip[0].offsetWidth
1279
+ var height = $tip[0].offsetHeight
1280
+
1281
+ // manually read margins because getBoundingClientRect includes difference
1282
+ var marginTop = parseInt($tip.css('margin-top'), 10)
1283
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
1284
+
1285
+ // we must check for NaN for ie 8/9
1286
+ if (isNaN(marginTop)) marginTop = 0
1287
+ if (isNaN(marginLeft)) marginLeft = 0
1288
+
1289
+ offset.top = offset.top + marginTop
1290
+ offset.left = offset.left + marginLeft
1291
+
1292
+ $tip
1293
+ .offset(offset)
1294
+ .addClass('in')
1295
+
1296
+ // check to see if placing tip in new offset caused the tip to resize itself
1297
+ var actualWidth = $tip[0].offsetWidth
1298
+ var actualHeight = $tip[0].offsetHeight
1299
+
1300
+ if (placement == 'top' && actualHeight != height) {
1301
+ replace = true
1302
+ offset.top = offset.top + height - actualHeight
1303
+ }
1304
+
1305
+ if (/bottom|top/.test(placement)) {
1306
+ var delta = 0
1307
+
1308
+ if (offset.left < 0) {
1309
+ delta = offset.left * -2
1310
+ offset.left = 0
1311
+
1312
+ $tip.offset(offset)
1313
+
1314
+ actualWidth = $tip[0].offsetWidth
1315
+ actualHeight = $tip[0].offsetHeight
1316
+ }
1317
+
1318
+ this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
1319
+ } else {
1320
+ this.replaceArrow(actualHeight - height, actualHeight, 'top')
1321
+ }
1322
+
1323
+ if (replace) $tip.offset(offset)
1324
+ }
1325
+
1326
+ Tooltip.prototype.replaceArrow = function(delta, dimension, position) {
1327
+ this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
1328
+ }
1329
+
1330
+ Tooltip.prototype.setContent = function () {
1331
+ var $tip = this.tip()
1332
+ var title = this.getTitle()
1333
+
1334
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1335
+ $tip.removeClass('fade in top bottom left right')
1336
+ }
1337
+
1338
+ Tooltip.prototype.hide = function () {
1339
+ var that = this
1340
+ var $tip = this.tip()
1341
+ var e = $.Event('hide.bs.' + this.type)
1342
+
1343
+ function complete() {
1344
+ if (that.hoverState != 'in') $tip.detach()
1345
+ }
1346
+
1347
+ this.$element.trigger(e)
1348
+
1349
+ if (e.isDefaultPrevented()) return
1350
+
1351
+ $tip.removeClass('in')
1352
+
1353
+ $.support.transition && this.$tip.hasClass('fade') ?
1354
+ $tip
1355
+ .one($.support.transition.end, complete)
1356
+ .emulateTransitionEnd(150) :
1357
+ complete()
1358
+
1359
+ this.$element.trigger('hidden.bs.' + this.type)
1360
+
1361
+ return this
1362
+ }
1363
+
1364
+ Tooltip.prototype.fixTitle = function () {
1365
+ var $e = this.$element
1366
+ if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
1367
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1368
+ }
1369
+ }
1370
+
1371
+ Tooltip.prototype.hasContent = function () {
1372
+ return this.getTitle()
1373
+ }
1374
+
1375
+ Tooltip.prototype.getPosition = function () {
1376
+ var el = this.$element[0]
1377
+ return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
1378
+ width: el.offsetWidth
1379
+ , height: el.offsetHeight
1380
+ }, this.$element.offset())
1381
+ }
1382
+
1383
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
1384
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1385
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1386
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
1387
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
1388
+ }
1389
+
1390
+ Tooltip.prototype.getTitle = function () {
1391
+ var title
1392
+ var $e = this.$element
1393
+ var o = this.options
1394
+
1395
+ title = $e.attr('data-original-title')
1396
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
1397
+
1398
+ return title
1399
+ }
1400
+
1401
+ Tooltip.prototype.tip = function () {
1402
+ return this.$tip = this.$tip || $(this.options.template)
1403
+ }
1404
+
1405
+ Tooltip.prototype.arrow = function () {
1406
+ return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
1407
+ }
1408
+
1409
+ Tooltip.prototype.validate = function () {
1410
+ if (!this.$element[0].parentNode) {
1411
+ this.hide()
1412
+ this.$element = null
1413
+ this.options = null
1414
+ }
1415
+ }
1416
+
1417
+ Tooltip.prototype.enable = function () {
1418
+ this.enabled = true
1419
+ }
1420
+
1421
+ Tooltip.prototype.disable = function () {
1422
+ this.enabled = false
1423
+ }
1424
+
1425
+ Tooltip.prototype.toggleEnabled = function () {
1426
+ this.enabled = !this.enabled
1427
+ }
1428
+
1429
+ Tooltip.prototype.toggle = function (e) {
1430
+ var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
1431
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
1432
+ }
1433
+
1434
+ Tooltip.prototype.destroy = function () {
1435
+ this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
1436
+ }
1437
+
1438
+
1439
+ // TOOLTIP PLUGIN DEFINITION
1440
+ // =========================
1441
+
1442
+ var old = $.fn.tooltip
1443
+
1444
+ $.fn.tooltip = function (option) {
1445
+ return this.each(function () {
1446
+ var $this = $(this)
1447
+ var data = $this.data('bs.tooltip')
1448
+ var options = typeof option == 'object' && option
1449
+
1450
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
1451
+ if (typeof option == 'string') data[option]()
1452
+ })
1453
+ }
1454
+
1455
+ $.fn.tooltip.Constructor = Tooltip
1456
+
1457
+
1458
+ // TOOLTIP NO CONFLICT
1459
+ // ===================
1460
+
1461
+ $.fn.tooltip.noConflict = function () {
1462
+ $.fn.tooltip = old
1463
+ return this
1464
+ }
1465
+
1466
+ }(jQuery);
1467
+
1468
+ /* ========================================================================
1469
+ * Bootstrap: popover.js v3.0.3
1470
+ * http://getbootstrap.com/javascript/#popovers
1471
+ * ========================================================================
1472
+ * Copyright 2013 Twitter, Inc.
1473
+ *
1474
+ * Licensed under the Apache License, Version 2.0 (the "License");
1475
+ * you may not use this file except in compliance with the License.
1476
+ * You may obtain a copy of the License at
1477
+ *
1478
+ * http://www.apache.org/licenses/LICENSE-2.0
1479
+ *
1480
+ * Unless required by applicable law or agreed to in writing, software
1481
+ * distributed under the License is distributed on an "AS IS" BASIS,
1482
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1483
+ * See the License for the specific language governing permissions and
1484
+ * limitations under the License.
1485
+ * ======================================================================== */
1486
+
1487
+
1488
+ +function ($) { "use strict";
1489
+
1490
+ // POPOVER PUBLIC CLASS DEFINITION
1491
+ // ===============================
1492
+
1493
+ var Popover = function (element, options) {
1494
+ this.init('popover', element, options)
1495
+ }
1496
+
1497
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1498
+
1499
+ Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {
1500
+ placement: 'right'
1501
+ , trigger: 'click'
1502
+ , content: ''
1503
+ , template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1504
+ })
1505
+
1506
+
1507
+ // NOTE: POPOVER EXTENDS tooltip.js
1508
+ // ================================
1509
+
1510
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
1511
+
1512
+ Popover.prototype.constructor = Popover
1513
+
1514
+ Popover.prototype.getDefaults = function () {
1515
+ return Popover.DEFAULTS
1516
+ }
1517
+
1518
+ Popover.prototype.setContent = function () {
1519
+ var $tip = this.tip()
1520
+ var title = this.getTitle()
1521
+ var content = this.getContent()
1522
+
1523
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1524
+ $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
1525
+
1526
+ $tip.removeClass('fade top bottom left right in')
1527
+
1528
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
1529
+ // this manually by checking the contents.
1530
+ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
1531
+ }
1532
+
1533
+ Popover.prototype.hasContent = function () {
1534
+ return this.getTitle() || this.getContent()
1535
+ }
1536
+
1537
+ Popover.prototype.getContent = function () {
1538
+ var $e = this.$element
1539
+ var o = this.options
1540
+
1541
+ return $e.attr('data-content')
1542
+ || (typeof o.content == 'function' ?
1543
+ o.content.call($e[0]) :
1544
+ o.content)
1545
+ }
1546
+
1547
+ Popover.prototype.arrow = function () {
1548
+ return this.$arrow = this.$arrow || this.tip().find('.arrow')
1549
+ }
1550
+
1551
+ Popover.prototype.tip = function () {
1552
+ if (!this.$tip) this.$tip = $(this.options.template)
1553
+ return this.$tip
1554
+ }
1555
+
1556
+
1557
+ // POPOVER PLUGIN DEFINITION
1558
+ // =========================
1559
+
1560
+ var old = $.fn.popover
1561
+
1562
+ $.fn.popover = function (option) {
1563
+ return this.each(function () {
1564
+ var $this = $(this)
1565
+ var data = $this.data('bs.popover')
1566
+ var options = typeof option == 'object' && option
1567
+
1568
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
1569
+ if (typeof option == 'string') data[option]()
1570
+ })
1571
+ }
1572
+
1573
+ $.fn.popover.Constructor = Popover
1574
+
1575
+
1576
+ // POPOVER NO CONFLICT
1577
+ // ===================
1578
+
1579
+ $.fn.popover.noConflict = function () {
1580
+ $.fn.popover = old
1581
+ return this
1582
+ }
1583
+
1584
+ }(jQuery);
1585
+
1586
+ /* ========================================================================
1587
+ * Bootstrap: scrollspy.js v3.0.3
1588
+ * http://getbootstrap.com/javascript/#scrollspy
1589
+ * ========================================================================
1590
+ * Copyright 2013 Twitter, Inc.
1591
+ *
1592
+ * Licensed under the Apache License, Version 2.0 (the "License");
1593
+ * you may not use this file except in compliance with the License.
1594
+ * You may obtain a copy of the License at
1595
+ *
1596
+ * http://www.apache.org/licenses/LICENSE-2.0
1597
+ *
1598
+ * Unless required by applicable law or agreed to in writing, software
1599
+ * distributed under the License is distributed on an "AS IS" BASIS,
1600
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1601
+ * See the License for the specific language governing permissions and
1602
+ * limitations under the License.
1603
+ * ======================================================================== */
1604
+
1605
+
1606
+ +function ($) { "use strict";
1607
+
1608
+ // SCROLLSPY CLASS DEFINITION
1609
+ // ==========================
1610
+
1611
+ function ScrollSpy(element, options) {
1612
+ var href
1613
+ var process = $.proxy(this.process, this)
1614
+
1615
+ this.$element = $(element).is('body') ? $(window) : $(element)
1616
+ this.$body = $('body')
1617
+ this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
1618
+ this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
1619
+ this.selector = (this.options.target
1620
+ || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1621
+ || '') + ' .nav li > a'
1622
+ this.offsets = $([])
1623
+ this.targets = $([])
1624
+ this.activeTarget = null
1625
+
1626
+ this.refresh()
1627
+ this.process()
1628
+ }
1629
+
1630
+ ScrollSpy.DEFAULTS = {
1631
+ offset: 10
1632
+ }
1633
+
1634
+ ScrollSpy.prototype.refresh = function () {
1635
+ var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
1636
+
1637
+ this.offsets = $([])
1638
+ this.targets = $([])
1639
+
1640
+ var self = this
1641
+ var $targets = this.$body
1642
+ .find(this.selector)
1643
+ .map(function () {
1644
+ var $el = $(this)
1645
+ var href = $el.data('target') || $el.attr('href')
1646
+ var $href = /^#\w/.test(href) && $(href)
1647
+
1648
+ return ($href
1649
+ && $href.length
1650
+ && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
1651
+ })
1652
+ .sort(function (a, b) { return a[0] - b[0] })
1653
+ .each(function () {
1654
+ self.offsets.push(this[0])
1655
+ self.targets.push(this[1])
1656
+ })
1657
+ }
1658
+
1659
+ ScrollSpy.prototype.process = function () {
1660
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
1661
+ var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
1662
+ var maxScroll = scrollHeight - this.$scrollElement.height()
1663
+ var offsets = this.offsets
1664
+ var targets = this.targets
1665
+ var activeTarget = this.activeTarget
1666
+ var i
1667
+
1668
+ if (scrollTop >= maxScroll) {
1669
+ return activeTarget != (i = targets.last()[0]) && this.activate(i)
1670
+ }
1671
+
1672
+ for (i = offsets.length; i--;) {
1673
+ activeTarget != targets[i]
1674
+ && scrollTop >= offsets[i]
1675
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
1676
+ && this.activate( targets[i] )
1677
+ }
1678
+ }
1679
+
1680
+ ScrollSpy.prototype.activate = function (target) {
1681
+ this.activeTarget = target
1682
+
1683
+ $(this.selector)
1684
+ .parents('.active')
1685
+ .removeClass('active')
1686
+
1687
+ var selector = this.selector
1688
+ + '[data-target="' + target + '"],'
1689
+ + this.selector + '[href="' + target + '"]'
1690
+
1691
+ var active = $(selector)
1692
+ .parents('li')
1693
+ .addClass('active')
1694
+
1695
+ if (active.parent('.dropdown-menu').length) {
1696
+ active = active
1697
+ .closest('li.dropdown')
1698
+ .addClass('active')
1699
+ }
1700
+
1701
+ active.trigger('activate.bs.scrollspy')
1702
+ }
1703
+
1704
+
1705
+ // SCROLLSPY PLUGIN DEFINITION
1706
+ // ===========================
1707
+
1708
+ var old = $.fn.scrollspy
1709
+
1710
+ $.fn.scrollspy = function (option) {
1711
+ return this.each(function () {
1712
+ var $this = $(this)
1713
+ var data = $this.data('bs.scrollspy')
1714
+ var options = typeof option == 'object' && option
1715
+
1716
+ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
1717
+ if (typeof option == 'string') data[option]()
1718
+ })
1719
+ }
1720
+
1721
+ $.fn.scrollspy.Constructor = ScrollSpy
1722
+
1723
+
1724
+ // SCROLLSPY NO CONFLICT
1725
+ // =====================
1726
+
1727
+ $.fn.scrollspy.noConflict = function () {
1728
+ $.fn.scrollspy = old
1729
+ return this
1730
+ }
1731
+
1732
+
1733
+ // SCROLLSPY DATA-API
1734
+ // ==================
1735
+
1736
+ $(window).on('load', function () {
1737
+ $('[data-spy="scroll"]').each(function () {
1738
+ var $spy = $(this)
1739
+ $spy.scrollspy($spy.data())
1740
+ })
1741
+ })
1742
+
1743
+ }(jQuery);
1744
+
1745
+ /* ========================================================================
1746
+ * Bootstrap: tab.js v3.0.3
1747
+ * http://getbootstrap.com/javascript/#tabs
1748
+ * ========================================================================
1749
+ * Copyright 2013 Twitter, Inc.
1750
+ *
1751
+ * Licensed under the Apache License, Version 2.0 (the "License");
1752
+ * you may not use this file except in compliance with the License.
1753
+ * You may obtain a copy of the License at
1754
+ *
1755
+ * http://www.apache.org/licenses/LICENSE-2.0
1756
+ *
1757
+ * Unless required by applicable law or agreed to in writing, software
1758
+ * distributed under the License is distributed on an "AS IS" BASIS,
1759
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1760
+ * See the License for the specific language governing permissions and
1761
+ * limitations under the License.
1762
+ * ======================================================================== */
1763
+
1764
+
1765
+ +function ($) { "use strict";
1766
+
1767
+ // TAB CLASS DEFINITION
1768
+ // ====================
1769
+
1770
+ var Tab = function (element) {
1771
+ this.element = $(element)
1772
+ }
1773
+
1774
+ Tab.prototype.show = function () {
1775
+ var $this = this.element
1776
+ var $ul = $this.closest('ul:not(.dropdown-menu)')
1777
+ var selector = $this.data('target')
1778
+
1779
+ if (!selector) {
1780
+ selector = $this.attr('href')
1781
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1782
+ }
1783
+
1784
+ if ($this.parent('li').hasClass('active')) return
1785
+
1786
+ var previous = $ul.find('.active:last a')[0]
1787
+ var e = $.Event('show.bs.tab', {
1788
+ relatedTarget: previous
1789
+ })
1790
+
1791
+ $this.trigger(e)
1792
+
1793
+ if (e.isDefaultPrevented()) return
1794
+
1795
+ var $target = $(selector)
1796
+
1797
+ this.activate($this.parent('li'), $ul)
1798
+ this.activate($target, $target.parent(), function () {
1799
+ $this.trigger({
1800
+ type: 'shown.bs.tab'
1801
+ , relatedTarget: previous
1802
+ })
1803
+ })
1804
+ }
1805
+
1806
+ Tab.prototype.activate = function (element, container, callback) {
1807
+ var $active = container.find('> .active')
1808
+ var transition = callback
1809
+ && $.support.transition
1810
+ && $active.hasClass('fade')
1811
+
1812
+ function next() {
1813
+ $active
1814
+ .removeClass('active')
1815
+ .find('> .dropdown-menu > .active')
1816
+ .removeClass('active')
1817
+
1818
+ element.addClass('active')
1819
+
1820
+ if (transition) {
1821
+ element[0].offsetWidth // reflow for transition
1822
+ element.addClass('in')
1823
+ } else {
1824
+ element.removeClass('fade')
1825
+ }
1826
+
1827
+ if (element.parent('.dropdown-menu')) {
1828
+ element.closest('li.dropdown').addClass('active')
1829
+ }
1830
+
1831
+ callback && callback()
1832
+ }
1833
+
1834
+ transition ?
1835
+ $active
1836
+ .one($.support.transition.end, next)
1837
+ .emulateTransitionEnd(150) :
1838
+ next()
1839
+
1840
+ $active.removeClass('in')
1841
+ }
1842
+
1843
+
1844
+ // TAB PLUGIN DEFINITION
1845
+ // =====================
1846
+
1847
+ var old = $.fn.tab
1848
+
1849
+ $.fn.tab = function ( option ) {
1850
+ return this.each(function () {
1851
+ var $this = $(this)
1852
+ var data = $this.data('bs.tab')
1853
+
1854
+ if (!data) $this.data('bs.tab', (data = new Tab(this)))
1855
+ if (typeof option == 'string') data[option]()
1856
+ })
1857
+ }
1858
+
1859
+ $.fn.tab.Constructor = Tab
1860
+
1861
+
1862
+ // TAB NO CONFLICT
1863
+ // ===============
1864
+
1865
+ $.fn.tab.noConflict = function () {
1866
+ $.fn.tab = old
1867
+ return this
1868
+ }
1869
+
1870
+
1871
+ // TAB DATA-API
1872
+ // ============
1873
+
1874
+ $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1875
+ e.preventDefault()
1876
+ $(this).tab('show')
1877
+ })
1878
+
1879
+ }(jQuery);
1880
+
1881
+ /* ========================================================================
1882
+ * Bootstrap: affix.js v3.0.3
1883
+ * http://getbootstrap.com/javascript/#affix
1884
+ * ========================================================================
1885
+ * Copyright 2013 Twitter, Inc.
1886
+ *
1887
+ * Licensed under the Apache License, Version 2.0 (the "License");
1888
+ * you may not use this file except in compliance with the License.
1889
+ * You may obtain a copy of the License at
1890
+ *
1891
+ * http://www.apache.org/licenses/LICENSE-2.0
1892
+ *
1893
+ * Unless required by applicable law or agreed to in writing, software
1894
+ * distributed under the License is distributed on an "AS IS" BASIS,
1895
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1896
+ * See the License for the specific language governing permissions and
1897
+ * limitations under the License.
1898
+ * ======================================================================== */
1899
+
1900
+
1901
+ +function ($) { "use strict";
1902
+
1903
+ // AFFIX CLASS DEFINITION
1904
+ // ======================
1905
+
1906
+ var Affix = function (element, options) {
1907
+ this.options = $.extend({}, Affix.DEFAULTS, options)
1908
+ this.$window = $(window)
1909
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
1910
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
1911
+
1912
+ this.$element = $(element)
1913
+ this.affixed =
1914
+ this.unpin = null
1915
+
1916
+ this.checkPosition()
1917
+ }
1918
+
1919
+ Affix.RESET = 'affix affix-top affix-bottom'
1920
+
1921
+ Affix.DEFAULTS = {
1922
+ offset: 0
1923
+ }
1924
+
1925
+ Affix.prototype.checkPositionWithEventLoop = function () {
1926
+ setTimeout($.proxy(this.checkPosition, this), 1)
1927
+ }
1928
+
1929
+ Affix.prototype.checkPosition = function () {
1930
+ if (!this.$element.is(':visible')) return
1931
+
1932
+ var scrollHeight = $(document).height()
1933
+ var scrollTop = this.$window.scrollTop()
1934
+ var position = this.$element.offset()
1935
+ var offset = this.options.offset
1936
+ var offsetTop = offset.top
1937
+ var offsetBottom = offset.bottom
1938
+
1939
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
1940
+ if (typeof offsetTop == 'function') offsetTop = offset.top()
1941
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
1942
+
1943
+ var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
1944
+ offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
1945
+ offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
1946
+
1947
+ if (this.affixed === affix) return
1948
+ if (this.unpin) this.$element.css('top', '')
1949
+
1950
+ this.affixed = affix
1951
+ this.unpin = affix == 'bottom' ? position.top - scrollTop : null
1952
+
1953
+ this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))
1954
+
1955
+ if (affix == 'bottom') {
1956
+ this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
1957
+ }
1958
+ }
1959
+
1960
+
1961
+ // AFFIX PLUGIN DEFINITION
1962
+ // =======================
1963
+
1964
+ var old = $.fn.affix
1965
+
1966
+ $.fn.affix = function (option) {
1967
+ return this.each(function () {
1968
+ var $this = $(this)
1969
+ var data = $this.data('bs.affix')
1970
+ var options = typeof option == 'object' && option
1971
+
1972
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
1973
+ if (typeof option == 'string') data[option]()
1974
+ })
1975
+ }
1976
+
1977
+ $.fn.affix.Constructor = Affix
1978
+
1979
+
1980
+ // AFFIX NO CONFLICT
1981
+ // =================
1982
+
1983
+ $.fn.affix.noConflict = function () {
1984
+ $.fn.affix = old
1985
+ return this
1986
+ }
1987
+
1988
+
1989
+ // AFFIX DATA-API
1990
+ // ==============
1991
+
1992
+ $(window).on('load', function () {
1993
+ $('[data-spy="affix"]').each(function () {
1994
+ var $spy = $(this)
1995
+ var data = $spy.data()
1996
+
1997
+ data.offset = data.offset || {}
1998
+
1999
+ if (data.offsetBottom) data.offset.bottom = data.offsetBottom
2000
+ if (data.offsetTop) data.offset.top = data.offsetTop
2001
+
2002
+ $spy.affix(data)
2003
+ })
2004
+ })
2005
+
2006
+ }(jQuery);