strelka-admin 0.0.1.pre7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.rdoc +4 -0
  3. data/Manifest.txt +58 -0
  4. data/README.rdoc +65 -0
  5. data/Rakefile +42 -0
  6. data/data/strelka-admin/app.conf +7 -0
  7. data/data/strelka-admin/apps/config-service +72 -0
  8. data/data/strelka-admin/apps/strelka-admin +102 -0
  9. data/data/strelka-admin/apps/strelka-setup +32 -0
  10. data/data/strelka-admin/host-config.rb +44 -0
  11. data/data/strelka-admin/static/css/bootstrap-responsive.css +581 -0
  12. data/data/strelka-admin/static/css/bootstrap-responsive.min.css +4 -0
  13. data/data/strelka-admin/static/css/bootstrap.css +3496 -0
  14. data/data/strelka-admin/static/css/bootstrap.min.css +632 -0
  15. data/data/strelka-admin/static/css/master.css +337 -0
  16. data/data/strelka-admin/static/css/reset.css +112 -0
  17. data/data/strelka-admin/static/fonts/IstokWeb-Bold.ttf +0 -0
  18. data/data/strelka-admin/static/fonts/IstokWeb-BoldItalic.ttf +0 -0
  19. data/data/strelka-admin/static/fonts/IstokWeb-Italic.ttf +0 -0
  20. data/data/strelka-admin/static/fonts/IstokWeb-Regular.ttf +0 -0
  21. data/data/strelka-admin/static/fonts/OFL.txt +94 -0
  22. data/data/strelka-admin/static/images/21d1-16.png +0 -0
  23. data/data/strelka-admin/static/images/21d1.png +0 -0
  24. data/data/strelka-admin/static/images/glyphicons-halflings-white.png +0 -0
  25. data/data/strelka-admin/static/images/glyphicons-halflings.png +0 -0
  26. data/data/strelka-admin/static/images/icons/blank.png +0 -0
  27. data/data/strelka-admin/static/images/icons/cross-button.png +0 -0
  28. data/data/strelka-admin/static/images/icons/tick-button.png +0 -0
  29. data/data/strelka-admin/static/images/icons/tick-circle-frame.png +0 -0
  30. data/data/strelka-admin/static/images/icons/tick-circle.png +0 -0
  31. data/data/strelka-admin/static/images/icons/tick-octagon-frame.png +0 -0
  32. data/data/strelka-admin/static/images/icons/tick-octagon.png +0 -0
  33. data/data/strelka-admin/static/images/icons/tick-red.png +0 -0
  34. data/data/strelka-admin/static/images/icons/tick-shield.png +0 -0
  35. data/data/strelka-admin/static/images/icons/tick-small-circle.png +0 -0
  36. data/data/strelka-admin/static/images/icons/tick-small-red.png +0 -0
  37. data/data/strelka-admin/static/images/icons/tick-small-white.png +0 -0
  38. data/data/strelka-admin/static/images/icons/tick-small.png +0 -0
  39. data/data/strelka-admin/static/images/icons/tick-white.png +0 -0
  40. data/data/strelka-admin/static/images/icons/tick.png +0 -0
  41. data/data/strelka-admin/static/images/noise.jpg +0 -0
  42. data/data/strelka-admin/static/images/noise.png +0 -0
  43. data/data/strelka-admin/static/js/admin/app.js +60 -0
  44. data/data/strelka-admin/static/js/vendor/backbone.js +1290 -0
  45. data/data/strelka-admin/static/js/vendor/bootstrap.js +1720 -0
  46. data/data/strelka-admin/static/js/vendor/bootstrap.min.js +1 -0
  47. data/data/strelka-admin/static/js/vendor/jquery-1.7.1.js +9266 -0
  48. data/data/strelka-admin/static/js/vendor/jquery.jeditable.mini.js +38 -0
  49. data/data/strelka-admin/static/js/vendor/jquery.tmpl.min.js +10 -0
  50. data/data/strelka-admin/static/js/vendor/jquery.tmplPlus.min.js +11 -0
  51. data/data/strelka-admin/static/js/vendor/jquery.tools.min.js +20 -0
  52. data/data/strelka-admin/static/js/vendor/json2.js +487 -0
  53. data/data/strelka-admin/static/js/vendor/underscore.js +999 -0
  54. data/data/strelka-admin/templates/admin/console.tmpl +80 -0
  55. data/data/strelka-admin/templates/admin/host.tmpl +75 -0
  56. data/data/strelka-admin/templates/admin/message.tmpl +14 -0
  57. data/data/strelka-admin/templates/admin/server.tmpl +75 -0
  58. data/data/strelka-admin/templates/layout.tmpl +85 -0
  59. data/lib/strelka/admin.rb +63 -0
  60. metadata +210 -0
  61. metadata.gz.sig +0 -0
@@ -0,0 +1,1720 @@
1
+ /* ===================================================
2
+ * bootstrap-transition.js v2.0.1
3
+ * http://twitter.github.com/bootstrap/javascript.html#transitions
4
+ * ===================================================
5
+ * Copyright 2012 Twitter, Inc.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ * ========================================================== */
19
+
20
+ !function( $ ) {
21
+
22
+ $(function () {
23
+
24
+ "use strict"
25
+
26
+ /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
27
+ * ======================================================= */
28
+
29
+ $.support.transition = (function () {
30
+ var thisBody = document.body || document.documentElement
31
+ , thisStyle = thisBody.style
32
+ , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
33
+
34
+ return support && {
35
+ end: (function () {
36
+ var transitionEnd = "TransitionEnd"
37
+ if ( $.browser.webkit ) {
38
+ transitionEnd = "webkitTransitionEnd"
39
+ } else if ( $.browser.mozilla ) {
40
+ transitionEnd = "transitionend"
41
+ } else if ( $.browser.opera ) {
42
+ transitionEnd = "oTransitionEnd"
43
+ }
44
+ return transitionEnd
45
+ }())
46
+ }
47
+ })()
48
+
49
+ })
50
+
51
+ }( window.jQuery );/* ==========================================================
52
+ * bootstrap-alert.js v2.0.1
53
+ * http://twitter.github.com/bootstrap/javascript.html#alerts
54
+ * ==========================================================
55
+ * Copyright 2012 Twitter, Inc.
56
+ *
57
+ * Licensed under the Apache License, Version 2.0 (the "License");
58
+ * you may not use this file except in compliance with the License.
59
+ * You may obtain a copy of the License at
60
+ *
61
+ * http://www.apache.org/licenses/LICENSE-2.0
62
+ *
63
+ * Unless required by applicable law or agreed to in writing, software
64
+ * distributed under the License is distributed on an "AS IS" BASIS,
65
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66
+ * See the License for the specific language governing permissions and
67
+ * limitations under the License.
68
+ * ========================================================== */
69
+
70
+
71
+ !function( $ ){
72
+
73
+ "use strict"
74
+
75
+ /* ALERT CLASS DEFINITION
76
+ * ====================== */
77
+
78
+ var dismiss = '[data-dismiss="alert"]'
79
+ , Alert = function ( el ) {
80
+ $(el).on('click', dismiss, this.close)
81
+ }
82
+
83
+ Alert.prototype = {
84
+
85
+ constructor: Alert
86
+
87
+ , close: function ( e ) {
88
+ var $this = $(this)
89
+ , selector = $this.attr('data-target')
90
+ , $parent
91
+
92
+ if (!selector) {
93
+ selector = $this.attr('href')
94
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
95
+ }
96
+
97
+ $parent = $(selector)
98
+ $parent.trigger('close')
99
+
100
+ e && e.preventDefault()
101
+
102
+ $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
103
+
104
+ $parent
105
+ .trigger('close')
106
+ .removeClass('in')
107
+
108
+ function removeElement() {
109
+ $parent
110
+ .trigger('closed')
111
+ .remove()
112
+ }
113
+
114
+ $.support.transition && $parent.hasClass('fade') ?
115
+ $parent.on($.support.transition.end, removeElement) :
116
+ removeElement()
117
+ }
118
+
119
+ }
120
+
121
+
122
+ /* ALERT PLUGIN DEFINITION
123
+ * ======================= */
124
+
125
+ $.fn.alert = function ( option ) {
126
+ return this.each(function () {
127
+ var $this = $(this)
128
+ , data = $this.data('alert')
129
+ if (!data) $this.data('alert', (data = new Alert(this)))
130
+ if (typeof option == 'string') data[option].call($this)
131
+ })
132
+ }
133
+
134
+ $.fn.alert.Constructor = Alert
135
+
136
+
137
+ /* ALERT DATA-API
138
+ * ============== */
139
+
140
+ $(function () {
141
+ $('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
142
+ })
143
+
144
+ }( window.jQuery );/* ============================================================
145
+ * bootstrap-button.js v2.0.1
146
+ * http://twitter.github.com/bootstrap/javascript.html#buttons
147
+ * ============================================================
148
+ * Copyright 2012 Twitter, Inc.
149
+ *
150
+ * Licensed under the Apache License, Version 2.0 (the "License");
151
+ * you may not use this file except in compliance with the License.
152
+ * You may obtain a copy of the License at
153
+ *
154
+ * http://www.apache.org/licenses/LICENSE-2.0
155
+ *
156
+ * Unless required by applicable law or agreed to in writing, software
157
+ * distributed under the License is distributed on an "AS IS" BASIS,
158
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159
+ * See the License for the specific language governing permissions and
160
+ * limitations under the License.
161
+ * ============================================================ */
162
+
163
+ !function( $ ){
164
+
165
+ "use strict"
166
+
167
+ /* BUTTON PUBLIC CLASS DEFINITION
168
+ * ============================== */
169
+
170
+ var Button = function ( element, options ) {
171
+ this.$element = $(element)
172
+ this.options = $.extend({}, $.fn.button.defaults, options)
173
+ }
174
+
175
+ Button.prototype = {
176
+
177
+ constructor: Button
178
+
179
+ , setState: function ( state ) {
180
+ var d = 'disabled'
181
+ , $el = this.$element
182
+ , data = $el.data()
183
+ , val = $el.is('input') ? 'val' : 'html'
184
+
185
+ state = state + 'Text'
186
+ data.resetText || $el.data('resetText', $el[val]())
187
+
188
+ $el[val](data[state] || this.options[state])
189
+
190
+ // push to event loop to allow forms to submit
191
+ setTimeout(function () {
192
+ state == 'loadingText' ?
193
+ $el.addClass(d).attr(d, d) :
194
+ $el.removeClass(d).removeAttr(d)
195
+ }, 0)
196
+ }
197
+
198
+ , toggle: function () {
199
+ var $parent = this.$element.parent('[data-toggle="buttons-radio"]')
200
+
201
+ $parent && $parent
202
+ .find('.active')
203
+ .removeClass('active')
204
+
205
+ this.$element.toggleClass('active')
206
+ }
207
+
208
+ }
209
+
210
+
211
+ /* BUTTON PLUGIN DEFINITION
212
+ * ======================== */
213
+
214
+ $.fn.button = function ( option ) {
215
+ return this.each(function () {
216
+ var $this = $(this)
217
+ , data = $this.data('button')
218
+ , options = typeof option == 'object' && option
219
+ if (!data) $this.data('button', (data = new Button(this, options)))
220
+ if (option == 'toggle') data.toggle()
221
+ else if (option) data.setState(option)
222
+ })
223
+ }
224
+
225
+ $.fn.button.defaults = {
226
+ loadingText: 'loading...'
227
+ }
228
+
229
+ $.fn.button.Constructor = Button
230
+
231
+
232
+ /* BUTTON DATA-API
233
+ * =============== */
234
+
235
+ $(function () {
236
+ $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
237
+ var $btn = $(e.target)
238
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
239
+ $btn.button('toggle')
240
+ })
241
+ })
242
+
243
+ }( window.jQuery );/* ==========================================================
244
+ * bootstrap-carousel.js v2.0.1
245
+ * http://twitter.github.com/bootstrap/javascript.html#carousel
246
+ * ==========================================================
247
+ * Copyright 2012 Twitter, Inc.
248
+ *
249
+ * Licensed under the Apache License, Version 2.0 (the "License");
250
+ * you may not use this file except in compliance with the License.
251
+ * You may obtain a copy of the License at
252
+ *
253
+ * http://www.apache.org/licenses/LICENSE-2.0
254
+ *
255
+ * Unless required by applicable law or agreed to in writing, software
256
+ * distributed under the License is distributed on an "AS IS" BASIS,
257
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
258
+ * See the License for the specific language governing permissions and
259
+ * limitations under the License.
260
+ * ========================================================== */
261
+
262
+
263
+ !function( $ ){
264
+
265
+ "use strict"
266
+
267
+ /* CAROUSEL CLASS DEFINITION
268
+ * ========================= */
269
+
270
+ var Carousel = function (element, options) {
271
+ this.$element = $(element)
272
+ this.options = $.extend({}, $.fn.carousel.defaults, options)
273
+ this.options.slide && this.slide(this.options.slide)
274
+ }
275
+
276
+ Carousel.prototype = {
277
+
278
+ cycle: function () {
279
+ this.interval = setInterval($.proxy(this.next, this), this.options.interval)
280
+ return this
281
+ }
282
+
283
+ , to: function (pos) {
284
+ var $active = this.$element.find('.active')
285
+ , children = $active.parent().children()
286
+ , activePos = children.index($active)
287
+ , that = this
288
+
289
+ if (pos > (children.length - 1) || pos < 0) return
290
+
291
+ if (this.sliding) {
292
+ return this.$element.one('slid', function () {
293
+ that.to(pos)
294
+ })
295
+ }
296
+
297
+ if (activePos == pos) {
298
+ return this.pause().cycle()
299
+ }
300
+
301
+ return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
302
+ }
303
+
304
+ , pause: function () {
305
+ clearInterval(this.interval)
306
+ this.interval = null
307
+ return this
308
+ }
309
+
310
+ , next: function () {
311
+ if (this.sliding) return
312
+ return this.slide('next')
313
+ }
314
+
315
+ , prev: function () {
316
+ if (this.sliding) return
317
+ return this.slide('prev')
318
+ }
319
+
320
+ , slide: function (type, next) {
321
+ var $active = this.$element.find('.active')
322
+ , $next = next || $active[type]()
323
+ , isCycling = this.interval
324
+ , direction = type == 'next' ? 'left' : 'right'
325
+ , fallback = type == 'next' ? 'first' : 'last'
326
+ , that = this
327
+
328
+ if (!$next.length) return
329
+
330
+ this.sliding = true
331
+
332
+ isCycling && this.pause()
333
+
334
+ $next = $next.length ? $next : this.$element.find('.item')[fallback]()
335
+
336
+ if (!$.support.transition && this.$element.hasClass('slide')) {
337
+ this.$element.trigger('slide')
338
+ $active.removeClass('active')
339
+ $next.addClass('active')
340
+ this.sliding = false
341
+ this.$element.trigger('slid')
342
+ } else {
343
+ $next.addClass(type)
344
+ $next[0].offsetWidth // force reflow
345
+ $active.addClass(direction)
346
+ $next.addClass(direction)
347
+ this.$element.trigger('slide')
348
+ this.$element.one($.support.transition.end, function () {
349
+ $next.removeClass([type, direction].join(' ')).addClass('active')
350
+ $active.removeClass(['active', direction].join(' '))
351
+ that.sliding = false
352
+ setTimeout(function () { that.$element.trigger('slid') }, 0)
353
+ })
354
+ }
355
+
356
+ isCycling && this.cycle()
357
+
358
+ return this
359
+ }
360
+
361
+ }
362
+
363
+
364
+ /* CAROUSEL PLUGIN DEFINITION
365
+ * ========================== */
366
+
367
+ $.fn.carousel = function ( option ) {
368
+ return this.each(function () {
369
+ var $this = $(this)
370
+ , data = $this.data('carousel')
371
+ , options = typeof option == 'object' && option
372
+ if (!data) $this.data('carousel', (data = new Carousel(this, options)))
373
+ if (typeof option == 'number') data.to(option)
374
+ else if (typeof option == 'string' || (option = options.slide)) data[option]()
375
+ else data.cycle()
376
+ })
377
+ }
378
+
379
+ $.fn.carousel.defaults = {
380
+ interval: 5000
381
+ }
382
+
383
+ $.fn.carousel.Constructor = Carousel
384
+
385
+
386
+ /* CAROUSEL DATA-API
387
+ * ================= */
388
+
389
+ $(function () {
390
+ $('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
391
+ var $this = $(this), href
392
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
393
+ , options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
394
+ $target.carousel(options)
395
+ e.preventDefault()
396
+ })
397
+ })
398
+
399
+ }( window.jQuery );/* =============================================================
400
+ * bootstrap-collapse.js v2.0.1
401
+ * http://twitter.github.com/bootstrap/javascript.html#collapse
402
+ * =============================================================
403
+ * Copyright 2012 Twitter, Inc.
404
+ *
405
+ * Licensed under the Apache License, Version 2.0 (the "License");
406
+ * you may not use this file except in compliance with the License.
407
+ * You may obtain a copy of the License at
408
+ *
409
+ * http://www.apache.org/licenses/LICENSE-2.0
410
+ *
411
+ * Unless required by applicable law or agreed to in writing, software
412
+ * distributed under the License is distributed on an "AS IS" BASIS,
413
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
414
+ * See the License for the specific language governing permissions and
415
+ * limitations under the License.
416
+ * ============================================================ */
417
+
418
+ !function( $ ){
419
+
420
+ "use strict"
421
+
422
+ var Collapse = function ( element, options ) {
423
+ this.$element = $(element)
424
+ this.options = $.extend({}, $.fn.collapse.defaults, options)
425
+
426
+ if (this.options["parent"]) {
427
+ this.$parent = $(this.options["parent"])
428
+ }
429
+
430
+ this.options.toggle && this.toggle()
431
+ }
432
+
433
+ Collapse.prototype = {
434
+
435
+ constructor: Collapse
436
+
437
+ , dimension: function () {
438
+ var hasWidth = this.$element.hasClass('width')
439
+ return hasWidth ? 'width' : 'height'
440
+ }
441
+
442
+ , show: function () {
443
+ var dimension = this.dimension()
444
+ , scroll = $.camelCase(['scroll', dimension].join('-'))
445
+ , actives = this.$parent && this.$parent.find('.in')
446
+ , hasData
447
+
448
+ if (actives && actives.length) {
449
+ hasData = actives.data('collapse')
450
+ actives.collapse('hide')
451
+ hasData || actives.data('collapse', null)
452
+ }
453
+
454
+ this.$element[dimension](0)
455
+ this.transition('addClass', 'show', 'shown')
456
+ this.$element[dimension](this.$element[0][scroll])
457
+
458
+ }
459
+
460
+ , hide: function () {
461
+ var dimension = this.dimension()
462
+ this.reset(this.$element[dimension]())
463
+ this.transition('removeClass', 'hide', 'hidden')
464
+ this.$element[dimension](0)
465
+ }
466
+
467
+ , reset: function ( size ) {
468
+ var dimension = this.dimension()
469
+
470
+ this.$element
471
+ .removeClass('collapse')
472
+ [dimension](size || 'auto')
473
+ [0].offsetWidth
474
+
475
+ this.$element.addClass('collapse')
476
+ }
477
+
478
+ , transition: function ( method, startEvent, completeEvent ) {
479
+ var that = this
480
+ , complete = function () {
481
+ if (startEvent == 'show') that.reset()
482
+ that.$element.trigger(completeEvent)
483
+ }
484
+
485
+ this.$element
486
+ .trigger(startEvent)
487
+ [method]('in')
488
+
489
+ $.support.transition && this.$element.hasClass('collapse') ?
490
+ this.$element.one($.support.transition.end, complete) :
491
+ complete()
492
+ }
493
+
494
+ , toggle: function () {
495
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
496
+ }
497
+
498
+ }
499
+
500
+ /* COLLAPSIBLE PLUGIN DEFINITION
501
+ * ============================== */
502
+
503
+ $.fn.collapse = function ( option ) {
504
+ return this.each(function () {
505
+ var $this = $(this)
506
+ , data = $this.data('collapse')
507
+ , options = typeof option == 'object' && option
508
+ if (!data) $this.data('collapse', (data = new Collapse(this, options)))
509
+ if (typeof option == 'string') data[option]()
510
+ })
511
+ }
512
+
513
+ $.fn.collapse.defaults = {
514
+ toggle: true
515
+ }
516
+
517
+ $.fn.collapse.Constructor = Collapse
518
+
519
+
520
+ /* COLLAPSIBLE DATA-API
521
+ * ==================== */
522
+
523
+ $(function () {
524
+ $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
525
+ var $this = $(this), href
526
+ , target = $this.attr('data-target')
527
+ || e.preventDefault()
528
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
529
+ , option = $(target).data('collapse') ? 'toggle' : $this.data()
530
+ $(target).collapse(option)
531
+ })
532
+ })
533
+
534
+ }( window.jQuery );/* ============================================================
535
+ * bootstrap-dropdown.js v2.0.1
536
+ * http://twitter.github.com/bootstrap/javascript.html#dropdowns
537
+ * ============================================================
538
+ * Copyright 2012 Twitter, Inc.
539
+ *
540
+ * Licensed under the Apache License, Version 2.0 (the "License");
541
+ * you may not use this file except in compliance with the License.
542
+ * You may obtain a copy of the License at
543
+ *
544
+ * http://www.apache.org/licenses/LICENSE-2.0
545
+ *
546
+ * Unless required by applicable law or agreed to in writing, software
547
+ * distributed under the License is distributed on an "AS IS" BASIS,
548
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
549
+ * See the License for the specific language governing permissions and
550
+ * limitations under the License.
551
+ * ============================================================ */
552
+
553
+
554
+ !function( $ ){
555
+
556
+ "use strict"
557
+
558
+ /* DROPDOWN CLASS DEFINITION
559
+ * ========================= */
560
+
561
+ var toggle = '[data-toggle="dropdown"]'
562
+ , Dropdown = function ( element ) {
563
+ var $el = $(element).on('click.dropdown.data-api', this.toggle)
564
+ $('html').on('click.dropdown.data-api', function () {
565
+ $el.parent().removeClass('open')
566
+ })
567
+ }
568
+
569
+ Dropdown.prototype = {
570
+
571
+ constructor: Dropdown
572
+
573
+ , toggle: function ( e ) {
574
+ var $this = $(this)
575
+ , selector = $this.attr('data-target')
576
+ , $parent
577
+ , isActive
578
+
579
+ if (!selector) {
580
+ selector = $this.attr('href')
581
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
582
+ }
583
+
584
+ $parent = $(selector)
585
+ $parent.length || ($parent = $this.parent())
586
+
587
+ isActive = $parent.hasClass('open')
588
+
589
+ clearMenus()
590
+ !isActive && $parent.toggleClass('open')
591
+
592
+ return false
593
+ }
594
+
595
+ }
596
+
597
+ function clearMenus() {
598
+ $(toggle).parent().removeClass('open')
599
+ }
600
+
601
+
602
+ /* DROPDOWN PLUGIN DEFINITION
603
+ * ========================== */
604
+
605
+ $.fn.dropdown = function ( option ) {
606
+ return this.each(function () {
607
+ var $this = $(this)
608
+ , data = $this.data('dropdown')
609
+ if (!data) $this.data('dropdown', (data = new Dropdown(this)))
610
+ if (typeof option == 'string') data[option].call($this)
611
+ })
612
+ }
613
+
614
+ $.fn.dropdown.Constructor = Dropdown
615
+
616
+
617
+ /* APPLY TO STANDARD DROPDOWN ELEMENTS
618
+ * =================================== */
619
+
620
+ $(function () {
621
+ $('html').on('click.dropdown.data-api', clearMenus)
622
+ $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
623
+ })
624
+
625
+ }( window.jQuery );/* =========================================================
626
+ * bootstrap-modal.js v2.0.1
627
+ * http://twitter.github.com/bootstrap/javascript.html#modals
628
+ * =========================================================
629
+ * Copyright 2012 Twitter, Inc.
630
+ *
631
+ * Licensed under the Apache License, Version 2.0 (the "License");
632
+ * you may not use this file except in compliance with the License.
633
+ * You may obtain a copy of the License at
634
+ *
635
+ * http://www.apache.org/licenses/LICENSE-2.0
636
+ *
637
+ * Unless required by applicable law or agreed to in writing, software
638
+ * distributed under the License is distributed on an "AS IS" BASIS,
639
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
640
+ * See the License for the specific language governing permissions and
641
+ * limitations under the License.
642
+ * ========================================================= */
643
+
644
+
645
+ !function( $ ){
646
+
647
+ "use strict"
648
+
649
+ /* MODAL CLASS DEFINITION
650
+ * ====================== */
651
+
652
+ var Modal = function ( content, options ) {
653
+ this.options = options
654
+ this.$element = $(content)
655
+ .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
656
+ }
657
+
658
+ Modal.prototype = {
659
+
660
+ constructor: Modal
661
+
662
+ , toggle: function () {
663
+ return this[!this.isShown ? 'show' : 'hide']()
664
+ }
665
+
666
+ , show: function () {
667
+ var that = this
668
+
669
+ if (this.isShown) return
670
+
671
+ $('body').addClass('modal-open')
672
+
673
+ this.isShown = true
674
+ this.$element.trigger('show')
675
+
676
+ escape.call(this)
677
+ backdrop.call(this, function () {
678
+ var transition = $.support.transition && that.$element.hasClass('fade')
679
+
680
+ !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position
681
+
682
+ that.$element
683
+ .show()
684
+
685
+ if (transition) {
686
+ that.$element[0].offsetWidth // force reflow
687
+ }
688
+
689
+ that.$element.addClass('in')
690
+
691
+ transition ?
692
+ that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
693
+ that.$element.trigger('shown')
694
+
695
+ })
696
+ }
697
+
698
+ , hide: function ( e ) {
699
+ e && e.preventDefault()
700
+
701
+ if (!this.isShown) return
702
+
703
+ var that = this
704
+ this.isShown = false
705
+
706
+ $('body').removeClass('modal-open')
707
+
708
+ escape.call(this)
709
+
710
+ this.$element
711
+ .trigger('hide')
712
+ .removeClass('in')
713
+
714
+ $.support.transition && this.$element.hasClass('fade') ?
715
+ hideWithTransition.call(this) :
716
+ hideModal.call(this)
717
+ }
718
+
719
+ }
720
+
721
+
722
+ /* MODAL PRIVATE METHODS
723
+ * ===================== */
724
+
725
+ function hideWithTransition() {
726
+ var that = this
727
+ , timeout = setTimeout(function () {
728
+ that.$element.off($.support.transition.end)
729
+ hideModal.call(that)
730
+ }, 500)
731
+
732
+ this.$element.one($.support.transition.end, function () {
733
+ clearTimeout(timeout)
734
+ hideModal.call(that)
735
+ })
736
+ }
737
+
738
+ function hideModal( that ) {
739
+ this.$element
740
+ .hide()
741
+ .trigger('hidden')
742
+
743
+ backdrop.call(this)
744
+ }
745
+
746
+ function backdrop( callback ) {
747
+ var that = this
748
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
749
+
750
+ if (this.isShown && this.options.backdrop) {
751
+ var doAnimate = $.support.transition && animate
752
+
753
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
754
+ .appendTo(document.body)
755
+
756
+ if (this.options.backdrop != 'static') {
757
+ this.$backdrop.click($.proxy(this.hide, this))
758
+ }
759
+
760
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
761
+
762
+ this.$backdrop.addClass('in')
763
+
764
+ doAnimate ?
765
+ this.$backdrop.one($.support.transition.end, callback) :
766
+ callback()
767
+
768
+ } else if (!this.isShown && this.$backdrop) {
769
+ this.$backdrop.removeClass('in')
770
+
771
+ $.support.transition && this.$element.hasClass('fade')?
772
+ this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
773
+ removeBackdrop.call(this)
774
+
775
+ } else if (callback) {
776
+ callback()
777
+ }
778
+ }
779
+
780
+ function removeBackdrop() {
781
+ this.$backdrop.remove()
782
+ this.$backdrop = null
783
+ }
784
+
785
+ function escape() {
786
+ var that = this
787
+ if (this.isShown && this.options.keyboard) {
788
+ $(document).on('keyup.dismiss.modal', function ( e ) {
789
+ e.which == 27 && that.hide()
790
+ })
791
+ } else if (!this.isShown) {
792
+ $(document).off('keyup.dismiss.modal')
793
+ }
794
+ }
795
+
796
+
797
+ /* MODAL PLUGIN DEFINITION
798
+ * ======================= */
799
+
800
+ $.fn.modal = function ( option ) {
801
+ return this.each(function () {
802
+ var $this = $(this)
803
+ , data = $this.data('modal')
804
+ , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
805
+ if (!data) $this.data('modal', (data = new Modal(this, options)))
806
+ if (typeof option == 'string') data[option]()
807
+ else if (options.show) data.show()
808
+ })
809
+ }
810
+
811
+ $.fn.modal.defaults = {
812
+ backdrop: true
813
+ , keyboard: true
814
+ , show: true
815
+ }
816
+
817
+ $.fn.modal.Constructor = Modal
818
+
819
+
820
+ /* MODAL DATA-API
821
+ * ============== */
822
+
823
+ $(function () {
824
+ $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
825
+ var $this = $(this), href
826
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
827
+ , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
828
+
829
+ e.preventDefault()
830
+ $target.modal(option)
831
+ })
832
+ })
833
+
834
+ }( window.jQuery );/* ===========================================================
835
+ * bootstrap-tooltip.js v2.0.1
836
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
837
+ * Inspired by the original jQuery.tipsy by Jason Frame
838
+ * ===========================================================
839
+ * Copyright 2012 Twitter, Inc.
840
+ *
841
+ * Licensed under the Apache License, Version 2.0 (the "License");
842
+ * you may not use this file except in compliance with the License.
843
+ * You may obtain a copy of the License at
844
+ *
845
+ * http://www.apache.org/licenses/LICENSE-2.0
846
+ *
847
+ * Unless required by applicable law or agreed to in writing, software
848
+ * distributed under the License is distributed on an "AS IS" BASIS,
849
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
850
+ * See the License for the specific language governing permissions and
851
+ * limitations under the License.
852
+ * ========================================================== */
853
+
854
+ !function( $ ) {
855
+
856
+ "use strict"
857
+
858
+ /* TOOLTIP PUBLIC CLASS DEFINITION
859
+ * =============================== */
860
+
861
+ var Tooltip = function ( element, options ) {
862
+ this.init('tooltip', element, options)
863
+ }
864
+
865
+ Tooltip.prototype = {
866
+
867
+ constructor: Tooltip
868
+
869
+ , init: function ( type, element, options ) {
870
+ var eventIn
871
+ , eventOut
872
+
873
+ this.type = type
874
+ this.$element = $(element)
875
+ this.options = this.getOptions(options)
876
+ this.enabled = true
877
+
878
+ if (this.options.trigger != 'manual') {
879
+ eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
880
+ eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
881
+ this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
882
+ this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
883
+ }
884
+
885
+ this.options.selector ?
886
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
887
+ this.fixTitle()
888
+ }
889
+
890
+ , getOptions: function ( options ) {
891
+ options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
892
+
893
+ if (options.delay && typeof options.delay == 'number') {
894
+ options.delay = {
895
+ show: options.delay
896
+ , hide: options.delay
897
+ }
898
+ }
899
+
900
+ return options
901
+ }
902
+
903
+ , enter: function ( e ) {
904
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
905
+
906
+ if (!self.options.delay || !self.options.delay.show) {
907
+ self.show()
908
+ } else {
909
+ self.hoverState = 'in'
910
+ setTimeout(function() {
911
+ if (self.hoverState == 'in') {
912
+ self.show()
913
+ }
914
+ }, self.options.delay.show)
915
+ }
916
+ }
917
+
918
+ , leave: function ( e ) {
919
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
920
+
921
+ if (!self.options.delay || !self.options.delay.hide) {
922
+ self.hide()
923
+ } else {
924
+ self.hoverState = 'out'
925
+ setTimeout(function() {
926
+ if (self.hoverState == 'out') {
927
+ self.hide()
928
+ }
929
+ }, self.options.delay.hide)
930
+ }
931
+ }
932
+
933
+ , show: function () {
934
+ var $tip
935
+ , inside
936
+ , pos
937
+ , actualWidth
938
+ , actualHeight
939
+ , placement
940
+ , tp
941
+
942
+ if (this.hasContent() && this.enabled) {
943
+ $tip = this.tip()
944
+ this.setContent()
945
+
946
+ if (this.options.animation) {
947
+ $tip.addClass('fade')
948
+ }
949
+
950
+ placement = typeof this.options.placement == 'function' ?
951
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
952
+ this.options.placement
953
+
954
+ inside = /in/.test(placement)
955
+
956
+ $tip
957
+ .remove()
958
+ .css({ top: 0, left: 0, display: 'block' })
959
+ .appendTo(inside ? this.$element : document.body)
960
+
961
+ pos = this.getPosition(inside)
962
+
963
+ actualWidth = $tip[0].offsetWidth
964
+ actualHeight = $tip[0].offsetHeight
965
+
966
+ switch (inside ? placement.split(' ')[1] : placement) {
967
+ case 'bottom':
968
+ tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
969
+ break
970
+ case 'top':
971
+ tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
972
+ break
973
+ case 'left':
974
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
975
+ break
976
+ case 'right':
977
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
978
+ break
979
+ }
980
+
981
+ $tip
982
+ .css(tp)
983
+ .addClass(placement)
984
+ .addClass('in')
985
+ }
986
+ }
987
+
988
+ , setContent: function () {
989
+ var $tip = this.tip()
990
+ $tip.find('.tooltip-inner').html(this.getTitle())
991
+ $tip.removeClass('fade in top bottom left right')
992
+ }
993
+
994
+ , hide: function () {
995
+ var that = this
996
+ , $tip = this.tip()
997
+
998
+ $tip.removeClass('in')
999
+
1000
+ function removeWithAnimation() {
1001
+ var timeout = setTimeout(function () {
1002
+ $tip.off($.support.transition.end).remove()
1003
+ }, 500)
1004
+
1005
+ $tip.one($.support.transition.end, function () {
1006
+ clearTimeout(timeout)
1007
+ $tip.remove()
1008
+ })
1009
+ }
1010
+
1011
+ $.support.transition && this.$tip.hasClass('fade') ?
1012
+ removeWithAnimation() :
1013
+ $tip.remove()
1014
+ }
1015
+
1016
+ , fixTitle: function () {
1017
+ var $e = this.$element
1018
+ if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
1019
+ $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
1020
+ }
1021
+ }
1022
+
1023
+ , hasContent: function () {
1024
+ return this.getTitle()
1025
+ }
1026
+
1027
+ , getPosition: function (inside) {
1028
+ return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
1029
+ width: this.$element[0].offsetWidth
1030
+ , height: this.$element[0].offsetHeight
1031
+ })
1032
+ }
1033
+
1034
+ , getTitle: function () {
1035
+ var title
1036
+ , $e = this.$element
1037
+ , o = this.options
1038
+
1039
+ title = $e.attr('data-original-title')
1040
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
1041
+
1042
+ title = title.toString().replace(/(^\s*|\s*$)/, "")
1043
+
1044
+ return title
1045
+ }
1046
+
1047
+ , tip: function () {
1048
+ return this.$tip = this.$tip || $(this.options.template)
1049
+ }
1050
+
1051
+ , validate: function () {
1052
+ if (!this.$element[0].parentNode) {
1053
+ this.hide()
1054
+ this.$element = null
1055
+ this.options = null
1056
+ }
1057
+ }
1058
+
1059
+ , enable: function () {
1060
+ this.enabled = true
1061
+ }
1062
+
1063
+ , disable: function () {
1064
+ this.enabled = false
1065
+ }
1066
+
1067
+ , toggleEnabled: function () {
1068
+ this.enabled = !this.enabled
1069
+ }
1070
+
1071
+ , toggle: function () {
1072
+ this[this.tip().hasClass('in') ? 'hide' : 'show']()
1073
+ }
1074
+
1075
+ }
1076
+
1077
+
1078
+ /* TOOLTIP PLUGIN DEFINITION
1079
+ * ========================= */
1080
+
1081
+ $.fn.tooltip = function ( option ) {
1082
+ return this.each(function () {
1083
+ var $this = $(this)
1084
+ , data = $this.data('tooltip')
1085
+ , options = typeof option == 'object' && option
1086
+ if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
1087
+ if (typeof option == 'string') data[option]()
1088
+ })
1089
+ }
1090
+
1091
+ $.fn.tooltip.Constructor = Tooltip
1092
+
1093
+ $.fn.tooltip.defaults = {
1094
+ animation: true
1095
+ , delay: 0
1096
+ , selector: false
1097
+ , placement: 'top'
1098
+ , trigger: 'hover'
1099
+ , title: ''
1100
+ , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
1101
+ }
1102
+
1103
+ }( window.jQuery );/* ===========================================================
1104
+ * bootstrap-popover.js v2.0.1
1105
+ * http://twitter.github.com/bootstrap/javascript.html#popovers
1106
+ * ===========================================================
1107
+ * Copyright 2012 Twitter, Inc.
1108
+ *
1109
+ * Licensed under the Apache License, Version 2.0 (the "License");
1110
+ * you may not use this file except in compliance with the License.
1111
+ * You may obtain a copy of the License at
1112
+ *
1113
+ * http://www.apache.org/licenses/LICENSE-2.0
1114
+ *
1115
+ * Unless required by applicable law or agreed to in writing, software
1116
+ * distributed under the License is distributed on an "AS IS" BASIS,
1117
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1118
+ * See the License for the specific language governing permissions and
1119
+ * limitations under the License.
1120
+ * =========================================================== */
1121
+
1122
+
1123
+ !function( $ ) {
1124
+
1125
+ "use strict"
1126
+
1127
+ var Popover = function ( element, options ) {
1128
+ this.init('popover', element, options)
1129
+ }
1130
+
1131
+ /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
1132
+ ========================================== */
1133
+
1134
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
1135
+
1136
+ constructor: Popover
1137
+
1138
+ , setContent: function () {
1139
+ var $tip = this.tip()
1140
+ , title = this.getTitle()
1141
+ , content = this.getContent()
1142
+
1143
+ $tip.find('.popover-title')[ $.type(title) == 'object' ? 'append' : 'html' ](title)
1144
+ $tip.find('.popover-content > *')[ $.type(content) == 'object' ? 'append' : 'html' ](content)
1145
+
1146
+ $tip.removeClass('fade top bottom left right in')
1147
+ }
1148
+
1149
+ , hasContent: function () {
1150
+ return this.getTitle() || this.getContent()
1151
+ }
1152
+
1153
+ , getContent: function () {
1154
+ var content
1155
+ , $e = this.$element
1156
+ , o = this.options
1157
+
1158
+ content = $e.attr('data-content')
1159
+ || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
1160
+
1161
+ content = content.toString().replace(/(^\s*|\s*$)/, "")
1162
+
1163
+ return content
1164
+ }
1165
+
1166
+ , tip: function() {
1167
+ if (!this.$tip) {
1168
+ this.$tip = $(this.options.template)
1169
+ }
1170
+ return this.$tip
1171
+ }
1172
+
1173
+ })
1174
+
1175
+
1176
+ /* POPOVER PLUGIN DEFINITION
1177
+ * ======================= */
1178
+
1179
+ $.fn.popover = function ( option ) {
1180
+ return this.each(function () {
1181
+ var $this = $(this)
1182
+ , data = $this.data('popover')
1183
+ , options = typeof option == 'object' && option
1184
+ if (!data) $this.data('popover', (data = new Popover(this, options)))
1185
+ if (typeof option == 'string') data[option]()
1186
+ })
1187
+ }
1188
+
1189
+ $.fn.popover.Constructor = Popover
1190
+
1191
+ $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
1192
+ placement: 'right'
1193
+ , content: ''
1194
+ , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
1195
+ })
1196
+
1197
+ }( window.jQuery );/* =============================================================
1198
+ * bootstrap-scrollspy.js v2.0.1
1199
+ * http://twitter.github.com/bootstrap/javascript.html#scrollspy
1200
+ * =============================================================
1201
+ * Copyright 2012 Twitter, Inc.
1202
+ *
1203
+ * Licensed under the Apache License, Version 2.0 (the "License");
1204
+ * you may not use this file except in compliance with the License.
1205
+ * You may obtain a copy of the License at
1206
+ *
1207
+ * http://www.apache.org/licenses/LICENSE-2.0
1208
+ *
1209
+ * Unless required by applicable law or agreed to in writing, software
1210
+ * distributed under the License is distributed on an "AS IS" BASIS,
1211
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
+ * See the License for the specific language governing permissions and
1213
+ * limitations under the License.
1214
+ * ============================================================== */
1215
+
1216
+ !function ( $ ) {
1217
+
1218
+ "use strict"
1219
+
1220
+ /* SCROLLSPY CLASS DEFINITION
1221
+ * ========================== */
1222
+
1223
+ function ScrollSpy( element, options) {
1224
+ var process = $.proxy(this.process, this)
1225
+ , $element = $(element).is('body') ? $(window) : $(element)
1226
+ , href
1227
+ this.options = $.extend({}, $.fn.scrollspy.defaults, options)
1228
+ this.$scrollElement = $element.on('scroll.scroll.data-api', process)
1229
+ this.selector = (this.options.target
1230
+ || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1231
+ || '') + ' .nav li > a'
1232
+ this.$body = $('body').on('click.scroll.data-api', this.selector, process)
1233
+ this.refresh()
1234
+ this.process()
1235
+ }
1236
+
1237
+ ScrollSpy.prototype = {
1238
+
1239
+ constructor: ScrollSpy
1240
+
1241
+ , refresh: function () {
1242
+ this.targets = this.$body
1243
+ .find(this.selector)
1244
+ .map(function () {
1245
+ var href = $(this).attr('href')
1246
+ return /^#\w/.test(href) && $(href).length ? href : null
1247
+ })
1248
+
1249
+ this.offsets = $.map(this.targets, function (id) {
1250
+ return $(id).position().top
1251
+ })
1252
+ }
1253
+
1254
+ , process: function () {
1255
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
1256
+ , offsets = this.offsets
1257
+ , targets = this.targets
1258
+ , activeTarget = this.activeTarget
1259
+ , i
1260
+
1261
+ for (i = offsets.length; i--;) {
1262
+ activeTarget != targets[i]
1263
+ && scrollTop >= offsets[i]
1264
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
1265
+ && this.activate( targets[i] )
1266
+ }
1267
+ }
1268
+
1269
+ , activate: function (target) {
1270
+ var active
1271
+
1272
+ this.activeTarget = target
1273
+
1274
+ this.$body
1275
+ .find(this.selector).parent('.active')
1276
+ .removeClass('active')
1277
+
1278
+ active = this.$body
1279
+ .find(this.selector + '[href="' + target + '"]')
1280
+ .parent('li')
1281
+ .addClass('active')
1282
+
1283
+ if ( active.parent('.dropdown-menu') ) {
1284
+ active.closest('li.dropdown').addClass('active')
1285
+ }
1286
+ }
1287
+
1288
+ }
1289
+
1290
+
1291
+ /* SCROLLSPY PLUGIN DEFINITION
1292
+ * =========================== */
1293
+
1294
+ $.fn.scrollspy = function ( option ) {
1295
+ return this.each(function () {
1296
+ var $this = $(this)
1297
+ , data = $this.data('scrollspy')
1298
+ , options = typeof option == 'object' && option
1299
+ if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
1300
+ if (typeof option == 'string') data[option]()
1301
+ })
1302
+ }
1303
+
1304
+ $.fn.scrollspy.Constructor = ScrollSpy
1305
+
1306
+ $.fn.scrollspy.defaults = {
1307
+ offset: 10
1308
+ }
1309
+
1310
+
1311
+ /* SCROLLSPY DATA-API
1312
+ * ================== */
1313
+
1314
+ $(function () {
1315
+ $('[data-spy="scroll"]').each(function () {
1316
+ var $spy = $(this)
1317
+ $spy.scrollspy($spy.data())
1318
+ })
1319
+ })
1320
+
1321
+ }( window.jQuery );/* ========================================================
1322
+ * bootstrap-tab.js v2.0.1
1323
+ * http://twitter.github.com/bootstrap/javascript.html#tabs
1324
+ * ========================================================
1325
+ * Copyright 2012 Twitter, Inc.
1326
+ *
1327
+ * Licensed under the Apache License, Version 2.0 (the "License");
1328
+ * you may not use this file except in compliance with the License.
1329
+ * You may obtain a copy of the License at
1330
+ *
1331
+ * http://www.apache.org/licenses/LICENSE-2.0
1332
+ *
1333
+ * Unless required by applicable law or agreed to in writing, software
1334
+ * distributed under the License is distributed on an "AS IS" BASIS,
1335
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1336
+ * See the License for the specific language governing permissions and
1337
+ * limitations under the License.
1338
+ * ======================================================== */
1339
+
1340
+
1341
+ !function( $ ){
1342
+
1343
+ "use strict"
1344
+
1345
+ /* TAB CLASS DEFINITION
1346
+ * ==================== */
1347
+
1348
+ var Tab = function ( element ) {
1349
+ this.element = $(element)
1350
+ }
1351
+
1352
+ Tab.prototype = {
1353
+
1354
+ constructor: Tab
1355
+
1356
+ , show: function () {
1357
+ var $this = this.element
1358
+ , $ul = $this.closest('ul:not(.dropdown-menu)')
1359
+ , selector = $this.attr('data-target')
1360
+ , previous
1361
+ , $target
1362
+
1363
+ if (!selector) {
1364
+ selector = $this.attr('href')
1365
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1366
+ }
1367
+
1368
+ if ( $this.parent('li').hasClass('active') ) return
1369
+
1370
+ previous = $ul.find('.active a').last()[0]
1371
+
1372
+ $this.trigger({
1373
+ type: 'show'
1374
+ , relatedTarget: previous
1375
+ })
1376
+
1377
+ $target = $(selector)
1378
+
1379
+ this.activate($this.parent('li'), $ul)
1380
+ this.activate($target, $target.parent(), function () {
1381
+ $this.trigger({
1382
+ type: 'shown'
1383
+ , relatedTarget: previous
1384
+ })
1385
+ })
1386
+ }
1387
+
1388
+ , activate: function ( element, container, callback) {
1389
+ var $active = container.find('> .active')
1390
+ , transition = callback
1391
+ && $.support.transition
1392
+ && $active.hasClass('fade')
1393
+
1394
+ function next() {
1395
+ $active
1396
+ .removeClass('active')
1397
+ .find('> .dropdown-menu > .active')
1398
+ .removeClass('active')
1399
+
1400
+ element.addClass('active')
1401
+
1402
+ if (transition) {
1403
+ element[0].offsetWidth // reflow for transition
1404
+ element.addClass('in')
1405
+ } else {
1406
+ element.removeClass('fade')
1407
+ }
1408
+
1409
+ if ( element.parent('.dropdown-menu') ) {
1410
+ element.closest('li.dropdown').addClass('active')
1411
+ }
1412
+
1413
+ callback && callback()
1414
+ }
1415
+
1416
+ transition ?
1417
+ $active.one($.support.transition.end, next) :
1418
+ next()
1419
+
1420
+ $active.removeClass('in')
1421
+ }
1422
+ }
1423
+
1424
+
1425
+ /* TAB PLUGIN DEFINITION
1426
+ * ===================== */
1427
+
1428
+ $.fn.tab = function ( option ) {
1429
+ return this.each(function () {
1430
+ var $this = $(this)
1431
+ , data = $this.data('tab')
1432
+ if (!data) $this.data('tab', (data = new Tab(this)))
1433
+ if (typeof option == 'string') data[option]()
1434
+ })
1435
+ }
1436
+
1437
+ $.fn.tab.Constructor = Tab
1438
+
1439
+
1440
+ /* TAB DATA-API
1441
+ * ============ */
1442
+
1443
+ $(function () {
1444
+ $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1445
+ e.preventDefault()
1446
+ $(this).tab('show')
1447
+ })
1448
+ })
1449
+
1450
+ }( window.jQuery );/* =============================================================
1451
+ * bootstrap-typeahead.js v2.0.1
1452
+ * http://twitter.github.com/bootstrap/javascript.html#typeahead
1453
+ * =============================================================
1454
+ * Copyright 2012 Twitter, Inc.
1455
+ *
1456
+ * Licensed under the Apache License, Version 2.0 (the "License");
1457
+ * you may not use this file except in compliance with the License.
1458
+ * You may obtain a copy of the License at
1459
+ *
1460
+ * http://www.apache.org/licenses/LICENSE-2.0
1461
+ *
1462
+ * Unless required by applicable law or agreed to in writing, software
1463
+ * distributed under the License is distributed on an "AS IS" BASIS,
1464
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1465
+ * See the License for the specific language governing permissions and
1466
+ * limitations under the License.
1467
+ * ============================================================ */
1468
+
1469
+ !function( $ ){
1470
+
1471
+ "use strict"
1472
+
1473
+ var Typeahead = function ( element, options ) {
1474
+ this.$element = $(element)
1475
+ this.options = $.extend({}, $.fn.typeahead.defaults, options)
1476
+ this.matcher = this.options.matcher || this.matcher
1477
+ this.sorter = this.options.sorter || this.sorter
1478
+ this.highlighter = this.options.highlighter || this.highlighter
1479
+ this.$menu = $(this.options.menu).appendTo('body')
1480
+ this.source = this.options.source
1481
+ this.shown = false
1482
+ this.listen()
1483
+ }
1484
+
1485
+ Typeahead.prototype = {
1486
+
1487
+ constructor: Typeahead
1488
+
1489
+ , select: function () {
1490
+ var val = this.$menu.find('.active').attr('data-value')
1491
+ this.$element.val(val)
1492
+ return this.hide()
1493
+ }
1494
+
1495
+ , show: function () {
1496
+ var pos = $.extend({}, this.$element.offset(), {
1497
+ height: this.$element[0].offsetHeight
1498
+ })
1499
+
1500
+ this.$menu.css({
1501
+ top: pos.top + pos.height
1502
+ , left: pos.left
1503
+ })
1504
+
1505
+ this.$menu.show()
1506
+ this.shown = true
1507
+ return this
1508
+ }
1509
+
1510
+ , hide: function () {
1511
+ this.$menu.hide()
1512
+ this.shown = false
1513
+ return this
1514
+ }
1515
+
1516
+ , lookup: function (event) {
1517
+ var that = this
1518
+ , items
1519
+ , q
1520
+
1521
+ this.query = this.$element.val()
1522
+
1523
+ if (!this.query) {
1524
+ return this.shown ? this.hide() : this
1525
+ }
1526
+
1527
+ items = $.grep(this.source, function (item) {
1528
+ if (that.matcher(item)) return item
1529
+ })
1530
+
1531
+ items = this.sorter(items)
1532
+
1533
+ if (!items.length) {
1534
+ return this.shown ? this.hide() : this
1535
+ }
1536
+
1537
+ return this.render(items.slice(0, this.options.items)).show()
1538
+ }
1539
+
1540
+ , matcher: function (item) {
1541
+ return ~item.toLowerCase().indexOf(this.query.toLowerCase())
1542
+ }
1543
+
1544
+ , sorter: function (items) {
1545
+ var beginswith = []
1546
+ , caseSensitive = []
1547
+ , caseInsensitive = []
1548
+ , item
1549
+
1550
+ while (item = items.shift()) {
1551
+ if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
1552
+ else if (~item.indexOf(this.query)) caseSensitive.push(item)
1553
+ else caseInsensitive.push(item)
1554
+ }
1555
+
1556
+ return beginswith.concat(caseSensitive, caseInsensitive)
1557
+ }
1558
+
1559
+ , highlighter: function (item) {
1560
+ return item.replace(new RegExp('(' + this.query + ')', 'ig'), function ($1, match) {
1561
+ return '<strong>' + match + '</strong>'
1562
+ })
1563
+ }
1564
+
1565
+ , render: function (items) {
1566
+ var that = this
1567
+
1568
+ items = $(items).map(function (i, item) {
1569
+ i = $(that.options.item).attr('data-value', item)
1570
+ i.find('a').html(that.highlighter(item))
1571
+ return i[0]
1572
+ })
1573
+
1574
+ items.first().addClass('active')
1575
+ this.$menu.html(items)
1576
+ return this
1577
+ }
1578
+
1579
+ , next: function (event) {
1580
+ var active = this.$menu.find('.active').removeClass('active')
1581
+ , next = active.next()
1582
+
1583
+ if (!next.length) {
1584
+ next = $(this.$menu.find('li')[0])
1585
+ }
1586
+
1587
+ next.addClass('active')
1588
+ }
1589
+
1590
+ , prev: function (event) {
1591
+ var active = this.$menu.find('.active').removeClass('active')
1592
+ , prev = active.prev()
1593
+
1594
+ if (!prev.length) {
1595
+ prev = this.$menu.find('li').last()
1596
+ }
1597
+
1598
+ prev.addClass('active')
1599
+ }
1600
+
1601
+ , listen: function () {
1602
+ this.$element
1603
+ .on('blur', $.proxy(this.blur, this))
1604
+ .on('keypress', $.proxy(this.keypress, this))
1605
+ .on('keyup', $.proxy(this.keyup, this))
1606
+
1607
+ if ($.browser.webkit || $.browser.msie) {
1608
+ this.$element.on('keydown', $.proxy(this.keypress, this))
1609
+ }
1610
+
1611
+ this.$menu
1612
+ .on('click', $.proxy(this.click, this))
1613
+ .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
1614
+ }
1615
+
1616
+ , keyup: function (e) {
1617
+ e.stopPropagation()
1618
+ e.preventDefault()
1619
+
1620
+ switch(e.keyCode) {
1621
+ case 40: // down arrow
1622
+ case 38: // up arrow
1623
+ break
1624
+
1625
+ case 9: // tab
1626
+ case 13: // enter
1627
+ if (!this.shown) return
1628
+ this.select()
1629
+ break
1630
+
1631
+ case 27: // escape
1632
+ this.hide()
1633
+ break
1634
+
1635
+ default:
1636
+ this.lookup()
1637
+ }
1638
+
1639
+ }
1640
+
1641
+ , keypress: function (e) {
1642
+ e.stopPropagation()
1643
+ if (!this.shown) return
1644
+
1645
+ switch(e.keyCode) {
1646
+ case 9: // tab
1647
+ case 13: // enter
1648
+ case 27: // escape
1649
+ e.preventDefault()
1650
+ break
1651
+
1652
+ case 38: // up arrow
1653
+ e.preventDefault()
1654
+ this.prev()
1655
+ break
1656
+
1657
+ case 40: // down arrow
1658
+ e.preventDefault()
1659
+ this.next()
1660
+ break
1661
+ }
1662
+ }
1663
+
1664
+ , blur: function (e) {
1665
+ var that = this
1666
+ e.stopPropagation()
1667
+ e.preventDefault()
1668
+ setTimeout(function () { that.hide() }, 150)
1669
+ }
1670
+
1671
+ , click: function (e) {
1672
+ e.stopPropagation()
1673
+ e.preventDefault()
1674
+ this.select()
1675
+ }
1676
+
1677
+ , mouseenter: function (e) {
1678
+ this.$menu.find('.active').removeClass('active')
1679
+ $(e.currentTarget).addClass('active')
1680
+ }
1681
+
1682
+ }
1683
+
1684
+
1685
+ /* TYPEAHEAD PLUGIN DEFINITION
1686
+ * =========================== */
1687
+
1688
+ $.fn.typeahead = function ( option ) {
1689
+ return this.each(function () {
1690
+ var $this = $(this)
1691
+ , data = $this.data('typeahead')
1692
+ , options = typeof option == 'object' && option
1693
+ if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
1694
+ if (typeof option == 'string') data[option]()
1695
+ })
1696
+ }
1697
+
1698
+ $.fn.typeahead.defaults = {
1699
+ source: []
1700
+ , items: 8
1701
+ , menu: '<ul class="typeahead dropdown-menu"></ul>'
1702
+ , item: '<li><a href="#"></a></li>'
1703
+ }
1704
+
1705
+ $.fn.typeahead.Constructor = Typeahead
1706
+
1707
+
1708
+ /* TYPEAHEAD DATA-API
1709
+ * ================== */
1710
+
1711
+ $(function () {
1712
+ $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
1713
+ var $this = $(this)
1714
+ if ($this.data('typeahead')) return
1715
+ e.preventDefault()
1716
+ $this.typeahead($this.data())
1717
+ })
1718
+ })
1719
+
1720
+ }( window.jQuery );