├── .gitattributes ├── .gitignore ├── DJangoHotel ├── __init__.py ├── admin.py ├── models.py ├── static │ ├── css │ │ ├── bootstrap.css │ │ ├── responsive-nav.css │ │ └── styles.css │ ├── js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ ├── jquery-2.1.1.js │ │ ├── responsive-nav.js │ │ └── unslider.js │ └── pic │ │ ├── 6240454_091935658000_2.jpg │ │ ├── hotel-logo.png │ │ ├── key_home_1.jpg │ │ ├── key_home_2.jpg │ │ ├── key_home_3.jpg │ │ └── key_overview_1.jpg ├── tests.py └── viewspackage │ ├── __init__.py │ ├── aboutView.py │ ├── indexView.py │ ├── orderResultView.py │ ├── orderView.py │ └── roomInfoView.py ├── README.md ├── kcsj ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ├── manage.py └── templates ├── 404.html ├── about.html ├── base.html ├── index.html ├── order.html ├── orderresult.html └── roominfo.html /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must ends with two \r. 29 | Icon 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | -------------------------------------------------------------------------------- /DJangoHotel/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ladder1984/DJangoHotel_Python/a39a37041e87af805ec571461d2ec214f304f193/DJangoHotel/__init__.py -------------------------------------------------------------------------------- /DJangoHotel/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | from DJangoHotel.models import Hotel, Customer, RoomInfo,Order 5 | 6 | 7 | class HotelAdmin(admin.ModelAdmin): 8 | list_display = ('name', 'address', 'description') 9 | 10 | class RoomInfoAdmin(admin.ModelAdmin): 11 | list_display = ('name', 'price','total', 'description') 12 | 13 | class OrderAdmin(admin.ModelAdmin): 14 | list_display = ('id','name','tel','cardid','roomtype','begin','end','totalprice','state') 15 | 16 | class customerAdmin(admin.ModelAdmin): 17 | list_display = ('tel','name','cardid') 18 | 19 | admin.site.register(Hotel,HotelAdmin) 20 | admin.site.register(Customer,customerAdmin) 21 | admin.site.register(RoomInfo,RoomInfoAdmin) 22 | admin.site.register(Order,OrderAdmin) -------------------------------------------------------------------------------- /DJangoHotel/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.db import models 3 | 4 | # Create your models here. 5 | 6 | ROOM_TPYE_CHOICES=( 7 | ('standard','标准间'), 8 | ('better','豪华间'), 9 | ('president','总统间') 10 | ) 11 | 12 | ORDER_STATE_CHOICES=( 13 | ('will','预定中'), 14 | ('run','执行中'), 15 | ('end','已结束'), 16 | ('destroyed','已废弃'), 17 | ) 18 | 19 | 20 | class Hotel(models.Model): 21 | name = models.CharField(max_length=30,primary_key=True) 22 | address = models.CharField(max_length=50) 23 | description = models.TextField() 24 | 25 | 26 | class Customer(models.Model): 27 | tel = models.CharField(max_length=50,primary_key=True) 28 | name = models.CharField(max_length=50) 29 | cardid=models.IntegerField(null=True,blank=True) 30 | 31 | class RoomInfo(models.Model): 32 | name = models.CharField(max_length=30,primary_key=True) 33 | price = models.IntegerField(null=True,blank=True) 34 | total = models.IntegerField(null=True,blank=True) 35 | description = models.TextField() 36 | 37 | def __unicode__(self): 38 | return self.name 39 | 40 | 41 | class Order(models.Model): 42 | #id 43 | name = models.CharField(max_length=45) 44 | tel = models.CharField(max_length=45) 45 | cardid = models.CharField(max_length=45) 46 | roomtype = models.CharField(max_length=45,choices= ROOM_TPYE_CHOICES) 47 | begin = models.DateField() 48 | end = models.DateField() 49 | totalprice = models.IntegerField() 50 | state=models.CharField(max_length=45,choices=ORDER_STATE_CHOICES) 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /DJangoHotel/static/css/responsive-nav.css: -------------------------------------------------------------------------------- 1 | /*! responsive-nav.js 1.0.32 by @viljamis */ 2 | 3 | .nav-collapse ul { 4 | margin: 0; 5 | padding: 0; 6 | width: 100%; 7 | display: block; 8 | list-style: none; 9 | } 10 | 11 | .nav-collapse li { 12 | width: 100%; 13 | display: block; 14 | } 15 | 16 | .js .nav-collapse { 17 | clip: rect(0 0 0 0); 18 | max-height: 0; 19 | position: absolute; 20 | display: block; 21 | overflow: hidden; 22 | zoom: 1; 23 | } 24 | 25 | .nav-collapse.opened { 26 | max-height: 9999px; 27 | } 28 | 29 | .disable-pointer-events { 30 | pointer-events: none !important; 31 | } 32 | 33 | .nav-toggle { 34 | -webkit-tap-highlight-color: rgba(0,0,0,0); 35 | -webkit-touch-callout: none; 36 | -webkit-user-select: none; 37 | -moz-user-select: none; 38 | -ms-user-select: none; 39 | -o-user-select: none; 40 | user-select: none; 41 | } 42 | 43 | @media screen and (min-width: 40em) { 44 | .js .nav-collapse { 45 | position: relative; 46 | } 47 | .js .nav-collapse.closed { 48 | max-height: none; 49 | } 50 | .nav-toggle { 51 | display: none; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /DJangoHotel/static/css/styles.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /* ------------------------------------------ 4 | RESET 5 | --------------------------------------------- */ 6 | 7 | body, div, 8 | h1, h2, h3, h4, h5, h6, 9 | p, blockquote, pre, dl, dt, dd, ol, ul, li, hr, 10 | fieldset, form, label, legend, th, td, 11 | article, aside, figure, footer, header, hgroup, menu, nav, section, 12 | summary, hgroup { 13 | margin: 0; 14 | padding: 0; 15 | border: 0; 16 | } 17 | 18 | a:active, 19 | a:hover { 20 | outline: 0; 21 | } 22 | 23 | @-webkit-viewport { width: device-width; } 24 | @-moz-viewport { width: device-width; } 25 | @-ms-viewport { width: device-width; } 26 | @-o-viewport { width: device-width; } 27 | @viewport { width: device-width; } 28 | 29 | 30 | /* ------------------------------------------ 31 | BASE DEMO STYLES 32 | --------------------------------------------- */ 33 | 34 | body { 35 | -webkit-text-size-adjust: 100%; 36 | -ms-text-size-adjust: 100%; 37 | text-size-adjust: 100%; 38 | color: #37302a; 39 | background: #fff; 40 | font: normal 100%/1.4 sans-serif; 41 | } 42 | 43 | section { 44 | border-bottom: 1px solid #999; 45 | float: left; 46 | width: 100%; 47 | height: 800px; 48 | } 49 | 50 | 51 | /* ------------------------------------------ 52 | NAVIGATION STYLES 53 | (+ responsive-nav.css file is loaded in the ) 54 | --------------------------------------------- */ 55 | 56 | .fixed { 57 | position: fixed; 58 | width: 100%; 59 | top: 0; 60 | left: 0; 61 | } 62 | 63 | .nav-collapse, 64 | .nav-collapse * { 65 | -moz-box-sizing: border-box; 66 | -webkit-box-sizing: border-box; 67 | box-sizing: border-box; 68 | } 69 | 70 | .nav-collapse, 71 | .nav-collapse ul { 72 | list-style: none; 73 | width: 100%; 74 | float: left; 75 | } 76 | 77 | .nav-collapse li { 78 | float: left; 79 | width: 100%; 80 | } 81 | 82 | @media screen and (min-width: 40em) { 83 | .nav-collapse li { 84 | width: 25%; 85 | *width: 24.9%; /* IE7 Hack */ 86 | _width: 19%; /* IE6 Hack */ 87 | } 88 | } 89 | 90 | .nav-collapse a { 91 | color: #fff; 92 | text-decoration: none; 93 | width: 100%; 94 | background: #403D3A; 95 | border-bottom: 1px solid white; 96 | padding: 0.7em 1em; 97 | float: left; 98 | } 99 | .nav-collapse a:hover { 100 | background: #53514E; 101 | } 102 | 103 | @media screen and (min-width: 40em) { 104 | .nav-collapse a { 105 | margin: 0; 106 | padding: 1em; 107 | float: left; 108 | text-align: center; 109 | border-bottom: 0; 110 | border-right: 1px solid white; 111 | } 112 | } 113 | 114 | .nav-collapse ul ul a { 115 | background: #ca3716; 116 | padding-left: 2em; 117 | } 118 | 119 | @media screen and (min-width: 40em) { 120 | .nav-collapse ul ul a { 121 | display: none; 122 | } 123 | } 124 | 125 | 126 | /* ------------------------------------------ 127 | NAV TOGGLE STYLES 128 | --------------------------------------------- */ 129 | 130 | @font-face { 131 | font-family: "responsivenav"; 132 | src:url("../icons/responsivenav.eot"); 133 | src:url("../icons/responsivenav.eot?#iefix") format("embedded-opentype"), 134 | url("../icons/responsivenav.ttf") format("truetype"), 135 | url("../icons/responsivenav.woff") format("woff"), 136 | url("../icons/responsivenav.svg#responsivenav") format("svg"); 137 | font-weight: normal; 138 | font-style: normal; 139 | } 140 | 141 | .nav-toggle { 142 | position: fixed; 143 | -webkit-font-smoothing: antialiased; 144 | -moz-osx-font-smoothing: grayscale; 145 | -webkit-touch-callout: none; 146 | -webkit-user-select: none; 147 | -moz-user-select: none; 148 | -ms-user-select: none; 149 | user-select: none; 150 | text-decoration: none; 151 | text-indent: -999px; 152 | position: relative; 153 | overflow: hidden; 154 | width: 70px; 155 | height: 55px; 156 | float: right; 157 | } 158 | 159 | .nav-toggle:before { 160 | color: #ffffff; /* Edit this to change the icon color */ 161 | font-family: "responsivenav", sans-serif; 162 | font-style: normal; 163 | font-weight: normal; 164 | font-variant: normal; 165 | font-size: 28px; 166 | text-transform: none; 167 | position: absolute; 168 | content: "≡"; 169 | text-indent: 0; 170 | text-align: center; 171 | line-height: 55px; 172 | speak: none; 173 | width: 100%; 174 | top: 0; 175 | left: 0; 176 | } 177 | 178 | .nav-toggle.active::before { 179 | font-size: 24px; 180 | content:"x"; 181 | } 182 | 183 | .banner { position: relative; overflow: auto;} 184 | .banner li { list-style: none; } 185 | .banner ul li { float: left; } 186 | 187 | 188 | .banner .dots { 189 | position: absolute; 190 | left: 40px; 191 | right: 0; 192 | bottom: 20px; 193 | } 194 | .banner .dots li { 195 | display: inline-block; 196 | width: 30px; 197 | height: 8px; 198 | margin: 0 4px; 199 | 200 | text-indent: -999em; 201 | 202 | border: 2px solid #fff; 203 | box-shadow: 0 0 10px rgba(0,0,0,0.8); 204 | 205 | 206 | cursor: pointer; 207 | opacity: .4; 208 | 209 | -webkit-transition: background .5s, opacity .5s; 210 | -moz-transition: background .5s, opacity .5s; 211 | transition: background .5s, opacity .5s; 212 | } 213 | .banner .dots li.active { 214 | background: #fff; 215 | opacity: 1; 216 | } 217 | 218 | 219 | /* ------------------------------------------ 220 | MAIN 221 | --------------------------------------------- */ 222 | 223 | *:hover { 224 | transition: all .7s; 225 | -moz-transition: all .7s; 226 | -webkit-transition: all .7s; 227 | -o-transition: all .7s; 228 | } 229 | 230 | .container-fluid { 231 | margin: 0 !important; 232 | padding: 0 !important; 233 | } 234 | .wrap { 235 | width: 1080px; 236 | margin: 0px auto; 237 | padding: 0px 0px 0px 0px; 238 | font-family: Helvetica, Tahoma, Arial, STXihei, "华文细黑", "Microsoft YaHei", "微软雅黑", SimSun, "宋体", Heiti, "黑体" ,sans-serif !important; 239 | background: #fff; 240 | color: #403D3A; 241 | } 242 | 243 | .wrap .hotel-logo { 244 | padding: 40px 0px; 245 | text-align: center 246 | } 247 | 248 | .wrap .nav-collapse a { 249 | font-size: 1.6em 250 | } 251 | 252 | .wrap >.panel-default { 253 | width: 60%; 254 | line-height: 1.5; 255 | font-size: 1.6em; 256 | margin-top: 40px; 257 | } 258 | .wrap .banner { 259 | position: relative; 260 | } 261 | 262 | 263 | .wrap .order { 264 | position: absolute; 265 | right: 40px; 266 | bottom: 20px; 267 | text-align: center; 268 | color: #fff; 269 | border: 5px solid rgba(255,255,255,0.6); 270 | 271 | } 272 | 273 | .wrap .order a { 274 | display: block; 275 | background: rgba(0,0,0,0.8); 276 | padding: 20px 40px; 277 | color: #fff; 278 | text-decoration: none; 279 | } 280 | .wrap .order a:hover { 281 | background: #2ecc71; 282 | } 283 | 284 | .about .banner, .room .banner, .order .banner { 285 | float: left; 286 | overflow: hidden; 287 | 288 | } 289 | .about .banner #hotelDescription { 290 | position: absolute; 291 | background: rgba(255,255,255,0.6); 292 | width: 800px; 293 | right: 40px; 294 | bottom: 40px; 295 | padding: 40px; 296 | border: 5px solid rgba(255,255,255,0.4); 297 | font-size: 1.4em; 298 | color: #fff; 299 | text-shadow: 1px 1px rgba(0,0,0,0.2); 300 | } 301 | .about .banner #hotelDescription h2 { 302 | margin-bottom: 20px; 303 | border-bottom: 1px dashed rgba(255,255,255,0.4); 304 | padding-bottom: 10px; 305 | } 306 | 307 | .panel { 308 | border: none; 309 | } 310 | .panel-default > .panel-heading { 311 | border: none; 312 | background: #403D3A; 313 | color: #fff; 314 | } 315 | .panel-body { 316 | background: #eee; 317 | } 318 | 319 | .room #hotelDescription { 320 | padding: 60px 40px 20px 40px; 321 | overflow: hidden; 322 | background: #403D3A; 323 | color: #fff; 324 | } 325 | .room #hotelDescription article { 326 | overflow: hidden; 327 | margin-bottom: 40px; 328 | font-size: 1.3em; 329 | } 330 | .room #hotelDescription img { 331 | float: left; 332 | margin-right: 40px; 333 | } 334 | .room #hotelDescription h3 { 335 | display: inline-block; 336 | width: 10%; 337 | padding-bottom: 10px; 338 | border-bottom: 1px solid rgba(255,255,255,0.4); 339 | margin: 10px 0 10px 0px; 340 | } 341 | .order .banner #hotelDescription { 342 | width: 400px; 343 | bottom: 160px !important; 344 | overflow: hidden; 345 | } 346 | .order input { 347 | display: block; 348 | width: 300px; 349 | margin-bottom: 10px; 350 | padding: 10px 20px; 351 | border: none; 352 | font-size: 1.4em; 353 | color: #666 354 | } 355 | .order input[type=button] { 356 | background: #5cb85c; 357 | color: #fff; 358 | } 359 | 360 | 361 | #footer { 362 | margin-top: 40px; 363 | } 364 | 365 | #footer .panel-body { 366 | text-align: center; 367 | color: #666; 368 | font-size: 1.4em; 369 | } 370 | 371 | #footer #hoteldescription { 372 | border: none; 373 | background: #eee; 374 | border-radius: 0px; 375 | } 376 | 377 | .about #footer { 378 | margin-top: 500px; 379 | } 380 | 381 | #hotelDescription select { color: #333; } 382 | -------------------------------------------------------------------------------- /DJangoHotel/static/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.2.0 (http://getbootstrap.com) 3 | * Copyright 2011-2014 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') } 8 | 9 | /* ======================================================================== 10 | * Bootstrap: transition.js v3.2.0 11 | * http://getbootstrap.com/javascript/#transitions 12 | * ======================================================================== 13 | * Copyright 2011-2014 Twitter, Inc. 14 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 15 | * ======================================================================== */ 16 | 17 | 18 | +function ($) { 19 | 'use strict'; 20 | 21 | // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 22 | // ============================================================ 23 | 24 | function transitionEnd() { 25 | var el = document.createElement('bootstrap') 26 | 27 | var transEndEventNames = { 28 | WebkitTransition : 'webkitTransitionEnd', 29 | MozTransition : 'transitionend', 30 | OTransition : 'oTransitionEnd otransitionend', 31 | transition : 'transitionend' 32 | } 33 | 34 | for (var name in transEndEventNames) { 35 | if (el.style[name] !== undefined) { 36 | return { end: transEndEventNames[name] } 37 | } 38 | } 39 | 40 | return false // explicit for ie8 ( ._.) 41 | } 42 | 43 | // http://blog.alexmaccaw.com/css-transitions 44 | $.fn.emulateTransitionEnd = function (duration) { 45 | var called = false 46 | var $el = this 47 | $(this).one('bsTransitionEnd', function () { called = true }) 48 | var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 49 | setTimeout(callback, duration) 50 | return this 51 | } 52 | 53 | $(function () { 54 | $.support.transition = transitionEnd() 55 | 56 | if (!$.support.transition) return 57 | 58 | $.event.special.bsTransitionEnd = { 59 | bindType: $.support.transition.end, 60 | delegateType: $.support.transition.end, 61 | handle: function (e) { 62 | if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 63 | } 64 | } 65 | }) 66 | 67 | }(jQuery); 68 | 69 | /* ======================================================================== 70 | * Bootstrap: alert.js v3.2.0 71 | * http://getbootstrap.com/javascript/#alerts 72 | * ======================================================================== 73 | * Copyright 2011-2014 Twitter, Inc. 74 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 75 | * ======================================================================== */ 76 | 77 | 78 | +function ($) { 79 | 'use strict'; 80 | 81 | // ALERT CLASS DEFINITION 82 | // ====================== 83 | 84 | var dismiss = '[data-dismiss="alert"]' 85 | var Alert = function (el) { 86 | $(el).on('click', dismiss, this.close) 87 | } 88 | 89 | Alert.VERSION = '3.2.0' 90 | 91 | Alert.prototype.close = function (e) { 92 | var $this = $(this) 93 | var selector = $this.attr('data-target') 94 | 95 | if (!selector) { 96 | selector = $this.attr('href') 97 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 98 | } 99 | 100 | var $parent = $(selector) 101 | 102 | if (e) e.preventDefault() 103 | 104 | if (!$parent.length) { 105 | $parent = $this.hasClass('alert') ? $this : $this.parent() 106 | } 107 | 108 | $parent.trigger(e = $.Event('close.bs.alert')) 109 | 110 | if (e.isDefaultPrevented()) return 111 | 112 | $parent.removeClass('in') 113 | 114 | function removeElement() { 115 | // detach from parent, fire event then clean up data 116 | $parent.detach().trigger('closed.bs.alert').remove() 117 | } 118 | 119 | $.support.transition && $parent.hasClass('fade') ? 120 | $parent 121 | .one('bsTransitionEnd', removeElement) 122 | .emulateTransitionEnd(150) : 123 | removeElement() 124 | } 125 | 126 | 127 | // ALERT PLUGIN DEFINITION 128 | // ======================= 129 | 130 | function Plugin(option) { 131 | return this.each(function () { 132 | var $this = $(this) 133 | var data = $this.data('bs.alert') 134 | 135 | if (!data) $this.data('bs.alert', (data = new Alert(this))) 136 | if (typeof option == 'string') data[option].call($this) 137 | }) 138 | } 139 | 140 | var old = $.fn.alert 141 | 142 | $.fn.alert = Plugin 143 | $.fn.alert.Constructor = Alert 144 | 145 | 146 | // ALERT NO CONFLICT 147 | // ================= 148 | 149 | $.fn.alert.noConflict = function () { 150 | $.fn.alert = old 151 | return this 152 | } 153 | 154 | 155 | // ALERT DATA-API 156 | // ============== 157 | 158 | $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 159 | 160 | }(jQuery); 161 | 162 | /* ======================================================================== 163 | * Bootstrap: button.js v3.2.0 164 | * http://getbootstrap.com/javascript/#buttons 165 | * ======================================================================== 166 | * Copyright 2011-2014 Twitter, Inc. 167 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 168 | * ======================================================================== */ 169 | 170 | 171 | +function ($) { 172 | 'use strict'; 173 | 174 | // BUTTON PUBLIC CLASS DEFINITION 175 | // ============================== 176 | 177 | var Button = function (element, options) { 178 | this.$element = $(element) 179 | this.options = $.extend({}, Button.DEFAULTS, options) 180 | this.isLoading = false 181 | } 182 | 183 | Button.VERSION = '3.2.0' 184 | 185 | Button.DEFAULTS = { 186 | loadingText: 'loading...' 187 | } 188 | 189 | Button.prototype.setState = function (state) { 190 | var d = 'disabled' 191 | var $el = this.$element 192 | var val = $el.is('input') ? 'val' : 'html' 193 | var data = $el.data() 194 | 195 | state = state + 'Text' 196 | 197 | if (data.resetText == null) $el.data('resetText', $el[val]()) 198 | 199 | $el[val](data[state] == null ? this.options[state] : data[state]) 200 | 201 | // push to event loop to allow forms to submit 202 | setTimeout($.proxy(function () { 203 | if (state == 'loadingText') { 204 | this.isLoading = true 205 | $el.addClass(d).attr(d, d) 206 | } else if (this.isLoading) { 207 | this.isLoading = false 208 | $el.removeClass(d).removeAttr(d) 209 | } 210 | }, this), 0) 211 | } 212 | 213 | Button.prototype.toggle = function () { 214 | var changed = true 215 | var $parent = this.$element.closest('[data-toggle="buttons"]') 216 | 217 | if ($parent.length) { 218 | var $input = this.$element.find('input') 219 | if ($input.prop('type') == 'radio') { 220 | if ($input.prop('checked') && this.$element.hasClass('active')) changed = false 221 | else $parent.find('.active').removeClass('active') 222 | } 223 | if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') 224 | } 225 | 226 | if (changed) this.$element.toggleClass('active') 227 | } 228 | 229 | 230 | // BUTTON PLUGIN DEFINITION 231 | // ======================== 232 | 233 | function Plugin(option) { 234 | return this.each(function () { 235 | var $this = $(this) 236 | var data = $this.data('bs.button') 237 | var options = typeof option == 'object' && option 238 | 239 | if (!data) $this.data('bs.button', (data = new Button(this, options))) 240 | 241 | if (option == 'toggle') data.toggle() 242 | else if (option) data.setState(option) 243 | }) 244 | } 245 | 246 | var old = $.fn.button 247 | 248 | $.fn.button = Plugin 249 | $.fn.button.Constructor = Button 250 | 251 | 252 | // BUTTON NO CONFLICT 253 | // ================== 254 | 255 | $.fn.button.noConflict = function () { 256 | $.fn.button = old 257 | return this 258 | } 259 | 260 | 261 | // BUTTON DATA-API 262 | // =============== 263 | 264 | $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 265 | var $btn = $(e.target) 266 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 267 | Plugin.call($btn, 'toggle') 268 | e.preventDefault() 269 | }) 270 | 271 | }(jQuery); 272 | 273 | /* ======================================================================== 274 | * Bootstrap: carousel.js v3.2.0 275 | * http://getbootstrap.com/javascript/#carousel 276 | * ======================================================================== 277 | * Copyright 2011-2014 Twitter, Inc. 278 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 279 | * ======================================================================== */ 280 | 281 | 282 | +function ($) { 283 | 'use strict'; 284 | 285 | // CAROUSEL CLASS DEFINITION 286 | // ========================= 287 | 288 | var Carousel = function (element, options) { 289 | this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this)) 290 | this.$indicators = this.$element.find('.carousel-indicators') 291 | this.options = options 292 | this.paused = 293 | this.sliding = 294 | this.interval = 295 | this.$active = 296 | this.$items = null 297 | 298 | this.options.pause == 'hover' && this.$element 299 | .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) 300 | .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) 301 | } 302 | 303 | Carousel.VERSION = '3.2.0' 304 | 305 | Carousel.DEFAULTS = { 306 | interval: 5000, 307 | pause: 'hover', 308 | wrap: true 309 | } 310 | 311 | Carousel.prototype.keydown = function (e) { 312 | switch (e.which) { 313 | case 37: this.prev(); break 314 | case 39: this.next(); break 315 | default: return 316 | } 317 | 318 | e.preventDefault() 319 | } 320 | 321 | Carousel.prototype.cycle = function (e) { 322 | e || (this.paused = false) 323 | 324 | this.interval && clearInterval(this.interval) 325 | 326 | this.options.interval 327 | && !this.paused 328 | && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 329 | 330 | return this 331 | } 332 | 333 | Carousel.prototype.getItemIndex = function (item) { 334 | this.$items = item.parent().children('.item') 335 | return this.$items.index(item || this.$active) 336 | } 337 | 338 | Carousel.prototype.to = function (pos) { 339 | var that = this 340 | var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) 341 | 342 | if (pos > (this.$items.length - 1) || pos < 0) return 343 | 344 | if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" 345 | if (activeIndex == pos) return this.pause().cycle() 346 | 347 | return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) 348 | } 349 | 350 | Carousel.prototype.pause = function (e) { 351 | e || (this.paused = true) 352 | 353 | if (this.$element.find('.next, .prev').length && $.support.transition) { 354 | this.$element.trigger($.support.transition.end) 355 | this.cycle(true) 356 | } 357 | 358 | this.interval = clearInterval(this.interval) 359 | 360 | return this 361 | } 362 | 363 | Carousel.prototype.next = function () { 364 | if (this.sliding) return 365 | return this.slide('next') 366 | } 367 | 368 | Carousel.prototype.prev = function () { 369 | if (this.sliding) return 370 | return this.slide('prev') 371 | } 372 | 373 | Carousel.prototype.slide = function (type, next) { 374 | var $active = this.$element.find('.item.active') 375 | var $next = next || $active[type]() 376 | var isCycling = this.interval 377 | var direction = type == 'next' ? 'left' : 'right' 378 | var fallback = type == 'next' ? 'first' : 'last' 379 | var that = this 380 | 381 | if (!$next.length) { 382 | if (!this.options.wrap) return 383 | $next = this.$element.find('.item')[fallback]() 384 | } 385 | 386 | if ($next.hasClass('active')) return (this.sliding = false) 387 | 388 | var relatedTarget = $next[0] 389 | var slideEvent = $.Event('slide.bs.carousel', { 390 | relatedTarget: relatedTarget, 391 | direction: direction 392 | }) 393 | this.$element.trigger(slideEvent) 394 | if (slideEvent.isDefaultPrevented()) return 395 | 396 | this.sliding = true 397 | 398 | isCycling && this.pause() 399 | 400 | if (this.$indicators.length) { 401 | this.$indicators.find('.active').removeClass('active') 402 | var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) 403 | $nextIndicator && $nextIndicator.addClass('active') 404 | } 405 | 406 | var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" 407 | if ($.support.transition && this.$element.hasClass('slide')) { 408 | $next.addClass(type) 409 | $next[0].offsetWidth // force reflow 410 | $active.addClass(direction) 411 | $next.addClass(direction) 412 | $active 413 | .one('bsTransitionEnd', function () { 414 | $next.removeClass([type, direction].join(' ')).addClass('active') 415 | $active.removeClass(['active', direction].join(' ')) 416 | that.sliding = false 417 | setTimeout(function () { 418 | that.$element.trigger(slidEvent) 419 | }, 0) 420 | }) 421 | .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000) 422 | } else { 423 | $active.removeClass('active') 424 | $next.addClass('active') 425 | this.sliding = false 426 | this.$element.trigger(slidEvent) 427 | } 428 | 429 | isCycling && this.cycle() 430 | 431 | return this 432 | } 433 | 434 | 435 | // CAROUSEL PLUGIN DEFINITION 436 | // ========================== 437 | 438 | function Plugin(option) { 439 | return this.each(function () { 440 | var $this = $(this) 441 | var data = $this.data('bs.carousel') 442 | var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) 443 | var action = typeof option == 'string' ? option : options.slide 444 | 445 | if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) 446 | if (typeof option == 'number') data.to(option) 447 | else if (action) data[action]() 448 | else if (options.interval) data.pause().cycle() 449 | }) 450 | } 451 | 452 | var old = $.fn.carousel 453 | 454 | $.fn.carousel = Plugin 455 | $.fn.carousel.Constructor = Carousel 456 | 457 | 458 | // CAROUSEL NO CONFLICT 459 | // ==================== 460 | 461 | $.fn.carousel.noConflict = function () { 462 | $.fn.carousel = old 463 | return this 464 | } 465 | 466 | 467 | // CAROUSEL DATA-API 468 | // ================= 469 | 470 | $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { 471 | var href 472 | var $this = $(this) 473 | var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 474 | if (!$target.hasClass('carousel')) return 475 | var options = $.extend({}, $target.data(), $this.data()) 476 | var slideIndex = $this.attr('data-slide-to') 477 | if (slideIndex) options.interval = false 478 | 479 | Plugin.call($target, options) 480 | 481 | if (slideIndex) { 482 | $target.data('bs.carousel').to(slideIndex) 483 | } 484 | 485 | e.preventDefault() 486 | }) 487 | 488 | $(window).on('load', function () { 489 | $('[data-ride="carousel"]').each(function () { 490 | var $carousel = $(this) 491 | Plugin.call($carousel, $carousel.data()) 492 | }) 493 | }) 494 | 495 | }(jQuery); 496 | 497 | /* ======================================================================== 498 | * Bootstrap: collapse.js v3.2.0 499 | * http://getbootstrap.com/javascript/#collapse 500 | * ======================================================================== 501 | * Copyright 2011-2014 Twitter, Inc. 502 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 503 | * ======================================================================== */ 504 | 505 | 506 | +function ($) { 507 | 'use strict'; 508 | 509 | // COLLAPSE PUBLIC CLASS DEFINITION 510 | // ================================ 511 | 512 | var Collapse = function (element, options) { 513 | this.$element = $(element) 514 | this.options = $.extend({}, Collapse.DEFAULTS, options) 515 | this.transitioning = null 516 | 517 | if (this.options.parent) this.$parent = $(this.options.parent) 518 | if (this.options.toggle) this.toggle() 519 | } 520 | 521 | Collapse.VERSION = '3.2.0' 522 | 523 | Collapse.DEFAULTS = { 524 | toggle: true 525 | } 526 | 527 | Collapse.prototype.dimension = function () { 528 | var hasWidth = this.$element.hasClass('width') 529 | return hasWidth ? 'width' : 'height' 530 | } 531 | 532 | Collapse.prototype.show = function () { 533 | if (this.transitioning || this.$element.hasClass('in')) return 534 | 535 | var startEvent = $.Event('show.bs.collapse') 536 | this.$element.trigger(startEvent) 537 | if (startEvent.isDefaultPrevented()) return 538 | 539 | var actives = this.$parent && this.$parent.find('> .panel > .in') 540 | 541 | if (actives && actives.length) { 542 | var hasData = actives.data('bs.collapse') 543 | if (hasData && hasData.transitioning) return 544 | Plugin.call(actives, 'hide') 545 | hasData || actives.data('bs.collapse', null) 546 | } 547 | 548 | var dimension = this.dimension() 549 | 550 | this.$element 551 | .removeClass('collapse') 552 | .addClass('collapsing')[dimension](0) 553 | 554 | this.transitioning = 1 555 | 556 | var complete = function () { 557 | this.$element 558 | .removeClass('collapsing') 559 | .addClass('collapse in')[dimension]('') 560 | this.transitioning = 0 561 | this.$element 562 | .trigger('shown.bs.collapse') 563 | } 564 | 565 | if (!$.support.transition) return complete.call(this) 566 | 567 | var scrollSize = $.camelCase(['scroll', dimension].join('-')) 568 | 569 | this.$element 570 | .one('bsTransitionEnd', $.proxy(complete, this)) 571 | .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 572 | } 573 | 574 | Collapse.prototype.hide = function () { 575 | if (this.transitioning || !this.$element.hasClass('in')) return 576 | 577 | var startEvent = $.Event('hide.bs.collapse') 578 | this.$element.trigger(startEvent) 579 | if (startEvent.isDefaultPrevented()) return 580 | 581 | var dimension = this.dimension() 582 | 583 | this.$element[dimension](this.$element[dimension]())[0].offsetHeight 584 | 585 | this.$element 586 | .addClass('collapsing') 587 | .removeClass('collapse') 588 | .removeClass('in') 589 | 590 | this.transitioning = 1 591 | 592 | var complete = function () { 593 | this.transitioning = 0 594 | this.$element 595 | .trigger('hidden.bs.collapse') 596 | .removeClass('collapsing') 597 | .addClass('collapse') 598 | } 599 | 600 | if (!$.support.transition) return complete.call(this) 601 | 602 | this.$element 603 | [dimension](0) 604 | .one('bsTransitionEnd', $.proxy(complete, this)) 605 | .emulateTransitionEnd(350) 606 | } 607 | 608 | Collapse.prototype.toggle = function () { 609 | this[this.$element.hasClass('in') ? 'hide' : 'show']() 610 | } 611 | 612 | 613 | // COLLAPSE PLUGIN DEFINITION 614 | // ========================== 615 | 616 | function Plugin(option) { 617 | return this.each(function () { 618 | var $this = $(this) 619 | var data = $this.data('bs.collapse') 620 | var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 621 | 622 | if (!data && options.toggle && option == 'show') option = !option 623 | if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 624 | if (typeof option == 'string') data[option]() 625 | }) 626 | } 627 | 628 | var old = $.fn.collapse 629 | 630 | $.fn.collapse = Plugin 631 | $.fn.collapse.Constructor = Collapse 632 | 633 | 634 | // COLLAPSE NO CONFLICT 635 | // ==================== 636 | 637 | $.fn.collapse.noConflict = function () { 638 | $.fn.collapse = old 639 | return this 640 | } 641 | 642 | 643 | // COLLAPSE DATA-API 644 | // ================= 645 | 646 | $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 647 | var href 648 | var $this = $(this) 649 | var target = $this.attr('data-target') 650 | || e.preventDefault() 651 | || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 652 | var $target = $(target) 653 | var data = $target.data('bs.collapse') 654 | var option = data ? 'toggle' : $this.data() 655 | var parent = $this.attr('data-parent') 656 | var $parent = parent && $(parent) 657 | 658 | if (!data || !data.transitioning) { 659 | if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 660 | $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 661 | } 662 | 663 | Plugin.call($target, option) 664 | }) 665 | 666 | }(jQuery); 667 | 668 | /* ======================================================================== 669 | * Bootstrap: dropdown.js v3.2.0 670 | * http://getbootstrap.com/javascript/#dropdowns 671 | * ======================================================================== 672 | * Copyright 2011-2014 Twitter, Inc. 673 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 674 | * ======================================================================== */ 675 | 676 | 677 | +function ($) { 678 | 'use strict'; 679 | 680 | // DROPDOWN CLASS DEFINITION 681 | // ========================= 682 | 683 | var backdrop = '.dropdown-backdrop' 684 | var toggle = '[data-toggle="dropdown"]' 685 | var Dropdown = function (element) { 686 | $(element).on('click.bs.dropdown', this.toggle) 687 | } 688 | 689 | Dropdown.VERSION = '3.2.0' 690 | 691 | Dropdown.prototype.toggle = function (e) { 692 | var $this = $(this) 693 | 694 | if ($this.is('.disabled, :disabled')) return 695 | 696 | var $parent = getParent($this) 697 | var isActive = $parent.hasClass('open') 698 | 699 | clearMenus() 700 | 701 | if (!isActive) { 702 | if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 703 | // if mobile we use a backdrop because click events don't delegate 704 | $('