├── .DS_Store ├── README.md ├── activate.php ├── admin.php ├── code.php ├── css ├── bootstrap.css └── styles.css ├── functions ├── ajaxfunctions.php ├── db.php ├── fetcharray.php ├── functions.php └── init.php ├── includes ├── footer.php ├── header.php └── nav.php ├── index.php ├── js ├── bootstrap.js ├── jquery.js └── scripts.js ├── login.php ├── login_db.sql ├── logout.php ├── recover.php ├── register.php └── reset.php /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohankrishna225/Email-Verification-SignUp-Form-using-PHP-Mysql/16068c742fe5b05283a5cfd1772c95dd20772b2a/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Email-Verification-SignUp-Form-using-PHP-Mysql 2 | 3 | Email Verification of Signup Forms with Remember Me |Forgot Password |Email-Verification |Admin Page 4 | 5 | Instructions for using this Repo: 6 | 7 | 1.Clone the Repository and Make Sure you have any Local Server installed with PHP version: 7.1.27 and Mysql along with it. 8 | 9 | 2.Import the login_db.sql file into phpmyadmin 10 | 11 | 3.Make sure that databases are correctly imported and change details of the localserver in db.php file. 12 | 13 | 4.Also change the serverpath where you find them in functions.php file 14 | 15 | 5.That's it your done with the configuration to use the repo :) 16 | 17 | -------------------------------------------------------------------------------- /activate.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Activate

13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /admin.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

15 |
16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /code.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 |
18 |
19 | 20 |
21 |
22 |
23 | 24 |
25 |
26 |
27 |
28 |
29 |

Enter Code

30 |
31 |
32 | 33 |
34 |
35 |
36 | 37 |
38 | 39 | 40 |
41 |
42 | 43 | 44 |
45 | 46 |
47 |
48 | 49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | 57 | -------------------------------------------------------------------------------- /css/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 90px; 3 | } 4 | .panel-login { 5 | border-color: #ccc; 6 | -webkit-box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2); 7 | -moz-box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2); 8 | box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.2); 9 | } 10 | .panel-login>.panel-heading { 11 | color: #00415d; 12 | background-color: #fff; 13 | border-color: #fff; 14 | text-align:center; 15 | } 16 | .panel-login>.panel-heading a{ 17 | text-decoration: none; 18 | color: #666; 19 | font-weight: bold; 20 | font-size: 15px; 21 | -webkit-transition: all 0.1s linear; 22 | -moz-transition: all 0.1s linear; 23 | transition: all 0.1s linear; 24 | } 25 | .panel-login>.panel-heading a.active{ 26 | color: #029f5b; 27 | font-size: 18px; 28 | } 29 | .panel-login>.panel-heading hr{ 30 | margin-top: 10px; 31 | margin-bottom: 0px; 32 | clear: both; 33 | border: 0; 34 | height: 1px; 35 | background-image: -webkit-linear-gradient(left,rgba(0, 0, 0, 0),rgba(0, 0, 0, 0.15),rgba(0, 0, 0, 0)); 36 | background-image: -moz-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0)); 37 | background-image: -ms-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0)); 38 | background-image: -o-linear-gradient(left,rgba(0,0,0,0),rgba(0,0,0,0.15),rgba(0,0,0,0)); 39 | } 40 | .panel-login input[type="text"],.panel-login input[type="email"],.panel-login input[type="password"] { 41 | height: 45px; 42 | border: 1px solid #ddd; 43 | font-size: 16px; 44 | -webkit-transition: all 0.1s linear; 45 | -moz-transition: all 0.1s linear; 46 | transition: all 0.1s linear; 47 | } 48 | .panel-login input:hover, 49 | .panel-login input:focus { 50 | outline:none; 51 | -webkit-box-shadow: none; 52 | -moz-box-shadow: none; 53 | box-shadow: none; 54 | border-color: #ccc; 55 | } 56 | .btn-login { 57 | background-color: #59B2E0; 58 | outline: none; 59 | color: #fff; 60 | font-size: 14px; 61 | height: auto; 62 | font-weight: normal; 63 | padding: 14px 0; 64 | text-transform: uppercase; 65 | border-color: #59B2E6; 66 | } 67 | .btn-login:hover, 68 | .btn-login:focus { 69 | color: #fff; 70 | background-color: #53A3CD; 71 | border-color: #53A3CD; 72 | } 73 | .forgot-password { 74 | text-decoration: underline; 75 | color: #888; 76 | } 77 | .forgot-password:hover, 78 | .forgot-password:focus { 79 | text-decoration: underline; 80 | color: #666; 81 | } 82 | 83 | .btn-register { 84 | background-color: #1CB94E; 85 | outline: none; 86 | color: #fff; 87 | font-size: 14px; 88 | height: auto; 89 | font-weight: normal; 90 | padding: 14px 0; 91 | text-transform: uppercase; 92 | border-color: #1CB94A; 93 | } 94 | .btn-register:hover, 95 | .btn-register:focus { 96 | color: #fff; 97 | background-color: #1CA347; 98 | border-color: #1CA347; 99 | } 100 | 101 | 102 | 103 | /* Code Page */ 104 | 105 | #code { 106 | 107 | height: 60px; 108 | width: 50%; 109 | margin: 0 auto; 110 | font-size: 40px; 111 | 112 | } 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /functions/ajaxfunctions.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /functions/db.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /functions/fetcharray.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /functions/functions.php: -------------------------------------------------------------------------------- 1 | 56 | 57 | $error_message 58 | 59 | 60 | DELIMITER; 61 | 62 | return $error_message; 63 | } 64 | 65 | 66 | 67 | function email_exists($email){ 68 | 69 | $sql = "SELECT id FROM users WHERE email ='$email'"; 70 | 71 | $result = query($sql); 72 | 73 | if(row_count($result) ==1){ 74 | return true; 75 | 76 | }else { 77 | return false; 78 | } 79 | } 80 | 81 | 82 | function username_exists($username){ 83 | 84 | $sql = "SELECT id FROM users WHERE username ='$username'"; 85 | 86 | $result = query($sql); 87 | 88 | if(row_count($result) ==1){ 89 | return true; 90 | 91 | }else { 92 | return false; 93 | } 94 | } 95 | 96 | 97 | 98 | function send_email($email, $subject, $msg, $headers) { 99 | 100 | 101 | return (mail($email, $subject, $msg, $headers)); 102 | 103 | 104 | 105 | 106 | } 107 | 108 | 109 | 110 | 111 | /* Validation Functions*/ 112 | 113 | function validate_user_registration(){ 114 | 115 | $errors = []; 116 | 117 | $min = 3; 118 | $max = 20; 119 | 120 | if($_SERVER['REQUEST_METHOD'] == "POST"){ 121 | 122 | $first_name = clean($_POST['first_name']); 123 | $last_name = clean($_POST['last_name']); 124 | $username = clean($_POST['username']); 125 | $email = clean($_POST['email']); 126 | $password = clean($_POST['password']); 127 | $confirm_password = clean($_POST['confirm_password']); 128 | 129 | if(strlen($first_name) < $min) { 130 | 131 | $errors[] = "Your first name cannor be less than {$min} characters "; 132 | 133 | } 134 | 135 | if(strlen($first_name) > $max) { 136 | 137 | $errors[] = "Your first name cannor be greater than {$max} characters "; 138 | 139 | } 140 | 141 | 142 | if(empty($first_name)){ 143 | 144 | $errors[] = "Your Firstname cannot be empty"; 145 | } 146 | 147 | 148 | if(strlen($last_name) < $min) { 149 | 150 | $errors[] = "Your last name cannor be less than {$min} characters "; 151 | 152 | } 153 | 154 | if(strlen($last_name) > $max) { 155 | 156 | $errors[] = "Your last name cannot be greater than {$max} characters "; 157 | 158 | } 159 | 160 | if(strlen($username) > $max) { 161 | 162 | $errors[] = "Your username cannot be greater than {$max} characters "; 163 | 164 | } 165 | 166 | if(strlen($username) < $min) { 167 | 168 | $errors[] = "Your user name cannot be less than {$min} characters "; 169 | 170 | } 171 | 172 | 173 | if(email_exists($email)){ 174 | 175 | $errors[] = "Sorry that email is already registered "; 176 | 177 | } 178 | if(username_exists($username)){ 179 | 180 | $errors[] = "Your that username is already registered "; 181 | 182 | } 183 | 184 | 185 | 186 | 187 | 188 | if(strlen($email) < $min) { 189 | 190 | $errors[] = "Your email cannot be less than {$min} characters "; 191 | 192 | } 193 | 194 | if($password !== $confirm_password) { 195 | 196 | $errors[] = "Your passwords do not match"; 197 | 198 | } 199 | 200 | 201 | 202 | 203 | 204 | 205 | if(!empty($errors)) { 206 | 207 | foreach ($errors as $error) { 208 | 209 | 210 | echo validation_errors($error); 211 | } 212 | } else { 213 | 214 | if(register_user($first_name, $last_name, $username, $email, $password)){ 215 | 216 | set_message("

Please Check Your Email for Activation Link

"); 217 | 218 | redirect("index.php"); 219 | 220 | echo "Users Registered"; 221 | } else { 222 | 223 | set_message("

we could not register the user

"); 224 | } 225 | 226 | } 227 | 228 | 229 | 230 | }//post request 231 | 232 | 233 | 234 | } //function 235 | 236 | 237 | /* ****************** Register user function************** */ 238 | function register_user($first_name, $last_name, $username, $email, $password) { 239 | 240 | 241 | $first_name = escape($first_name); 242 | $last_name = escape($last_name); 243 | $username = escape($username); 244 | $email = escape($email); 245 | $password = escape($password); 246 | 247 | 248 | if(email_exists($email)) { 249 | 250 | return false; 251 | 252 | } else if (username_exists($username)) { 253 | 254 | return false; 255 | 256 | } else { 257 | 258 | $password = md5($password); 259 | 260 | $validation_code = md5($username . microtime()); 261 | 262 | $sql ="INSERT INTO users(first_name, last_name, username, email, password, validation_code, active)"; 263 | $sql.= " VALUES('$first_name','$last_name','$username','$email','$password','$validation_code', 0)"; 264 | $result = query($sql); 265 | confirm($result); 266 | 267 | 268 | 269 | $subject = "Activation of Account"; 270 | $msg = "Please Click the link below to activate your account 271 | http://localhost/udemy/activate.php?email=$email&code=$validation_code"; 272 | 273 | $headers = "From: noreply@urwebsite.com"; 274 | 275 | 276 | send_email($email, $subject, $msg, $headers); 277 | 278 | 279 | 280 | 281 | return true; 282 | 283 | 284 | 285 | 286 | } 287 | 288 | } 289 | 290 | 291 | 292 | /* ****************** Activate user function************** */ 293 | 294 | 295 | function activate_user(){ 296 | 297 | if($_SERVER['REQUEST_METHOD'] == "GET") { 298 | 299 | if(isset($_GET['email'])){ 300 | 301 | 302 | echo $email = clean($_GET['email']); 303 | 304 | echo $validation_code = clean($_GET['code']); 305 | 306 | $sql = "SELECT id FROM users WHERE email = '".escape($_GET['email'])."' AND validation_code ='".escape($_GET['code'])."' "; 307 | $result = query($sql); 308 | confirm($result); 309 | 310 | if(row_count($result) ==1) { 311 | 312 | $sql2 = "UPDATE users SET active =1, validation_code = 0 WHERE email ='".escape($email)."' AND validation_code ='" .escape($validation_code) ."' "; 313 | $result2 = query($sql2); 314 | confirm($result2); 315 | 316 | set_message("

Your Account has been activated please login

"); 317 | 318 | redirect("login.php"); 319 | 320 | 321 | } else { 322 | 323 | 324 | set_message("

Sorry Ur account is not activated

"); 325 | redirect("login.php"); 326 | } 327 | 328 | 329 | } 330 | } 331 | 332 | } //fucntion 333 | 334 | 335 | /*****************Validate user login Functions************** */ 336 | function validate_user_login() { 337 | 338 | $errors = []; 339 | 340 | $min = 3; 341 | $max = 20; 342 | 343 | if($_SERVER['REQUEST_METHOD'] == "POST"){ 344 | 345 | 346 | 347 | 348 | $email = clean($_POST['email']); 349 | $password = clean($_POST['password']); 350 | $remember = isset($_POST['remember']); 351 | 352 | 353 | if(empty($email)) { 354 | 355 | $errors[] = "Email Field cannot be empty"; 356 | 357 | } 358 | 359 | if(empty($password)) { 360 | 361 | $errors[] = "Password Field cannot be empty"; 362 | 363 | } 364 | 365 | 366 | 367 | if(!empty($errors)) { 368 | 369 | foreach ($errors as $error) { 370 | 371 | 372 | echo validation_errors($error); 373 | } 374 | } else { 375 | 376 | 377 | if(login_user($email, $password, $remember)){ 378 | 379 | redirect("admin.php"); 380 | } else { 381 | 382 | echo validation_errors("Your Credenials are not correct"); 383 | 384 | } 385 | 386 | 387 | } 388 | 389 | 390 | } 391 | 392 | 393 | 394 | }//function 395 | 396 | 397 | 398 | /********User Login Functions*************/ 399 | 400 | 401 | function login_user($email, $password, $remember) { 402 | 403 | 404 | $sql = "SELECT password, id FROM users WHERE email = '".escape($email)."' AND active =1"; 405 | 406 | $result =query($sql); 407 | 408 | if(row_count($result) ==1){ 409 | 410 | $row = fetch_array($result); 411 | 412 | $db_password = $row['password']; 413 | 414 | if(md5($password) == $db_password){ 415 | 416 | 417 | if($remember == "on") { 418 | 419 | setcookie('email', $email, time() + 86400); 420 | } 421 | 422 | 423 | 424 | 425 | 426 | $_SESSION['email'] = $email; 427 | 428 | return true; 429 | 430 | } else { 431 | 432 | return false; 433 | } 434 | 435 | 436 | 437 | 438 | return true; 439 | } else { 440 | 441 | return false; 442 | 443 | } 444 | 445 | 446 | 447 | } ////end of function. 448 | 449 | 450 | /**********Logged in Function*******/ 451 | 452 | function logged_in(){ 453 | 454 | 455 | if(isset($_SESSION['email']) || isset($_COOKIE['email'])){ 456 | 457 | return true; 458 | 459 | }else{ 460 | 461 | return false; 462 | } 463 | 464 | 465 | } //funcion 466 | 467 | 468 | /******* recover function ******/ 469 | 470 | function recover_password() { 471 | 472 | if($_SERVER['REQUEST_METHOD'] == "POST") { 473 | 474 | if(isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token']) { 475 | 476 | 477 | $email = clean($_POST['email']); 478 | 479 | 480 | if(email_exists($email)){ 481 | 482 | $validation_code = md5($email . microtime()); 483 | 484 | setcookie('temp_access_code', $validation_code, time() + 900); 485 | 486 | 487 | $sql = "UPDATE users SET validation_code ='".escape($validation_code)."' WHERE email = '".escape($email)."'"; 488 | $result = query($sql); 489 | confirm($result); 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | $subject = "please reset your password"; 500 | $msg = "Here is the your password reset code {$validation_code} 501 | Click Here to reset your password http://localhost/udemy/code.php?email=$email&code=$validation_code"; 502 | 503 | $headers = "From: noreply@urwebsite.com"; 504 | 505 | 506 | if(!send_email($email, $subject, $msg, $headers)) { 507 | 508 | // sending email via localhost 509 | echo validation_errors("email could not be sent"); 510 | 511 | } 512 | 513 | set_message("

Please Check your Spam folder for a password reset

"); 514 | 515 | redirect("index.php"); 516 | 517 | 518 | 519 | }else { 520 | 521 | echo validation_errors("This email doesnot exists"); 522 | } 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | }else{ //token checking if fails 531 | 532 | redirect("index.php"); 533 | } 534 | 535 | 536 | if(isset($_POST['cancel_submit'])){ 537 | 538 | redirect("login.php"); 539 | 540 | } 541 | 542 | 543 | }// post request 544 | 545 | 546 | 547 | 548 | }//functions 549 | 550 | 551 | 552 | /****** Code Validation****//// 553 | 554 | function validate_code(){ 555 | 556 | if(isset($_COOKIE['temp_access_code'])) { 557 | 558 | 559 | if(!isset($_GET['email']) && !isset($_GET['code'])) { 560 | 561 | redirect("index.php"); 562 | 563 | } else if (empty($_GET['email']) || empty($_GET['code'])) { 564 | 565 | 566 | redirect("index.php"); 567 | 568 | 569 | }else { 570 | 571 | 572 | if(isset($_POST['code'])){ 573 | 574 | 575 | $email = clean($_GET['email']); 576 | 577 | $validation_code = clean($_POST['code']); 578 | 579 | $sql = "SELECT id FROM users WHERE validation_code ='".escape($validation_code)."' AND email ='".escape($email)."'"; 580 | $result = query($sql); 581 | confirm($result); 582 | 583 | if(row_count($result) == 1){ 584 | 585 | setcookie('temp_access_code', $validation_code, time() + 300); 586 | 587 | 588 | redirect("reset.php?email=$email&code=$validation_code"); 589 | 590 | }else { 591 | 592 | echo validation_errors("Sorry wrong validation code"); 593 | } 594 | 595 | 596 | 597 | 598 | 599 | 600 | } 601 | } 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | }else { 614 | 615 | set_message("

Sorry Your Validation cookie was expired

"); 616 | 617 | redirect("recover.php"); 618 | } 619 | 620 | 621 | } //function 622 | 623 | 624 | /***********Password Reset*********/ 625 | 626 | function password_reset() { 627 | 628 | 629 | 630 | if(isset($_COOKIE['temp_access_code'])) { 631 | 632 | 633 | if(isset($_GET['email']) && isset($_GET['code'])) { 634 | 635 | 636 | if(isset($_SESSION['token']) && isset($_POST['token'])) { 637 | 638 | 639 | if($_POST['token'] === $_SESSION['token']) { 640 | 641 | 642 | 643 | if($_POST['password'] === $_POST['confirm_password']){ 644 | 645 | 646 | $updated_password =md5($_POST['password']); 647 | 648 | 649 | 650 | $sql = "UPDATE users SET password ='".escape($updated_password)."', validation_code = 0 WHERE email = '".escape($_GET['email'])."' "; 651 | 652 | query($sql); 653 | 654 | 655 | set_message("

Your Password has been updated

"); 656 | 657 | redirect("login.php"); 658 | 659 | echo "Passwords Match"; 660 | }else { 661 | 662 | echo "Passwords donot Match"; 663 | } 664 | 665 | } 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | } 678 | 679 | 680 | } 681 | 682 | 683 | }else { 684 | 685 | 686 | 687 | set_message("

Sorry Your Time has expired

"); 688 | 689 | 690 | 691 | redirect("recover.php"); 692 | 693 | 694 | } 695 | 696 | 697 | 698 | } 699 | 700 | 701 | 702 | 703 | 704 | 705 | ?> 706 | -------------------------------------------------------------------------------- /functions/init.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /includes/footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /includes/header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
-------------------------------------------------------------------------------- /includes/nav.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 |

Home Page

12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /js/bootstrap.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.2 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | if (typeof jQuery === 'undefined') { 8 | throw new Error('Bootstrap\'s JavaScript requires jQuery') 9 | } 10 | 11 | +function ($) { 12 | 'use strict'; 13 | var version = $.fn.jquery.split(' ')[0].split('.') 14 | if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { 15 | throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') 16 | } 17 | }(jQuery); 18 | 19 | /* ======================================================================== 20 | * Bootstrap: transition.js v3.3.2 21 | * http://getbootstrap.com/javascript/#transitions 22 | * ======================================================================== 23 | * Copyright 2011-2015 Twitter, Inc. 24 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 25 | * ======================================================================== */ 26 | 27 | 28 | +function ($) { 29 | 'use strict'; 30 | 31 | // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 32 | // ============================================================ 33 | 34 | function transitionEnd() { 35 | var el = document.createElement('bootstrap') 36 | 37 | var transEndEventNames = { 38 | WebkitTransition : 'webkitTransitionEnd', 39 | MozTransition : 'transitionend', 40 | OTransition : 'oTransitionEnd otransitionend', 41 | transition : 'transitionend' 42 | } 43 | 44 | for (var name in transEndEventNames) { 45 | if (el.style[name] !== undefined) { 46 | return { end: transEndEventNames[name] } 47 | } 48 | } 49 | 50 | return false // explicit for ie8 ( ._.) 51 | } 52 | 53 | // http://blog.alexmaccaw.com/css-transitions 54 | $.fn.emulateTransitionEnd = function (duration) { 55 | var called = false 56 | var $el = this 57 | $(this).one('bsTransitionEnd', function () { called = true }) 58 | var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 59 | setTimeout(callback, duration) 60 | return this 61 | } 62 | 63 | $(function () { 64 | $.support.transition = transitionEnd() 65 | 66 | if (!$.support.transition) return 67 | 68 | $.event.special.bsTransitionEnd = { 69 | bindType: $.support.transition.end, 70 | delegateType: $.support.transition.end, 71 | handle: function (e) { 72 | if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 73 | } 74 | } 75 | }) 76 | 77 | }(jQuery); 78 | 79 | /* ======================================================================== 80 | * Bootstrap: alert.js v3.3.2 81 | * http://getbootstrap.com/javascript/#alerts 82 | * ======================================================================== 83 | * Copyright 2011-2015 Twitter, Inc. 84 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 85 | * ======================================================================== */ 86 | 87 | 88 | +function ($) { 89 | 'use strict'; 90 | 91 | // ALERT CLASS DEFINITION 92 | // ====================== 93 | 94 | var dismiss = '[data-dismiss="alert"]' 95 | var Alert = function (el) { 96 | $(el).on('click', dismiss, this.close) 97 | } 98 | 99 | Alert.VERSION = '3.3.2' 100 | 101 | Alert.TRANSITION_DURATION = 150 102 | 103 | Alert.prototype.close = function (e) { 104 | var $this = $(this) 105 | var selector = $this.attr('data-target') 106 | 107 | if (!selector) { 108 | selector = $this.attr('href') 109 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 110 | } 111 | 112 | var $parent = $(selector) 113 | 114 | if (e) e.preventDefault() 115 | 116 | if (!$parent.length) { 117 | $parent = $this.closest('.alert') 118 | } 119 | 120 | $parent.trigger(e = $.Event('close.bs.alert')) 121 | 122 | if (e.isDefaultPrevented()) return 123 | 124 | $parent.removeClass('in') 125 | 126 | function removeElement() { 127 | // detach from parent, fire event then clean up data 128 | $parent.detach().trigger('closed.bs.alert').remove() 129 | } 130 | 131 | $.support.transition && $parent.hasClass('fade') ? 132 | $parent 133 | .one('bsTransitionEnd', removeElement) 134 | .emulateTransitionEnd(Alert.TRANSITION_DURATION) : 135 | removeElement() 136 | } 137 | 138 | 139 | // ALERT PLUGIN DEFINITION 140 | // ======================= 141 | 142 | function Plugin(option) { 143 | return this.each(function () { 144 | var $this = $(this) 145 | var data = $this.data('bs.alert') 146 | 147 | if (!data) $this.data('bs.alert', (data = new Alert(this))) 148 | if (typeof option == 'string') data[option].call($this) 149 | }) 150 | } 151 | 152 | var old = $.fn.alert 153 | 154 | $.fn.alert = Plugin 155 | $.fn.alert.Constructor = Alert 156 | 157 | 158 | // ALERT NO CONFLICT 159 | // ================= 160 | 161 | $.fn.alert.noConflict = function () { 162 | $.fn.alert = old 163 | return this 164 | } 165 | 166 | 167 | // ALERT DATA-API 168 | // ============== 169 | 170 | $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 171 | 172 | }(jQuery); 173 | 174 | /* ======================================================================== 175 | * Bootstrap: button.js v3.3.2 176 | * http://getbootstrap.com/javascript/#buttons 177 | * ======================================================================== 178 | * Copyright 2011-2015 Twitter, Inc. 179 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 180 | * ======================================================================== */ 181 | 182 | 183 | +function ($) { 184 | 'use strict'; 185 | 186 | // BUTTON PUBLIC CLASS DEFINITION 187 | // ============================== 188 | 189 | var Button = function (element, options) { 190 | this.$element = $(element) 191 | this.options = $.extend({}, Button.DEFAULTS, options) 192 | this.isLoading = false 193 | } 194 | 195 | Button.VERSION = '3.3.2' 196 | 197 | Button.DEFAULTS = { 198 | loadingText: 'loading...' 199 | } 200 | 201 | Button.prototype.setState = function (state) { 202 | var d = 'disabled' 203 | var $el = this.$element 204 | var val = $el.is('input') ? 'val' : 'html' 205 | var data = $el.data() 206 | 207 | state = state + 'Text' 208 | 209 | if (data.resetText == null) $el.data('resetText', $el[val]()) 210 | 211 | // push to event loop to allow forms to submit 212 | setTimeout($.proxy(function () { 213 | $el[val](data[state] == null ? this.options[state] : data[state]) 214 | 215 | if (state == 'loadingText') { 216 | this.isLoading = true 217 | $el.addClass(d).attr(d, d) 218 | } else if (this.isLoading) { 219 | this.isLoading = false 220 | $el.removeClass(d).removeAttr(d) 221 | } 222 | }, this), 0) 223 | } 224 | 225 | Button.prototype.toggle = function () { 226 | var changed = true 227 | var $parent = this.$element.closest('[data-toggle="buttons"]') 228 | 229 | if ($parent.length) { 230 | var $input = this.$element.find('input') 231 | if ($input.prop('type') == 'radio') { 232 | if ($input.prop('checked') && this.$element.hasClass('active')) changed = false 233 | else $parent.find('.active').removeClass('active') 234 | } 235 | if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') 236 | } else { 237 | this.$element.attr('aria-pressed', !this.$element.hasClass('active')) 238 | } 239 | 240 | if (changed) this.$element.toggleClass('active') 241 | } 242 | 243 | 244 | // BUTTON PLUGIN DEFINITION 245 | // ======================== 246 | 247 | function Plugin(option) { 248 | return this.each(function () { 249 | var $this = $(this) 250 | var data = $this.data('bs.button') 251 | var options = typeof option == 'object' && option 252 | 253 | if (!data) $this.data('bs.button', (data = new Button(this, options))) 254 | 255 | if (option == 'toggle') data.toggle() 256 | else if (option) data.setState(option) 257 | }) 258 | } 259 | 260 | var old = $.fn.button 261 | 262 | $.fn.button = Plugin 263 | $.fn.button.Constructor = Button 264 | 265 | 266 | // BUTTON NO CONFLICT 267 | // ================== 268 | 269 | $.fn.button.noConflict = function () { 270 | $.fn.button = old 271 | return this 272 | } 273 | 274 | 275 | // BUTTON DATA-API 276 | // =============== 277 | 278 | $(document) 279 | .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 280 | var $btn = $(e.target) 281 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 282 | Plugin.call($btn, 'toggle') 283 | e.preventDefault() 284 | }) 285 | .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { 286 | $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) 287 | }) 288 | 289 | }(jQuery); 290 | 291 | /* ======================================================================== 292 | * Bootstrap: carousel.js v3.3.2 293 | * http://getbootstrap.com/javascript/#carousel 294 | * ======================================================================== 295 | * Copyright 2011-2015 Twitter, Inc. 296 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 297 | * ======================================================================== */ 298 | 299 | 300 | +function ($) { 301 | 'use strict'; 302 | 303 | // CAROUSEL CLASS DEFINITION 304 | // ========================= 305 | 306 | var Carousel = function (element, options) { 307 | this.$element = $(element) 308 | this.$indicators = this.$element.find('.carousel-indicators') 309 | this.options = options 310 | this.paused = 311 | this.sliding = 312 | this.interval = 313 | this.$active = 314 | this.$items = null 315 | 316 | this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) 317 | 318 | this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element 319 | .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) 320 | .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) 321 | } 322 | 323 | Carousel.VERSION = '3.3.2' 324 | 325 | Carousel.TRANSITION_DURATION = 600 326 | 327 | Carousel.DEFAULTS = { 328 | interval: 5000, 329 | pause: 'hover', 330 | wrap: true, 331 | keyboard: true 332 | } 333 | 334 | Carousel.prototype.keydown = function (e) { 335 | if (/input|textarea/i.test(e.target.tagName)) return 336 | switch (e.which) { 337 | case 37: this.prev(); break 338 | case 39: this.next(); break 339 | default: return 340 | } 341 | 342 | e.preventDefault() 343 | } 344 | 345 | Carousel.prototype.cycle = function (e) { 346 | e || (this.paused = false) 347 | 348 | this.interval && clearInterval(this.interval) 349 | 350 | this.options.interval 351 | && !this.paused 352 | && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 353 | 354 | return this 355 | } 356 | 357 | Carousel.prototype.getItemIndex = function (item) { 358 | this.$items = item.parent().children('.item') 359 | return this.$items.index(item || this.$active) 360 | } 361 | 362 | Carousel.prototype.getItemForDirection = function (direction, active) { 363 | var activeIndex = this.getItemIndex(active) 364 | var willWrap = (direction == 'prev' && activeIndex === 0) 365 | || (direction == 'next' && activeIndex == (this.$items.length - 1)) 366 | if (willWrap && !this.options.wrap) return active 367 | var delta = direction == 'prev' ? -1 : 1 368 | var itemIndex = (activeIndex + delta) % this.$items.length 369 | return this.$items.eq(itemIndex) 370 | } 371 | 372 | Carousel.prototype.to = function (pos) { 373 | var that = this 374 | var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) 375 | 376 | if (pos > (this.$items.length - 1) || pos < 0) return 377 | 378 | if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" 379 | if (activeIndex == pos) return this.pause().cycle() 380 | 381 | return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) 382 | } 383 | 384 | Carousel.prototype.pause = function (e) { 385 | e || (this.paused = true) 386 | 387 | if (this.$element.find('.next, .prev').length && $.support.transition) { 388 | this.$element.trigger($.support.transition.end) 389 | this.cycle(true) 390 | } 391 | 392 | this.interval = clearInterval(this.interval) 393 | 394 | return this 395 | } 396 | 397 | Carousel.prototype.next = function () { 398 | if (this.sliding) return 399 | return this.slide('next') 400 | } 401 | 402 | Carousel.prototype.prev = function () { 403 | if (this.sliding) return 404 | return this.slide('prev') 405 | } 406 | 407 | Carousel.prototype.slide = function (type, next) { 408 | var $active = this.$element.find('.item.active') 409 | var $next = next || this.getItemForDirection(type, $active) 410 | var isCycling = this.interval 411 | var direction = type == 'next' ? 'left' : 'right' 412 | var that = this 413 | 414 | if ($next.hasClass('active')) return (this.sliding = false) 415 | 416 | var relatedTarget = $next[0] 417 | var slideEvent = $.Event('slide.bs.carousel', { 418 | relatedTarget: relatedTarget, 419 | direction: direction 420 | }) 421 | this.$element.trigger(slideEvent) 422 | if (slideEvent.isDefaultPrevented()) return 423 | 424 | this.sliding = true 425 | 426 | isCycling && this.pause() 427 | 428 | if (this.$indicators.length) { 429 | this.$indicators.find('.active').removeClass('active') 430 | var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) 431 | $nextIndicator && $nextIndicator.addClass('active') 432 | } 433 | 434 | var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" 435 | if ($.support.transition && this.$element.hasClass('slide')) { 436 | $next.addClass(type) 437 | $next[0].offsetWidth // force reflow 438 | $active.addClass(direction) 439 | $next.addClass(direction) 440 | $active 441 | .one('bsTransitionEnd', function () { 442 | $next.removeClass([type, direction].join(' ')).addClass('active') 443 | $active.removeClass(['active', direction].join(' ')) 444 | that.sliding = false 445 | setTimeout(function () { 446 | that.$element.trigger(slidEvent) 447 | }, 0) 448 | }) 449 | .emulateTransitionEnd(Carousel.TRANSITION_DURATION) 450 | } else { 451 | $active.removeClass('active') 452 | $next.addClass('active') 453 | this.sliding = false 454 | this.$element.trigger(slidEvent) 455 | } 456 | 457 | isCycling && this.cycle() 458 | 459 | return this 460 | } 461 | 462 | 463 | // CAROUSEL PLUGIN DEFINITION 464 | // ========================== 465 | 466 | function Plugin(option) { 467 | return this.each(function () { 468 | var $this = $(this) 469 | var data = $this.data('bs.carousel') 470 | var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) 471 | var action = typeof option == 'string' ? option : options.slide 472 | 473 | if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) 474 | if (typeof option == 'number') data.to(option) 475 | else if (action) data[action]() 476 | else if (options.interval) data.pause().cycle() 477 | }) 478 | } 479 | 480 | var old = $.fn.carousel 481 | 482 | $.fn.carousel = Plugin 483 | $.fn.carousel.Constructor = Carousel 484 | 485 | 486 | // CAROUSEL NO CONFLICT 487 | // ==================== 488 | 489 | $.fn.carousel.noConflict = function () { 490 | $.fn.carousel = old 491 | return this 492 | } 493 | 494 | 495 | // CAROUSEL DATA-API 496 | // ================= 497 | 498 | var clickHandler = function (e) { 499 | var href 500 | var $this = $(this) 501 | var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 502 | if (!$target.hasClass('carousel')) return 503 | var options = $.extend({}, $target.data(), $this.data()) 504 | var slideIndex = $this.attr('data-slide-to') 505 | if (slideIndex) options.interval = false 506 | 507 | Plugin.call($target, options) 508 | 509 | if (slideIndex) { 510 | $target.data('bs.carousel').to(slideIndex) 511 | } 512 | 513 | e.preventDefault() 514 | } 515 | 516 | $(document) 517 | .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) 518 | .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) 519 | 520 | $(window).on('load', function () { 521 | $('[data-ride="carousel"]').each(function () { 522 | var $carousel = $(this) 523 | Plugin.call($carousel, $carousel.data()) 524 | }) 525 | }) 526 | 527 | }(jQuery); 528 | 529 | /* ======================================================================== 530 | * Bootstrap: collapse.js v3.3.2 531 | * http://getbootstrap.com/javascript/#collapse 532 | * ======================================================================== 533 | * Copyright 2011-2015 Twitter, Inc. 534 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 535 | * ======================================================================== */ 536 | 537 | 538 | +function ($) { 539 | 'use strict'; 540 | 541 | // COLLAPSE PUBLIC CLASS DEFINITION 542 | // ================================ 543 | 544 | var Collapse = function (element, options) { 545 | this.$element = $(element) 546 | this.options = $.extend({}, Collapse.DEFAULTS, options) 547 | this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') 548 | this.transitioning = null 549 | 550 | if (this.options.parent) { 551 | this.$parent = this.getParent() 552 | } else { 553 | this.addAriaAndCollapsedClass(this.$element, this.$trigger) 554 | } 555 | 556 | if (this.options.toggle) this.toggle() 557 | } 558 | 559 | Collapse.VERSION = '3.3.2' 560 | 561 | Collapse.TRANSITION_DURATION = 350 562 | 563 | Collapse.DEFAULTS = { 564 | toggle: true, 565 | trigger: '[data-toggle="collapse"]' 566 | } 567 | 568 | Collapse.prototype.dimension = function () { 569 | var hasWidth = this.$element.hasClass('width') 570 | return hasWidth ? 'width' : 'height' 571 | } 572 | 573 | Collapse.prototype.show = function () { 574 | if (this.transitioning || this.$element.hasClass('in')) return 575 | 576 | var activesData 577 | var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') 578 | 579 | if (actives && actives.length) { 580 | activesData = actives.data('bs.collapse') 581 | if (activesData && activesData.transitioning) return 582 | } 583 | 584 | var startEvent = $.Event('show.bs.collapse') 585 | this.$element.trigger(startEvent) 586 | if (startEvent.isDefaultPrevented()) return 587 | 588 | if (actives && actives.length) { 589 | Plugin.call(actives, 'hide') 590 | activesData || actives.data('bs.collapse', null) 591 | } 592 | 593 | var dimension = this.dimension() 594 | 595 | this.$element 596 | .removeClass('collapse') 597 | .addClass('collapsing')[dimension](0) 598 | .attr('aria-expanded', true) 599 | 600 | this.$trigger 601 | .removeClass('collapsed') 602 | .attr('aria-expanded', true) 603 | 604 | this.transitioning = 1 605 | 606 | var complete = function () { 607 | this.$element 608 | .removeClass('collapsing') 609 | .addClass('collapse in')[dimension]('') 610 | this.transitioning = 0 611 | this.$element 612 | .trigger('shown.bs.collapse') 613 | } 614 | 615 | if (!$.support.transition) return complete.call(this) 616 | 617 | var scrollSize = $.camelCase(['scroll', dimension].join('-')) 618 | 619 | this.$element 620 | .one('bsTransitionEnd', $.proxy(complete, this)) 621 | .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) 622 | } 623 | 624 | Collapse.prototype.hide = function () { 625 | if (this.transitioning || !this.$element.hasClass('in')) return 626 | 627 | var startEvent = $.Event('hide.bs.collapse') 628 | this.$element.trigger(startEvent) 629 | if (startEvent.isDefaultPrevented()) return 630 | 631 | var dimension = this.dimension() 632 | 633 | this.$element[dimension](this.$element[dimension]())[0].offsetHeight 634 | 635 | this.$element 636 | .addClass('collapsing') 637 | .removeClass('collapse in') 638 | .attr('aria-expanded', false) 639 | 640 | this.$trigger 641 | .addClass('collapsed') 642 | .attr('aria-expanded', false) 643 | 644 | this.transitioning = 1 645 | 646 | var complete = function () { 647 | this.transitioning = 0 648 | this.$element 649 | .removeClass('collapsing') 650 | .addClass('collapse') 651 | .trigger('hidden.bs.collapse') 652 | } 653 | 654 | if (!$.support.transition) return complete.call(this) 655 | 656 | this.$element 657 | [dimension](0) 658 | .one('bsTransitionEnd', $.proxy(complete, this)) 659 | .emulateTransitionEnd(Collapse.TRANSITION_DURATION) 660 | } 661 | 662 | Collapse.prototype.toggle = function () { 663 | this[this.$element.hasClass('in') ? 'hide' : 'show']() 664 | } 665 | 666 | Collapse.prototype.getParent = function () { 667 | return $(this.options.parent) 668 | .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') 669 | .each($.proxy(function (i, element) { 670 | var $element = $(element) 671 | this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) 672 | }, this)) 673 | .end() 674 | } 675 | 676 | Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { 677 | var isOpen = $element.hasClass('in') 678 | 679 | $element.attr('aria-expanded', isOpen) 680 | $trigger 681 | .toggleClass('collapsed', !isOpen) 682 | .attr('aria-expanded', isOpen) 683 | } 684 | 685 | function getTargetFromTrigger($trigger) { 686 | var href 687 | var target = $trigger.attr('data-target') 688 | || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 689 | 690 | return $(target) 691 | } 692 | 693 | 694 | // COLLAPSE PLUGIN DEFINITION 695 | // ========================== 696 | 697 | function Plugin(option) { 698 | return this.each(function () { 699 | var $this = $(this) 700 | var data = $this.data('bs.collapse') 701 | var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 702 | 703 | if (!data && options.toggle && option == 'show') options.toggle = false 704 | if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 705 | if (typeof option == 'string') data[option]() 706 | }) 707 | } 708 | 709 | var old = $.fn.collapse 710 | 711 | $.fn.collapse = Plugin 712 | $.fn.collapse.Constructor = Collapse 713 | 714 | 715 | // COLLAPSE NO CONFLICT 716 | // ==================== 717 | 718 | $.fn.collapse.noConflict = function () { 719 | $.fn.collapse = old 720 | return this 721 | } 722 | 723 | 724 | // COLLAPSE DATA-API 725 | // ================= 726 | 727 | $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 728 | var $this = $(this) 729 | 730 | if (!$this.attr('data-target')) e.preventDefault() 731 | 732 | var $target = getTargetFromTrigger($this) 733 | var data = $target.data('bs.collapse') 734 | var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) 735 | 736 | Plugin.call($target, option) 737 | }) 738 | 739 | }(jQuery); 740 | 741 | /* ======================================================================== 742 | * Bootstrap: dropdown.js v3.3.2 743 | * http://getbootstrap.com/javascript/#dropdowns 744 | * ======================================================================== 745 | * Copyright 2011-2015 Twitter, Inc. 746 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 747 | * ======================================================================== */ 748 | 749 | 750 | +function ($) { 751 | 'use strict'; 752 | 753 | // DROPDOWN CLASS DEFINITION 754 | // ========================= 755 | 756 | var backdrop = '.dropdown-backdrop' 757 | var toggle = '[data-toggle="dropdown"]' 758 | var Dropdown = function (element) { 759 | $(element).on('click.bs.dropdown', this.toggle) 760 | } 761 | 762 | Dropdown.VERSION = '3.3.2' 763 | 764 | Dropdown.prototype.toggle = function (e) { 765 | var $this = $(this) 766 | 767 | if ($this.is('.disabled, :disabled')) return 768 | 769 | var $parent = getParent($this) 770 | var isActive = $parent.hasClass('open') 771 | 772 | clearMenus() 773 | 774 | if (!isActive) { 775 | if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 776 | // if mobile we use a backdrop because click events don't delegate 777 | $('