Browse Source

sign in modal (but no tests for it yet)

Rafał Pitoń 9 years ago
parent
commit
867a036b88
45 changed files with 41725 additions and 282 deletions
  1. 2 1
      frontend/.babelrc
  2. 1 0
      frontend/.jshintrc
  3. 5 4
      frontend/gulpfile.js
  4. 5 0
      frontend/package.json
  5. 28 0
      frontend/src/components/avatar.js
  6. 49 0
      frontend/src/components/banned-page.js
  7. 7 4
      frontend/src/components/button.js
  8. 98 0
      frontend/src/components/form.js
  9. 2 4
      frontend/src/components/loader.js
  10. 2 2
      frontend/src/components/register/root.js
  11. 146 0
      frontend/src/components/sign-in.js
  12. 0 68
      frontend/src/components/sign-in/root.js
  13. 9 7
      frontend/src/components/snackbar.js
  14. 50 2
      frontend/src/components/user-menu/guest-nav.js
  15. 13 1
      frontend/src/components/user-menu/root.js
  16. 11 0
      frontend/src/initializers/ajax.js
  17. 15 0
      frontend/src/initializers/mobile-navbar-dropdown.js
  18. 11 0
      frontend/src/initializers/moment-locale.js
  19. 13 0
      frontend/src/initializers/tick-reducer.js
  20. 17 0
      frontend/src/initializers/tick-start.js
  21. 2 1
      frontend/src/initializers/user-menu-component.js
  22. 21 0
      frontend/src/reducers/tick.js
  23. 25 0
      frontend/src/services/mobile-navbar-dropdown.js
  24. 28 0
      frontend/src/services/snackbar.js
  25. 134 0
      frontend/src/test-setup.js
  26. 33 0
      frontend/src/utils/banned-page.js
  27. 100 0
      frontend/src/utils/validators.js
  28. 0 14
      frontend/src/vendor-tests.js
  29. 16 9
      frontend/style/misago/buttons.less
  30. 31 144
      frontend/style/misago/loaders.less
  31. 42 0
      frontend/tests/components/avatar.js
  32. 78 0
      frontend/tests/components/button.js
  33. 22 0
      frontend/tests/components/loader.js
  34. 1 6
      frontend/tests/components/snackbar.js
  35. 44 0
      frontend/tests/components/user-menu/guest-menu.js
  36. 105 0
      frontend/tests/modal.js
  37. 69 0
      frontend/tests/navbar-dropdown.js
  38. 96 0
      frontend/tests/validators.js
  39. 4612 1
      misago/static/misago/css/misago.css
  40. BIN
      misago/static/misago/img/site-icon.png
  41. BIN
      misago/static/misago/img/site-logo.png
  42. 2466 2
      misago/static/misago/js/misago.js
  43. 33312 10
      misago/static/misago/js/vendor.js
  44. 1 1
      misago/templates/misago/navbar.html
  45. 3 1
      misago/users/models/ban.py

+ 2 - 1
frontend/.babelrc

@@ -3,6 +3,7 @@
   "plugins": [
     ["babel-plugin-module-alias", [
       { "src": "./src", "expose": "misago" }
-    ]]
+    ]],
+    "transform-class-properties"
   ]
 }

+ 1 - 0
frontend/.jshintrc

@@ -2,6 +2,7 @@
   "undef": true,
   "unused": true,
   "esnext": true,
+  
   "predef": [
     "global",
     "console",

+ 5 - 4
frontend/gulpfile.js

@@ -51,8 +51,6 @@ function getSources() {
   };
 
   include('src/initializers/*.js');
-  include('src/components/*.js');
-  include('src/components/**/root.js');
 
   return sources.map(function(path) {
     return path;
@@ -70,6 +68,7 @@ gulp.task('fastsource', ['lintsource'], function() {
       entries: getSources(),
       debug: true
     })
+    .external('moment')
     .external('react')
     .external('react-dom')
     .external('redux')
@@ -88,6 +87,7 @@ gulp.task('source', ['lintsource'], function() {
       entries: getSources(),
       debug: false
     })
+    .external('moment')
     .external('react')
     .external('react-dom')
     .external('redux')
@@ -155,6 +155,7 @@ gulp.task('fastvendorsources', function() {
       debug: true
     })
     .transform('browserify-shim')
+    .require('moment')
     .require('react')
     .require('react-dom')
     .require('redux')
@@ -172,6 +173,7 @@ gulp.task('vendorsources', function() {
       entries: 'src/vendor.js',
       debug: false
     })
+    .require('moment')
     .require('react')
     .require('react-dom')
     .require('redux')
@@ -196,8 +198,7 @@ gulp.task('linttests', function() {
 
 gulp.task('test', ['linttests', 'lintsource'], function() {
   var mochify = require('mochify');
-  mochify('tests/**/*.js')
-    .add('src/vendor-tests.js')
+  mochify('src/test-setup.js tests/**/*.js')
     .transform(babelify)
     .bundle();
 });

+ 5 - 0
frontend/package.json

@@ -22,6 +22,7 @@
   "dependencies": {
     "babel": "^6.3.13",
     "babel-plugin-module-alias": "^1.0.0",
+    "babel-plugin-transform-class-properties": "^6.3.13",
     "babel-polyfill": "^6.3.14",
     "babel-preset-es2015": "^6.1.18",
     "babel-preset-react": "^6.1.18",
@@ -44,8 +45,12 @@
     "gulp-uglify": "^1.5.1",
     "jquery": "^2.1.4",
     "jquery-mockjax": "^2.0.1",
+    "moment": "^2.10.6",
     "react": "^0.14.3",
+    "react-addons-test-utils": "^0.14.5",
     "react-dom": "^0.14.3",
+    "react-redux": "^4.0.6",
+    "redux": "^3.0.5",
     "vinyl-buffer": "^1.0.0",
     "vinyl-source-stream": "^1.1.0"
   },

+ 28 - 0
frontend/src/components/avatar.js

@@ -0,0 +1,28 @@
+import React from 'react';
+
+const BASE_URL = $('base').attr('href') + 'user-avatar/';
+
+export default class extends React.Component {
+  getSrc() {
+    let size = this.props.size || 100; // jshint ignore:line
+    let url = BASE_URL;
+
+    if (this.props.user && this.props.user.id) {
+      // just avatar hash, size and user id
+      url += this.props.user.avatar_hash + '/' + size + '/' + this.props.user.id + '.png';
+    } else {
+      // just append avatar size to file to produce no-avatar placeholder
+      url += size + '.png';
+    }
+
+    return url;
+  }
+
+  render() {
+    /* jshint ignore:start */
+    return <img src={this.getSrc()}
+                className={this.props.className || 'user-avatar'}
+                title={gettext("User avatar")}/>;
+    /* jshint ignore:end */
+  }
+}

+ 49 - 0
frontend/src/components/banned-page.js

@@ -0,0 +1,49 @@
+import moment from 'moment';
+import React from 'react';
+
+export default class extends React.Component {
+  getReasonMessage() {
+    /* jshint ignore:start */
+    if (this.props.message.html) {
+      return <div className="lead"
+                  dangerouslySetInnerHTML={{__html: this.props.message.html}} />;
+    } else {
+      return <p className="lead">{this.props.message.plain}</p>;
+    }
+    /* jshint ignore:end */
+  }
+
+  getExpirationMessage() {
+    if (this.props.expires) {
+      if (this.props.expires.isAfter(moment())) {
+        return interpolate(
+          gettext('This ban expires %(expires_on)s.'),
+          {'expires_on': this.props.expires.fromNow()},
+          true);
+      } else {
+        return gettext('This ban has expired.');
+      }
+    } else {
+      return gettext('This ban is permanent.');
+    }
+  }
+
+  render() {
+    /* jshint ignore:start */
+    return <div className="page page-error page-error-baned">
+      <div className="container">
+        <div className="message-panel">
+
+          <div className="message-icon">
+            <span className="material-icon">highlight_off</span>
+          </div>
+          <div className="message-body">
+            {this.getReasonMessage()}
+            <p>{this.getExpirationMessage()}</p>
+          </div>
+        </div>
+      </div>
+    </div>;
+    /* jshint ignore:end */
+  }
+}

+ 7 - 4
frontend/src/components/button.js

@@ -4,20 +4,23 @@ import Loader from 'misago/components/loader'; // jshint ignore:line
 export default class Button extends React.Component {
   render() {
     let content = null;
+    let className = 'btn ' + this.props.className;
+    let disabled = this.props.disabled;
+
     if (this.props.loading) {
       /* jshint ignore:start */
       content = <Loader />;
       /* jshint ignore:end */
+      className += ' btn-loading';
+      disabled = true;
     } else {
       content = this.props.children;
     }
 
     /* jshint ignore:start */
-    let className = 'btn ' + this.props.className;
-
-    return <button type={this.props.type}
+    return <button type={this.props.onClick ? 'button' : 'submit'}
                    className={className}
-                   disabled={this.props.disabled}
+                   disabled={disabled}
                    onClick={this.props.onClick}>
       {content}
     </button>;

+ 98 - 0
frontend/src/components/form.js

@@ -0,0 +1,98 @@
+import React from 'react';
+import { required } from 'misago/utils/validators';
+
+export default class extends React.Component {
+  validate() {
+    let isValid = true;
+    let errors = {};
+
+    for (var key in this.state.validators) {
+      if (this.state.validators.hasOwnProperty(key)) {
+        let value = this.state[key];
+        errors[key] = this.validateField(value, this.state.validators[key]);
+        if (errors[key] !== null) {
+          isValid = false;
+        }
+      }
+    }
+
+    return isValid ? null : errors;
+  }
+
+  validateField(value, validators) {
+    let result = required()(value);
+    let errors = [];
+
+    if (result) {
+      return [result];
+    } else {
+      for (let i in validators) {
+        result = validators[i](value);
+        if (result) {
+          errors.push(result);
+        }
+      }
+    }
+
+    return errors.length ? errors : null;
+  }
+
+  changeValue(name, value) {
+    let errors = null;
+    if (this.state.validators.name) {
+      errors = this.validateField(name, value);
+    }
+  }
+
+  /* jshint ignore:start */
+  bindInput = (name) => {
+    return (event) => {
+      let newState = {};
+      newState[name] = event.target.value;
+      this.setState(newState);
+    }
+  }
+
+  clean() {
+    return true;
+  }
+
+  send() {
+    return null;
+  }
+
+  handleSuccess(success) {
+    return;
+  }
+
+  handleError(rejection) {
+    return;
+  }
+
+  handleSubmit = (event) => {
+    // we don't reload page on submissions
+    event.preventDefault();
+
+    if (this.state.isLoading) {
+      return;
+    }
+
+    if (this.clean()) {
+      this.setState({'isLoading': true});
+      let promise = this.send();
+
+      if (promise) {
+        promise.then((success) => {
+          this.handleSuccess(success);
+          this.setState({'isLoading': false});
+        }, (rejection) => {
+          this.handleError(rejection);
+          this.setState({'isLoading': false});
+        });
+      } else {
+        this.setState({'isLoading': false});
+      }
+    }
+  }
+  /* jshint ignore:end */
+}

+ 2 - 4
frontend/src/components/loader.js

@@ -1,12 +1,10 @@
 import React from 'react';
 
-export default class Loader extends React.Component {
+export default class extends React.Component {
   render() {
     /* jshint ignore:start */
     return <div className="loader-compact">
-      <div className="bounce1"></div>
-      <div className="bounce2"></div>
-      <div className="bounce3"></div>
+      <div className="loader-spinning-wheel"></div>
     </div>;
     /* jshint ignore:end */
   }

+ 2 - 2
frontend/src/components/register/root.js

@@ -1,9 +1,9 @@
 import React from 'react';
 
-export default class RegisterModal extends React.Component {
+export default class extends React.Component {
   render() {
     /* jshint ignore:start */
-    return <div className="modal-dialog">
+    return <div className="modal-dialog modal-register">
       <div className="modal-content">
         <div className="modal-header">
           <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>

+ 146 - 0
frontend/src/components/sign-in.js

@@ -0,0 +1,146 @@
+import React from 'react'; // jshint ignore:line
+import misago from 'misago/index';
+import Button from 'misago/components/button'; // jshint ignore:line
+import Form from 'misago/components/form';
+import ajax from 'misago/services/ajax';
+import modal from 'misago/services/modal';
+import snackbar from 'misago/services/snackbar';
+import showBannedPage from 'misago/utils/banned-page';
+
+export default class extends Form {
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      'isLoading': false,
+      'showActivation': false,
+
+      'username': '',
+      'password': '',
+
+      validators: {
+        'username': [],
+        'password': []
+      }
+    };
+  }
+
+  clean() {
+    if (this.validate()) {
+      snackbar.error(gettext("Fill out both fields."));
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  send() {
+    return ajax.post(misago.get('AUTH_API'), {
+      'username': this.state.username,
+      'password': this.state.password
+    });
+  }
+
+  handleSuccess() {
+    modal.hide();
+
+    let form = $('#hidden-login-form');
+
+    form.append('<input type="text" name="username" />');
+    form.append('<input type="password" name="password" />');
+
+    // fill out form with user credentials and submit it, this will tell
+    // Misago to redirect user back to right page, and will trigger browser's
+    // key ring feature
+    form.find('input[type="hidden"]').val(ajax.getCsrfToken());
+    form.find('input[name="redirect_to"]').val(window.location.pathname);
+    form.find('input[name="username"]').val(this.state.username);
+    form.find('input[name="password"]').val(this.state.password);
+    form.submit();
+  }
+
+  handleError(rejection) {
+    if (rejection.status === 400) {
+      if (rejection.code === 'inactive_admin') {
+        snackbar.info(rejection.detail);
+      } else if (rejection.code === 'inactive_user') {
+        snackbar.info(rejection.detail);
+        this.setState({
+          'showActivation': true
+        });
+      } else if (rejection.code === 'banned') {
+        showBannedPage(rejection.detail);
+        modal.hide();
+      } else {
+        snackbar.error(rejection.detail);
+      }
+    } else {
+      snackbar.apiError(rejection);
+    }
+  }
+
+  getActivationButton() {
+    if (this.state.showActivation) {
+      /* jshint ignore:start */
+      return <a href={misago.get('REQUEST_ACTIVATION_URL')}
+                className="btn btn-success btn-block">
+         {gettext("Activate account")}
+      </a>;
+      /* jshint ignore:end */
+    } else {
+      return null;
+    }
+  }
+
+  render() {
+    /* jshint ignore:start */
+    return <div className="modal-dialog modal-sm modal-sign-in">
+      <div className="modal-content">
+        <div className="modal-header">
+          <button type="button" className="close" data-dismiss="modal"
+                  aria-label={gettext("Close")}>
+            <span aria-hidden="true">&times;</span>
+          </button>
+          <h4 className="modal-title">{gettext("Sign in")}</h4>
+        </div>
+        <form onSubmit={this.handleSubmit}>
+          <div className="modal-body">
+
+            <div className="form-group">
+              <div className="control-input">
+                <input id="id_username" className="form-control" type="text"
+                       disabled={this.state.isLoading}
+                       placeholder={gettext("Username or e-mail")}
+                       onChange={this.bindInput('username')}
+                       value={this.state.username} />
+              </div>
+            </div>
+
+            <div className="form-group">
+              <div className="control-input">
+                <input id="id_password" className="form-control" type="password"
+                       disabled={this.state.isLoading}
+                       placeholder={gettext("Password")}
+                       onChange={this.bindInput('password')}
+                       value={this.state.password} />
+              </div>
+            </div>
+
+          </div>
+          <div className="modal-footer">
+            {this.getActivationButton()}
+            <Button className="btn-primary btn-block"
+                    loading={this.state.isLoading}>
+              {gettext("Sign in")}
+            </Button>
+            <a href={misago.get('FORGOTTEN_PASSWORD_URL')}
+               className="btn btn-default btn-block">
+               {gettext("Forgot password?")}
+            </a>
+          </div>
+        </form>
+      </div>
+    </div>;
+    /* jshint ignore:end */
+  }
+}

+ 0 - 68
frontend/src/components/sign-in/root.js

@@ -1,68 +0,0 @@
-import React from 'react';
-import snackbar from 'misago/services/snackbar';
-
-export default class SignInModal extends React.Component {
-  info() {
-    snackbar.info('Lorem ipsum dolor met');
-  }
-
-  success() {
-    snackbar.success('Lorem ipsum dolor met');
-  }
-
-  warning() {
-    snackbar.warning('Lorem ipsum dolor met');
-  }
-
-  error() {
-    snackbar.error('Lorem ipsum dolor met');
-  }
-
-  render() {
-    /* jshint ignore:start */
-    return <div className="modal-dialog">
-      <div className="modal-content">
-        <div className="modal-header">
-          <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
-          <h4 className="modal-title">{gettext("Sign in")}</h4>
-        </div>
-        <div className="modal-body">
-          <p>This will be sign in form!</p>
-          <button type="button"
-                  className="btn btn-primary"
-                  onClick={this.info}>
-            Test info alert
-          </button>
-
-          <br />
-
-          <button type="button"
-                  className="btn btn-success"
-                  onClick={this.success}>
-            Test success alert
-          </button>
-
-          <br />
-
-          <button type="button"
-                  className="btn btn-warning"
-                  onClick={this.warning}>
-            Test warning alert
-          </button>
-
-          <br />
-
-          <button type="button"
-                  className="btn btn-danger"
-                  onClick={this.error}>
-            Test error alert
-          </button>
-        </div>
-        <div className="modal-footer">
-          <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
-        </div>
-      </div>
-    </div>;
-    /* jshint ignore:end */
-  }
-}

+ 9 - 7
frontend/src/components/snackbar.js

@@ -1,27 +1,29 @@
 import React from 'react';
 
+/* jshint ignore:start */
 const TYPES_CLASSES = {
   'info': 'alert-info',
   'success': 'alert-success',
   'warning': 'alert-warning',
   'error': 'alert-danger'
 };
+/* jshint ignore:end */
 
 export class Snackbar extends React.Component {
-  render() {
-    var typeClass = 'alert ' + TYPES_CLASSES[this.props.type]; // jshint ignore:line
-
-    var snackbarClass = 'alerts-snackbar';
-
+  getSnackbarClass() {
+    let snackbarClass = 'alerts-snackbar';
     if (this.props.isVisible) {
       snackbarClass += ' in';
     } else {
       snackbarClass += ' out';
     }
+    return snackbarClass;
+  }
 
+  render() {
     /* jshint ignore:start */
-    return <div className={snackbarClass}>
-      <p className={typeClass}>
+    return <div className={this.getSnackbarClass()}>
+      <p className={'alert ' + TYPES_CLASSES[this.props.type]}>
         {this.props.message}
       </p>
     </div>;

+ 50 - 2
frontend/src/components/user-menu/guest-nav.js

@@ -2,10 +2,12 @@ import React from 'react';
 import Button from 'misago/components/button'; // jshint ignore:line
 
 import modal from 'misago/services/modal';
-import SignInModal from 'misago/components/sign-in/root.js';
+import dropdown from 'misago/services/mobile-navbar-dropdown';
+import Avatar from 'misago/components/avatar'; // jshint ignore:line
+import SignInModal from 'misago/components/sign-in.js';
 import RegisterModal from 'misago/components/register/root.js';
 
-export default class GuestNav extends React.Component {
+export class GuestMenu extends React.Component {
   showSignInModal() {
     modal.show(SignInModal);
   }
@@ -16,6 +18,38 @@ export default class GuestNav extends React.Component {
 
   render() {
     /* jshint ignore:start */
+    return <ul className="dropdown-menu user-dropdown dropdown-menu-right"
+               role="menu">
+      <li className="guest-preview">
+        <h4>{gettext("You are browsing as guest.")}</h4>
+        <p>
+          {gettext('Sign in or register to start and participate in discussions.')}
+        </p>
+        <div className="row">
+
+          <div className="col-xs-6">
+            <button type="button" className="btn btn-default btn-block">
+              Thy Sign In
+            </button>
+
+          </div>
+          <div className="col-xs-6">
+
+            <button type="button" className="btn btn-primary btn-block">
+              Thy Registry
+            </button>
+
+          </div>
+        </div>
+      </li>
+    </ul>;
+    /* jshint ignore:end */
+  }
+}
+
+export class GuestNav extends GuestMenu {
+  render() {
+    /* jshint ignore:start */
     return <div className="nav nav-guest">
       <Button type="button"
               className="navbar-btn btn-default"
@@ -31,3 +65,17 @@ export default class GuestNav extends React.Component {
     /* jshint ignore:end */
   }
 }
+
+export class CompactGuestNav extends React.Component {
+  showGuestMenu() {
+    dropdown.show(GuestMenu);
+  }
+
+  render() {
+    /* jshint ignore:start */
+    return <button type="button" onClick={this.showGuestMenu}>
+      <Avatar size="64" />
+    </button>;
+    /* jshint ignore:end */
+  }
+}

+ 13 - 1
frontend/src/components/user-menu/root.js

@@ -1,5 +1,5 @@
 import React from 'react';
-import GuestNav from 'misago/components/user-menu/guest-nav'; // jshint ignore:line
+import { GuestNav, CompactGuestNav } from 'misago/components/user-menu/guest-nav'; // jshint ignore:line
 import UserNav from 'misago/components/user-menu/user-nav'; // jshint ignore:line
 
 export class UserMenu extends React.Component {
@@ -14,6 +14,18 @@ export class UserMenu extends React.Component {
   }
 }
 
+export class CompactUserMenu extends React.Component {
+  render() {
+    /* jshint ignore:start */
+    if (this.props.isAuthenticated) {
+      return <UserNav user={this.props.user} />;
+    } else {
+      return <CompactGuestNav />;
+    }
+    /* jshint ignore:end */
+  }
+}
+
 export function select(state) {
   return state.auth;
 }

+ 11 - 0
frontend/src/initializers/ajax.js

@@ -0,0 +1,11 @@
+import misago from 'misago/index';
+import ajax from 'misago/services/ajax';
+
+export default function initializer() {
+  ajax.init(misago.get('CSRF_COOKIE_NAME'));
+}
+
+misago.addInitializer({
+  name: 'ajax',
+  initializer: initializer
+});

+ 15 - 0
frontend/src/initializers/mobile-navbar-dropdown.js

@@ -0,0 +1,15 @@
+import misago from 'misago/index';
+import dropdown from 'misago/services/mobile-navbar-dropdown';
+
+export default function initializer() {
+  let element = document.getElementById('mobile-navbar-dropdown-mount');
+  if (element) {
+    dropdown.init(element);
+  }
+}
+
+misago.addInitializer({
+  name: 'dropdown',
+  initializer: initializer,
+  before: 'store'
+});

+ 11 - 0
frontend/src/initializers/moment-locale.js

@@ -0,0 +1,11 @@
+import moment from 'moment';
+import misago from 'misago/index';
+
+export default function initializer() {
+  moment.locale($('html').attr('lang'));
+}
+
+misago.addInitializer({
+  name: 'moment',
+  initializer: initializer
+});

+ 13 - 0
frontend/src/initializers/tick-reducer.js

@@ -0,0 +1,13 @@
+import misago from 'misago/index';
+import reducer, { initialState } from 'misago/reducers/tick';
+import store from 'misago/services/store';
+
+export default function initializer() {
+  store.addReducer('tick', reducer, initialState);
+}
+
+misago.addInitializer({
+  name: 'reducer:tick',
+  initializer: initializer,
+  before: 'store'
+});

+ 17 - 0
frontend/src/initializers/tick-start.js

@@ -0,0 +1,17 @@
+import misago from 'misago/index';
+import { doTick } from 'misago/reducers/tick';
+import store from 'misago/services/store';
+
+const TICK_PERIOD = 50 * 1000; //do the tick every 50s
+
+export default function initializer() {
+  window.setInterval(function() {
+    store.dispatch(doTick());
+  }, TICK_PERIOD);
+}
+
+misago.addInitializer({
+  name: 'tick-start',
+  initializer: initializer,
+  after: 'store'
+});

+ 2 - 1
frontend/src/initializers/user-menu-component.js

@@ -1,10 +1,11 @@
 import { connect } from 'react-redux';
 import misago from 'misago/index';
-import { UserMenu, select } from 'misago/components/user-menu/root';
+import { UserMenu, CompactUserMenu, select } from 'misago/components/user-menu/root';
 import mount from 'misago/utils/mount-component';
 
 export default function initializer() {
   mount(connect(select)(UserMenu), 'user-menu-mount');
+  mount(connect(select)(CompactUserMenu), 'user-menu-compact-mount');
 }
 
 misago.addInitializer({

+ 21 - 0
frontend/src/reducers/tick.js

@@ -0,0 +1,21 @@
+export var initialState = {
+  tick: 0
+};
+
+export const TICK = 'TICK';
+
+export function doTick() {
+  return {
+    type: TICK
+  };
+}
+
+export default function tick(state=initialState, action=null) {
+  if (action.type === TICK) {
+    return Object.assign({}, state, {
+        tick: state.tick + 1
+    });
+  } else {
+    return state;
+  }
+}

+ 25 - 0
frontend/src/services/mobile-navbar-dropdown.js

@@ -0,0 +1,25 @@
+import mount from 'misago/utils/mount-component';
+
+export class MobileNavbarDropdown {
+  init(element) {
+    this._element = element;
+    this._component = null;
+  }
+
+  show(component) {
+    if (this._component === component) {
+      this.hide();
+    } else {
+      this._component = component;
+      mount(component, this._element.id);
+      $(this._element).addClass('open');
+    }
+  }
+
+  hide() {
+    $(this._element).removeClass('open');
+    this._component = null;
+  }
+}
+
+export default new MobileNavbarDropdown();

+ 28 - 0
frontend/src/services/snackbar.js

@@ -28,6 +28,7 @@ export class Snackbar {
   }
 
   // shorthands for message types
+
   info(message) {
     this.alert(message, 'info');
   }
@@ -43,6 +44,33 @@ export class Snackbar {
   error(message) {
     this.alert(message, 'error');
   }
+
+  // shorthand for api errors
+  apiError(rejection) {
+    let message = gettext("Unknown error has occured.");
+
+    if (rejection.status === 0) {
+      message = gettext("Lost connection with application.");
+    }
+
+    if (rejection.status === 400 && rejection.detail) {
+      message = rejection.detail;
+    }
+
+    if (rejection.status === 403) {
+      message = rejection.detail;
+      if (message === "Permission denied") {
+        message = gettext(
+          "You don't have permission to perform this action.");
+      }
+    }
+
+    if (rejection.status === 404) {
+      message = gettext("Action link is invalid.");
+    }
+
+    this.error(message);
+  }
 }
 
 export default new Snackbar();

+ 134 - 0
frontend/src/test-setup.js

@@ -0,0 +1,134 @@
+var jQuery = require('jQuery'); // jshint ignore:line
+
+global.$ = jQuery;
+global.jQuery = jQuery;
+
+require('bootstrap-transition');
+require('bootstrap-affix');
+require('bootstrap-modal');
+require('bootstrap-dropdown');
+
+require('jquery-mockjax')(jQuery, window);
+$.mockjaxSettings.logging = false;
+
+require("babel-polyfill");
+
+// Mock base href element
+$('head').append('<base href="/test-runner/">');
+
+// Bootstrap's modal (we'll need it anyway for tests);
+$('body').append('<div class="modal fade" id="modal-mount" tabindex="-1" role="dialog" aria-labelledby="misago-modal-label"></div>');
+$('body').append('<div id="dropdown-mount"></div>');
+$('body').append('<div id="test-mount"></div>');
+
+// set global utility function for cleaning test containers
+var ReactDOM = require('react-dom');
+global.emptyTestContainers = function() {
+  ReactDOM.unmountComponentAtNode(document.getElementById('modal-mount'));
+  ReactDOM.unmountComponentAtNode(document.getElementById('dropdown-mount'));
+  ReactDOM.unmountComponentAtNode(document.getElementById('test-mount'));
+};
+
+// global utility function for store init
+global.initEmptyStore = function(store) {
+  store.constructor();
+  store.addReducer('test', function(state={}, action=null) { return {}; }, {}); // jshint ignore:line
+  store.init();
+};
+
+// global init function for modal and dropdown services
+global.initModal = function(modal) {
+  modal.init(document.getElementById('modal-mount'));
+};
+
+global.initDropdown = function(dropdown) {
+  dropdown.init(document.getElementById('dropdown-mount'));
+};
+
+// inlined gettext functions form Django
+// jshint ignore: start
+(function (globals) {
+
+  var django = globals.django || (globals.django = {});
+
+  django.pluralidx = function (count) { return (count == 1) ? 0 : 1; };
+
+  /* gettext identity library */
+
+  django.gettext = function (msgid) { return msgid; };
+  django.ngettext = function (singular, plural, count) { return (count == 1) ? singular : plural; };
+  django.gettext_noop = function (msgid) { return msgid; };
+  django.pgettext = function (context, msgid) { return msgid; };
+  django.npgettext = function (context, singular, plural, count) { return (count == 1) ? singular : plural; };
+
+
+  django.interpolate = function (fmt, obj, named) {
+    if (named) {
+      return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])});
+    } else {
+      return fmt.replace(/%s/g, function(match){return String(obj.shift())});
+    }
+  };
+
+
+  /* formatting library */
+
+  django.formats = {
+    "DATETIME_FORMAT": "N j, Y, P",
+    "DATETIME_INPUT_FORMATS": [
+      "%Y-%m-%d %H:%M:%S",
+      "%Y-%m-%d %H:%M:%S.%f",
+      "%Y-%m-%d %H:%M",
+      "%Y-%m-%d",
+      "%m/%d/%Y %H:%M:%S",
+      "%m/%d/%Y %H:%M:%S.%f",
+      "%m/%d/%Y %H:%M",
+      "%m/%d/%Y",
+      "%m/%d/%y %H:%M:%S",
+      "%m/%d/%y %H:%M:%S.%f",
+      "%m/%d/%y %H:%M",
+      "%m/%d/%y"
+    ],
+    "DATE_FORMAT": "N j, Y",
+    "DATE_INPUT_FORMATS": [
+      "%Y-%m-%d",
+      "%m/%d/%Y",
+      "%m/%d/%y"
+    ],
+    "DECIMAL_SEPARATOR": ".",
+    "FIRST_DAY_OF_WEEK": "0",
+    "MONTH_DAY_FORMAT": "F j",
+    "NUMBER_GROUPING": "3",
+    "SHORT_DATETIME_FORMAT": "m/d/Y P",
+    "SHORT_DATE_FORMAT": "m/d/Y",
+    "THOUSAND_SEPARATOR": ",",
+    "TIME_FORMAT": "P",
+    "TIME_INPUT_FORMATS": [
+      "%H:%M:%S",
+      "%H:%M:%S.%f",
+      "%H:%M"
+    ],
+    "YEAR_MONTH_FORMAT": "F Y"
+  };
+
+  django.get_format = function (format_type) {
+    var value = django.formats[format_type];
+    if (typeof(value) == 'undefined') {
+      return format_type;
+    } else {
+      return value;
+    }
+  };
+
+  /* add to global namespace */
+  window.pluralidx = django.pluralidx;
+  window.gettext = django.gettext;
+  window.ngettext = django.ngettext;
+  window.gettext_noop = django.gettext_noop;
+  window.pgettext = django.pgettext;
+  window.npgettext = django.npgettext;
+  window.interpolate = django.interpolate;
+  window.get_format = django.get_format;
+
+}(global));
+// jshint ignore: end

+ 33 - 0
frontend/src/utils/banned-page.js

@@ -0,0 +1,33 @@
+import moment from 'moment'; // jshint ignore:line
+import React from 'react'; // jshint ignore:line
+import ReactDOM from 'react-dom';
+import { Provider, connect } from 'react-redux'; // jshint ignore:line
+import BannedPage from 'misago/components/banned-page'; // jshint ignore:line
+import misago from 'misago/index';
+import store from 'misago/services/store'; // jshint ignore:line
+
+/* jshint ignore:start */
+let select = function(state) {
+  return state.tick;
+};
+
+let RedrawedBannedPage = connect(select)(BannedPage);
+/* jshint ignore:end */
+
+export default function(ban, changeState) {
+  ReactDOM.render(
+    /* jshint ignore:start */
+    <Provider store={store.getStore()}>
+      <RedrawedBannedPage message={ban.message}
+                          expires={ban.expires_on ? moment(ban.expires_on) : null} />
+    </Provider>,
+    /* jshint ignore:end */
+    document.getElementById('page-mount')
+  );
+
+  if (typeof changeState === 'undefined' || !changeState) {
+    let forumName = misago.get('SETTINGS').forum_name;
+    document.title = gettext("You are banned") + ' | ' + forumName;
+    window.history.pushState({}, "", misago.get('BANNED_URL'));
+  }
+}

+ 100 - 0
frontend/src/utils/validators.js

@@ -0,0 +1,100 @@
+const EMAIL = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+const USERNAME = new RegExp('^[0-9a-z]+$', 'i');
+
+export function required() {
+  return function(value) {
+    if ($.trim(value).length === 0) {
+      return gettext("This field is required.");
+    }
+  };
+}
+
+export function email(message) {
+  return function(value) {
+    if (!EMAIL.test(value)) {
+      return message || gettext("Enter a valid email address.");
+    }
+  };
+}
+
+export function minLength(limitValue, message) {
+  return function(value) {
+    var returnMessage = '';
+    var length = $.trim(value).length;
+
+    if (length < limitValue) {
+      if (message) {
+        returnMessage = message(limitValue, length);
+      } else {
+        returnMessage = ngettext(
+          "Ensure this value has at least %(limit_value)s character (it has %(show_value)s).",
+          "Ensure this value has at least %(limit_value)s characters (it has %(show_value)s).",
+          limitValue);
+      }
+      return interpolate(returnMessage, {
+        limit_value: limitValue,
+        show_value: length
+      }, true);
+    }
+  };
+}
+
+export function maxLength(limitValue, message) {
+  return function(value) {
+    var returnMessage = '';
+    var length = $.trim(value).length;
+
+    if (length > limitValue) {
+      if (message) {
+        returnMessage = message(limitValue, length);
+      } else {
+        returnMessage = ngettext(
+          "Ensure this value has at most %(limit_value)s character (it has %(show_value)s).",
+          "Ensure this value has at most %(limit_value)s characters (it has %(show_value)s).",
+          limitValue);
+      }
+      return interpolate(returnMessage, {
+        limit_value: limitValue,
+        show_value: length
+      }, true);
+    }
+  };
+}
+
+export function usernameMinLength(settings) {
+  var message = function(limitValue) {
+    return ngettext(
+      "Username must be at least %(limit_value)s character long.",
+      "Username must be at least %(limit_value)s characters long.",
+      limitValue);
+  };
+  return this.minLength(settings.username_length_min, message);
+}
+
+export function usernameMaxLength(settings) {
+  var message = function(limitValue) {
+    return ngettext(
+      "Username cannot be longer than %(limit_value)s character.",
+      "Username cannot be longer than %(limit_value)s characters.",
+      limitValue);
+  };
+  return this.maxLength(settings.username_length_max, message);
+}
+
+export function usernameContent() {
+  return function(value) {
+    if (!USERNAME.test($.trim(value))) {
+      return gettext("Username can only contain latin alphabet letters and digits.");
+    }
+  };
+}
+
+export function passwordMinLength(settings) {
+  var message = function(limitValue) {
+    return ngettext(
+      "Valid password must be at least %(limit_value)s character long.",
+      "Valid password must be at least %(limit_value)s characters long.",
+      limitValue);
+  };
+  return this.minLength(settings.password_length_min, message);
+}

+ 0 - 14
frontend/src/vendor-tests.js

@@ -1,14 +0,0 @@
-var jQuery = require('jQuery'); // jshint ignore:line
-
-global.$ = jQuery;
-global.jQuery = jQuery;
-
-require('bootstrap-transition');
-require('bootstrap-affix');
-require('bootstrap-modal');
-require('bootstrap-dropdown');
-
-require('jquery-mockjax')(jQuery, window);
-$.mockjaxSettings.logging = false;
-
-require("babel-polyfill");

+ 16 - 9
frontend/style/misago/buttons.less

@@ -11,35 +11,42 @@
 
     // position loader over the text
     .loader-compact {
-      margin-top: @line-height-computed * -1;
       height: 20px;
 
-      position: relative;
-      top: 0px;
+      & > div {
+        width: 20px;
+        height: 20px;
+      }
     }
   }
 
   &.btn-default .loader-compact > div {
-    background-color: @btn-default-color;
+    border-top-color: @btn-default-color;
+    border-bottom-color: @btn-default-color;
   }
 
   &.btn-primary .loader-compact > div {
-    background-color: @btn-primary-color;
+    border-top-color: @btn-primary-color;
+    border-bottom-color: @btn-primary-color;
   }
 
   &.btn-success .loader-compact > div {
-    background-color: @btn-success-color;
+    border-top-color: @btn-success-color;
+    border-bottom-color: @btn-success-color;
   }
 
   &.btn-info .loader-compact > div {
-    background-color: @btn-info-color;
+    border-top-color: @btn-info-color;
+    border-bottom-color: @btn-info-color;
   }
 
   &.btn-warning .loader-compact > div {
-    background-color: @btn-warning-color;
+    border-top-color: @btn-warning-color;
+    border-bottom-color: @btn-warning-color;
   }
 
   &.btn-danger .loader-compact > div {
-    background-color: @btn-danger-color;
+    border-top-color: @btn-danger-color;
+    border-bottom-color: @btn-danger-color;
   }
 }

+ 31 - 144
frontend/style/misago/loaders.less

@@ -3,156 +3,43 @@
 // --------------------------------------------------
 
 
-.loader {
-  &.sk-folding-cube {
-    margin: @loader-vertical-margin auto;
-    width: @loader-size;
-    height: @loader-size;
-    position: relative;
-    -webkit-transform: rotateZ(45deg);
-            transform: rotateZ(45deg);
-  }
-
-  &.sk-folding-cube .sk-cube {
-    float: left;
-    width: 50%;
-    height: 50%;
-    position: relative;
-    -webkit-transform: scale(1.1);
-        -ms-transform: scale(1.1);
-            transform: scale(1.1);
-  }
-
-  &.sk-folding-cube .sk-cube:before {
-    content: '';
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    background-color: @loader-color;
-    -webkit-animation: sk-foldCubeAngle 2.4s infinite linear both;
-            animation: sk-foldCubeAngle 2.4s infinite linear both;
-    -webkit-transform-origin: 100% 100%;
-        -ms-transform-origin: 100% 100%;
-            transform-origin: 100% 100%;
-  }
-
-  &.sk-folding-cube .sk-cube2 {
-    -webkit-transform: scale(1.1) rotateZ(90deg);
-            transform: scale(1.1) rotateZ(90deg);
-  }
-
-  &.sk-folding-cube .sk-cube3 {
-    -webkit-transform: scale(1.1) rotateZ(180deg);
-            transform: scale(1.1) rotateZ(180deg);
-  }
-
-  &.sk-folding-cube .sk-cube4 {
-    -webkit-transform: scale(1.1) rotateZ(270deg);
-            transform: scale(1.1) rotateZ(270deg);
-  }
-
-  &.sk-folding-cube .sk-cube2:before {
-    -webkit-animation-delay: 0.3s;
-            animation-delay: 0.3s;
-  }
-
-  &.sk-folding-cube .sk-cube3:before {
-    -webkit-animation-delay: 0.6s;
-            animation-delay: 0.6s;
-  }
-
-  &.sk-folding-cube .sk-cube4:before {
-    -webkit-animation-delay: 0.9s;
-            animation-delay: 0.9s;
-  }
-
-  @-webkit-keyframes sk-foldCubeAngle {
-    0%, 10% {
-      -webkit-transform: perspective(140px) rotateX(-180deg);
-              transform: perspective(140px) rotateX(-180deg);
-      opacity: 0;
-    } 25%, 75% {
-      -webkit-transform: perspective(140px) rotateX(0deg);
-              transform: perspective(140px) rotateX(0deg);
-      opacity: 1;
-    } 90%, 100% {
-      -webkit-transform: perspective(140px) rotateY(180deg);
-              transform: perspective(140px) rotateY(180deg);
-      opacity: 0;
-    }
-  }
-
-  @keyframes sk-foldCubeAngle {
-    0%, 10% {
-      -webkit-transform: perspective(140px) rotateX(-180deg);
-              transform: perspective(140px) rotateX(-180deg);
-      opacity: 0;
-    } 25%, 75% {
-      -webkit-transform: perspective(140px) rotateX(0deg);
-              transform: perspective(140px) rotateX(0deg);
-      opacity: 1;
-    } 90%, 100% {
-      -webkit-transform: perspective(140px) rotateY(180deg);
-              transform: perspective(140px) rotateY(180deg);
-      opacity: 0;
-    }
-  }
-}
-
-
 .loader-compact {
-  margin: 0px auto;
-  width: 50px;
+  width: 100%;
+  height: 49px;
   text-align: center;
+}
 
-  &>div {
-    width: @loader-compact-height;
-    height: @loader-compact-height;
-    background-color: #333;
-
-    border-radius: 100%;
-    display: inline-block;
-    -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
-    animation: sk-bouncedelay 1.4s infinite ease-in-out both;
-  }
-
-  .bounce1 {
-    -webkit-animation-delay: -0.32s;
-    animation-delay: -0.32s;
-  }
-
-  .bounce2 {
-    margin: 0px 4px;
-    -webkit-animation-delay: -0.16s;
-    animation-delay: -0.16s;
-  }
-
-  @-webkit-keyframes sk-bouncedelay {
-    0%, 80%, 100% { -webkit-transform: scale(0.5) }
-    40% { -webkit-transform: scale(1.0) }
-  }
+.loader-spinning-wheel {
+  width: 49px;
+  height: 49px;
+  margin: 0 auto;
+  border: 3px solid rgb(0,0,0);
+  border-radius: 50%;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  animation: cssload-spin 575ms infinite linear;
+    -o-animation: cssload-spin 575ms infinite linear;
+    -ms-animation: cssload-spin 575ms infinite linear;
+    -webkit-animation: cssload-spin 575ms infinite linear;
+    -moz-animation: cssload-spin 575ms infinite linear;
+}
 
-  @keyframes sk-bouncedelay {
-    0%, 80%, 100% {
-      -webkit-transform: scale(0.5);
-      transform: scale(0.5);
-    } 40% {
-      -webkit-transform: scale(1.0);
-      transform: scale(1.0);
-    }
-  }
+@keyframes cssload-spin {
+  100%{ transform: rotate(360deg); transform: rotate(360deg); }
 }
 
+@-o-keyframes cssload-spin {
+  100%{ -o-transform: rotate(360deg); transform: rotate(360deg); }
+}
 
-// Loading page extra styles
-.page-loading {
-  .lead {
-    margin-top: @loader-vertical-margin * -0.5;
-    margin-bottom: @loader-vertical-margin;
+@-ms-keyframes cssload-spin {
+  100%{ -ms-transform: rotate(360deg); transform: rotate(360deg); }
+}
 
-    color: @loader-text;
-    text-align: center;
-  }
+@-webkit-keyframes cssload-spin {
+  100%{ -webkit-transform: rotate(360deg); transform: rotate(360deg); }
 }
+
+@-moz-keyframes cssload-spin {
+  100%{ -moz-transform: rotate(360deg); transform: rotate(360deg); }
+}

+ 42 - 0
frontend/tests/components/avatar.js

@@ -0,0 +1,42 @@
+import assert from 'assert';
+import React from 'react'; // jshint ignore:line
+import ReactDOM from 'react-dom'; // jshint ignore:line
+import Avatar from 'misago/components/avatar'; // jshint ignore:line
+
+describe("Avatar", function() {
+  afterEach(function() {
+    window.emptyTestContainers();
+  });
+
+  it('renders guest avatar', function() {
+    /* jshint ignore:start */
+    ReactDOM.render(
+      <Avatar size="42" />,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    let element = $('#test-mount img.user-avatar');
+    assert.ok(element.length, "component renders for guest");
+    assert.equal(element.attr('src'), '/test-runner/user-avatar/42.png', "component builds valid avatar url");
+  });
+
+  it('renders user avatar', function() {
+    /* jshint ignore:start */
+    let user = {
+      id: 1234,
+      avatar_hash: 'aabbccddeeff'
+    };
+
+    ReactDOM.render(
+      <Avatar user={user} size="42" />,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    let element = $('#test-mount img.user-avatar');
+    assert.ok(element.length, "component renders for user");
+    assert.equal(element.attr('src'), '/test-runner/user-avatar/aabbccddeeff/42/1234.png',
+      "component builds valid avatar url for authenticated");
+  });
+});

+ 78 - 0
frontend/tests/components/button.js

@@ -0,0 +1,78 @@
+import assert from 'assert';
+import React from 'react'; // jshint ignore:line
+import ReactDOM from 'react-dom'; // jshint ignore:line
+import ReactTestUtils from 'react-addons-test-utils';
+import Button from 'misago/components/button'; // jshint ignore:line
+
+describe("Button", function() {
+  afterEach(function() {
+    window.emptyTestContainers();
+  });
+
+  it('renders', function() {
+    /* jshint ignore:start */
+    ReactDOM.render(
+      <Button>
+        Lorem ipsum
+      </Button>,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    let element = $('#test-mount button');
+    assert.ok(element.length, "component rendered");
+    assert.equal(element.attr('type'), 'submit', "component is submit button");
+    assert.equal(element.text().trim(), "Lorem ipsum", "component contains child");
+  });
+
+  it('handles clicks', function(done) { // jshint ignore:line
+    /* jshint ignore:start */
+    function click() {
+      assert.ok(true, "component called callback on click");
+      done();
+    }
+
+    ReactDOM.render(
+      <Button onClick={click}>
+        Lorem ipsum
+      </Button>,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    let element = $('#test-mount button');
+    assert.ok(element.length, "component rendered");
+    assert.equal(element.attr('type'), 'button', "component is regular button");
+    ReactTestUtils.Simulate.click(element.get(0));
+  });
+
+  it('renders disabled', function() {
+    /* jshint ignore:start */
+    ReactDOM.render(
+      <Button disabled={true}>
+        Lorem ipsum
+      </Button>,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    let element = $('#test-mount button');
+    assert.ok(element.length, "component rendered");
+    assert.equal(element.attr('disabled'), 'disabled', "component is disabled");
+  });
+
+  it('renders loading', function() {
+    /* jshint ignore:start */
+    ReactDOM.render(
+      <Button loading={true}>
+        Lorem ipsum
+      </Button>,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    let element = $('#test-mount button>.loader-compact');
+    assert.ok(element.length, "component rendered with loader");
+    assert.equal(element.parent().attr('disabled'), 'disabled', "component is disabled");
+  });
+});

+ 22 - 0
frontend/tests/components/loader.js

@@ -0,0 +1,22 @@
+import assert from 'assert';
+import React from 'react'; // jshint ignore:line
+import ReactDOM from 'react-dom'; // jshint ignore:line
+import Loader from 'misago/components/loader'; // jshint ignore:line
+
+describe("Snackbar", function() {
+  afterEach(function() {
+    window.emptyTestContainers();
+  });
+
+  it('renders', function() {
+    /* jshint ignore:start */
+    ReactDOM.render(
+      <Loader />,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    assert.ok($('#test-mount .loader-compact .loader-spinning-wheel').length,
+      "component renders");
+  });
+});

+ 1 - 6
frontend/tests/components/snackbar.js

@@ -4,13 +4,8 @@ import ReactDOM from 'react-dom'; // jshint ignore:line
 import { Snackbar } from 'misago/components/snackbar'; // jshint ignore:line
 
 describe("Snackbar", function() {
-  beforeEach(function() {
-    $('body').append('<div id="test-mount"></div>');
-  });
-
   afterEach(function() {
-    ReactDOM.unmountComponentAtNode(document.getElementById('test-mount'));
-    $('#test-mount').remove();
+    window.emptyTestContainers();
   });
 
   it('renders', function() {

+ 44 - 0
frontend/tests/components/user-menu/guest-menu.js

@@ -0,0 +1,44 @@
+import assert from 'assert';
+import React from 'react'; // jshint ignore:line
+import ReactDOM from 'react-dom'; // jshint ignore:line
+import ReactTestUtils from 'react-addons-test-utils';
+import { CompactGuestNav } from 'misago/components/user-menu/guest-nav'; // jshint ignore:line
+import dropdown from 'misago/services/mobile-navbar-dropdown';
+import store from 'misago/services/store';
+
+describe("CompactGuestNav", function() {
+  beforeEach(function() {
+    window.initEmptyStore(store);
+    window.initDropdown(dropdown);
+  });
+
+  afterEach(function() {
+    window.emptyTestContainers();
+  });
+
+  it('renders', function() {
+    /* jshint ignore:start */
+    ReactDOM.render(
+      <CompactGuestNav />,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    let element = $('#test-mount img.user-avatar');
+    assert.ok(element.length, "component renders");
+  });
+
+  it('opens dropdown on click', function() {
+    /* jshint ignore:start */
+    ReactDOM.render(
+      <CompactGuestNav />,
+      document.getElementById('test-mount')
+    );
+    /* jshint ignore:end */
+
+    ReactTestUtils.Simulate.click($('#test-mount button').get(0));
+
+    let element = $('#dropdown-mount>.dropdown-menu');
+    assert.ok(element.length, "component opened dropdown");
+  });
+});

+ 105 - 0
frontend/tests/modal.js

@@ -0,0 +1,105 @@
+import assert from 'assert';
+import React from 'react'; // jshint ignore:line
+import ReactDOM from 'react-dom'; // jshint ignore:line
+import store from 'misago/services/store';
+import { Modal } from 'misago/services/modal';
+
+var modal = null;
+
+class TestModalA extends React.Component {
+  render() {
+    /* jshint ignore:start */
+    return <div className="modal-dialog modal-a">
+      <div className="modal-content">
+        <div className="modal-header">
+          <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+          <h4 className="modal-title">Modal A</h4>
+        </div>
+        <div className="modal-body">
+          <p>This is first test modal!</p>
+        </div>
+        <div className="modal-footer">
+          <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
+        </div>
+      </div>
+    </div>;
+    /* jshint ignore:end */
+  }
+}
+
+class TestModalB extends React.Component {
+  render() {
+    /* jshint ignore:start */
+    return <div className="modal-dialog modal-b">
+      <div className="modal-content">
+        <div className="modal-header">
+          <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+          <h4 className="modal-title">Modal B</h4>
+        </div>
+        <div className="modal-body">
+          <p>This is second test modal!</p>
+        </div>
+        <div className="modal-footer">
+          <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
+        </div>
+      </div>
+    </div>;
+    /* jshint ignore:end */
+  }
+}
+
+describe("Modal", function() {
+  beforeEach(function() {
+    modal = new Modal();
+    modal.init(document.getElementById('modal-mount'));
+
+    window.initEmptyStore(store);
+  });
+
+  afterEach(function() {
+    window.emptyTestContainers();
+  });
+
+  it('shows component', function(done) {
+    modal.show(TestModalA);
+
+    window.setTimeout(function() {
+      let element = $('#modal-mount .modal-a');
+      assert.ok(element.length, "component was rendered");
+      done();
+    }, 400);
+  });
+
+  it('shows and cycles component', function(done) {
+    modal.show(TestModalA);
+
+    window.setTimeout(function() {
+      let element = $('#modal-mount .modal-a');
+      assert.ok(element.length, "component was rendered");
+
+      modal.show(TestModalB);
+    }, 400);
+
+    window.setTimeout(function() {
+      let element = $('#modal-mount .modal-b');
+      assert.ok(element.length, "component was toggled");
+      done();
+    }, 500);
+  });
+
+  it('hides component', function(done) {
+    modal.show(TestModalA);
+
+    window.setTimeout(function() {
+      let element = $('#modal-mount .modal-a');
+      assert.ok(element.length, "component was rendered");
+      modal.hide();
+    }, 400);
+
+    window.setTimeout(function() {
+      let element = $('#modal-mount');
+      assert.equal(element.children().length, 0, "modal was emptied");
+      done();
+    }, 1000);
+  });
+});

+ 69 - 0
frontend/tests/navbar-dropdown.js

@@ -0,0 +1,69 @@
+import assert from 'assert';
+import React from 'react'; // jshint ignore:line
+import ReactDOM from 'react-dom'; // jshint ignore:line
+import store from 'misago/services/store';
+import { MobileNavbarDropdown } from 'misago/services/mobile-navbar-dropdown';
+
+var dropdown = null;
+
+class TestComponentA extends React.Component {
+  render() {
+    /* jshint ignore:start */
+    return <div className="dropdown-a">
+      <p>This is first test dropdown!</p>
+    </div>;
+    /* jshint ignore:end */
+  }
+}
+
+class TestComponentB extends React.Component {
+  render() {
+    /* jshint ignore:start */
+    return <div className="dropdown-b">
+      <p>This is second test dropdown!</p>
+    </div>;
+    /* jshint ignore:end */
+  }
+}
+
+describe("dropdown", function() {
+  beforeEach(function() {
+    dropdown = new MobileNavbarDropdown();
+    dropdown.init(document.getElementById('dropdown-mount'));
+
+    store.constructor();
+    store.addReducer('test', function(state={}, action=null) { return {}; }, {}); // jshint ignore:line
+    store.init();
+  });
+
+  afterEach(function() {
+    window.emptyTestContainers();
+  });
+
+  it('shows component', function(done) {
+    dropdown.show(TestComponentA);
+
+    window.setTimeout(function() {
+      let element = $('#dropdown-mount .dropdown-a');
+      assert.ok(element.length, "component was rendered");
+      done();
+    }, 100);
+  });
+
+  it('shows and cycles component', function(done) {
+    dropdown.show(TestComponentA);
+
+    window.setTimeout(function() {
+      let element = $('#dropdown-mount .dropdown-a');
+      assert.ok(element.length, "component was rendered");
+
+      dropdown.show(TestComponentB);
+    }, 100);
+
+    window.setTimeout(function() {
+      let element = $('#dropdown-mount .dropdown-b');
+      assert.ok(element.length, "component was toggled");
+      done();
+    }, 300);
+  });
+});

+ 96 - 0
frontend/tests/validators.js

@@ -0,0 +1,96 @@
+import assert from 'assert';
+import * as validators from 'misago/utils/validators';
+
+describe("Validator", function() {
+  it("required validator", function() {
+    assert.equal(validators.required()('yup'), undefined,
+      "non-empty string passed validation.");
+    assert.equal(
+      validators.required()(' '), gettext("This field is required."),
+      "empty string failed validation.");
+  });
+
+  it("email validator", function() {
+    assert.equal(validators.email()('simple@email.com'), undefined,
+      "simple e-mail passed validation.");
+    assert.equal(validators.email()('si.mp.le@ema.il.com'), undefined,
+      "dotted e-mail passed validation.");
+    assert.equal(validators.email()('si-mp-le@ema-il.com'), undefined,
+      "hyphenated e-mail passed validation.");
+    assert.equal(validators.email()('si_mp_le@ema_il.com'), undefined,
+      "underscored e-mail passed validation.");
+    assert.equal(validators.email()('si+mp+le@email.com'), undefined,
+      "plused e-mail passed validation.");
+    assert.equal(validators.email('Nope!')('hh'), 'Nope!',
+      "non-email errored with message providen.");
+  });
+
+  it("minLength validator", function() {
+    assert.equal(validators.minLength(5)('yusss'), undefined,
+      "string of required length passed validation.");
+    assert.equal(
+      validators.minLength(5)('nope'),
+      "Ensure this value has at least 5 characters (it has 4).",
+      "too short string failed validation.");
+  });
+
+  it("maxLength validator", function() {
+    assert.equal(validators.maxLength(5)('yusss'), undefined,
+      "string of required length passed validation.");
+    assert.equal(
+      validators.maxLength(5)('too long!'),
+      "Ensure this value has at most 5 characters (it has 9).",
+      "too long string failed validation.");
+  });
+
+  it("usernameMinLength validator", function() {
+    var settings = {
+      username_length_min: 4
+    };
+
+    assert.equal(
+      validators.usernameMinLength(settings)('yusss'), undefined,
+      "username of required length passed validation.");
+    assert.equal(
+      validators.usernameMinLength(settings)('no'),
+      "Username must be at least 4 characters long.",
+      "too short username failed validation.");
+  });
+
+  it("usernameMaxLength validator", function() {
+    var settings = {
+      username_length_max: 4
+    };
+
+    assert.equal(
+      validators.usernameMaxLength(settings)('yuss'), undefined,
+      "username of required length passed validation.");
+    assert.equal(
+      validators.usernameMaxLength(settings)('too long!'),
+      "Username cannot be longer than 4 characters.",
+      "too long username failed validation.");
+  });
+
+  it("username validator", function() {
+    assert.equal(validators.usernameContent()('v4lid'), undefined,
+      "valid username passed validation.");
+    assert.equal(
+      validators.usernameContent()('++++'),
+      "Username can only contain latin alphabet letters and digits.",
+      "invalid username failed validation.");
+  });
+
+  it("passwordMinLength validator", function() {
+    var settings = {
+      password_length_min: 4
+    };
+
+    assert.equal(
+      validators.passwordMinLength(settings)('yusss'), undefined,
+      "password of required length passed validation.");
+    assert.equal(
+      validators.passwordMinLength(settings)('no'),
+      "Valid password must be at least 4 characters long.",
+      "too short password failed validation.");
+  });
+});

+ 4612 - 1
misago/static/misago/css/misago.css

@@ -1 +1,4612 @@
-/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */hr,img{border:0}body,figure{margin:0}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px}.img-thumbnail,.table,label{max-width:100%}.alerts-snackbar,a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}b,optgroup,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{vertical-align:middle}svg:not(:root){overflow:hidden}hr{box-sizing:content-box;height:0}pre,textarea{overflow:auto}code,kbd,pre,samp{font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{blockquote,img,pre,tr{page-break-inside:avoid}*,:after,:before{background:0 0!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999}thead{display:table-header-group}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}.btn,.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-warning.active,.btn-warning:active,.btn.active,.btn:active,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover,.form-control,.navbar-toggle,.open>.dropdown-toggle.btn-danger,.open>.dropdown-toggle.btn-default,.open>.dropdown-toggle.btn-info,.open>.dropdown-toggle.btn-primary,.open>.dropdown-toggle.btn-warning{background-image:none}.img-thumbnail,body{background-color:#fff}*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;height:auto}.dropdown-menu .divider,.nav .nav-divider,.sr-only{height:1px;overflow:hidden}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;margin:-1px;padding:0;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}dt,kbd kbd,label{font-weight:700}address,blockquote .small,blockquote footer,blockquote small,dd,dt,pre{line-height:1.42857143}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{background-color:#fcf8e3;padding:.2em}.list-inline,.list-unstyled{padding-left:0;list-style:none}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}pre code,table{background-color:transparent}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}dl,ol,ul{margin-top:0}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child,ol ol,ol ul,ul ol,ul ul{margin-bottom:0}address,dl{margin-bottom:20px}ol,ul{margin-bottom:10px}.list-inline{margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.container{width:750px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;color:#777}legend,pre{display:block;color:#333}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}code,kbd{padding:2px 4px;font-size:90%}caption,th{text-align:left}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{font-style:normal}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;box-shadow:none}pre{padding:9.5px;margin:0 0 10px;font-size:13px;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}.container,.container-fluid{margin-right:auto;margin-left:auto}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;border-radius:0}.container,.container-fluid{padding-left:15px;padding-right:15px}.pre-scrollable{overflow-y:scroll}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}caption{padding-top:8px;padding-bottom:8px;color:#777}.table{width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.btn,.caret{vertical-align:middle}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered,.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover,.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}table col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset,legend{padding:0;border:0}fieldset{margin:0;min-width:0}legend{width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px}.media-object.img-thumbnail,.nav>li>a>img{max-width:none}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}.form-control,output{font-size:14px;line-height:1.42857143;color:#555;display:block}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}output{padding-top:7px}.form-control{width:100%;height:34px;padding:6px 12px;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .form-control-feedback,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-left:-20px;margin-top:4px\9}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.checkbox-inline.disabled,.checkbox.disabled label,.radio-inline.disabled,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio label,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.form-group-sm .form-control,.input-sm{padding:5px 10px;border-radius:3px;font-size:12px}.input-sm{height:30px;line-height:1.5}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;line-height:1.5}.form-group-lg .form-control,.input-lg{border-radius:6px;padding:10px 16px;font-size:18px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;line-height:1.3333333}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;line-height:1.3333333}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.collapsing,.dropdown,.dropup{position:relative}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .form-control-feedback,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .form-control-feedback,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-control-static,.form-inline .form-group{display:inline-block}.form-inline .control-label,.form-inline .form-group{margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.btn-block,input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;touch-action:manipulation;cursor:pointer;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.btn.active,.btn:active,.dropdown-toggle:focus,.modal,.modal-content,.navbar-toggle:focus,.open>a{outline:0}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary.active,.btn-primary:active,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success.active,.btn-success:active,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info.active,.btn-info:active,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger.active,.btn-danger:active,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:400;border-radius:0}.alert .alert-link,.close{font-weight:700}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-xs{font-size:12px;line-height:1.5;border-radius:3px}.btn-sm{padding:5px 10px}.btn-xs{padding:1px 5px}.btn-block{display:block}.btn-block+.btn-block{margin-top:5px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{height:0;overflow:hidden;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu-right,.dropdown-menu.pull-right{left:auto;right:0}.nav>li,.nav>li>a,.open>.dropdown-menu{display:block}.dropdown-menu .divider{margin:9px 0;background-color:#e5e5e5}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0;background-color:#337ab7}.dropdown-header,.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover,.nav>li.disabled>a{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.nav>li,.nav>li>a,.navbar{position:relative}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.nav-justified>.dropdown .dropdown-menu,.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li>a{padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{margin:9px 0;background-color:#e5e5e5}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px;margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0;border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-justified>li,.nav-stacked>li{float:none}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{min-height:50px;border:1px solid transparent}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar{border-radius:4px}.navbar-header{float:left}.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-left:0;padding-right:0}}.modal,.modal-open,.progress{overflow:hidden}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}.navbar-static-top{z-index:1000;border-width:0 0 1px}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;border:1px solid transparent;border-radius:4px}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}.progress-bar-striped,.progress-striped .progress-bar,.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}@media (min-width:768px){.navbar-toggle{display:none}.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin:8px -15px}@media (min-width:768px){.navbar-form .form-control-static,.navbar-form .form-group{display:inline-block}.navbar-form .control-label,.navbar-form .form-group{margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-radius:4px 4px 0 0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-nav>li>a,.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>li>a,.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.modal,.modal-backdrop{top:0;right:0;bottom:0;left:0}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-striped .progress-bar-info,.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal{display:none;position:fixed;z-index:1050;-webkit-overflow-scrolling:touch}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box}.modal-backdrop{position:fixed;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.row:after,.row:before{content:" ";display:table}.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.row:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.hidden,.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.material-icon,.user-dropdown .dropdown-header strong{font-weight:400}.affix{position:fixed}@-ms-viewport{width:device-width}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}.visible-xs-block{display:block!important}.visible-xs-inline{display:inline!important}.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}.visible-sm-block{display:block!important}.visible-sm-inline{display:inline!important}.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}.visible-md-block{display:block!important}.visible-md-inline{display:inline!important}.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}.visible-lg-block{display:block!important}.visible-lg-inline{display:inline!important}.visible-lg-inline-block{display:inline-block!important}.hidden-lg{display:none!important}}@media (max-width:767px){.hidden-xs{display:none!important}.navbar.navbar-misago{min-height:auto}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}.hidden-print{display:none!important}}.alerts-snackbar p,.loader-compact>div,.navbar .navbar-full .navbar-brand>*{display:inline-block}.auth-changed-message{width:100%;position:fixed;top:0;left:0;z-index:1070;transition:top .3s ease}.auth-changed-message>div{position:absolute;bottom:0;width:100%;background-color:#eee;padding:20px 0}.auth-changed-message.show>div{top:0;bottom:auto}.auth-changed-message p{padding:10px 0;color:#222;font-size:18px}@media screen and (max-width:991px){.auth-changed-message{text-align:center}.auth-changed-message .btn{padding:10px 16px;font-size:18px}}.alerts-snackbar{position:fixed;top:-100%;width:100%;z-index:1060;text-align:center;font-size:18px;transition:top .3s ease}.alerts-snackbar.in{top:0;transition:top .2s ease}.alerts-snackbar p{border-radius:0 0 4px 4px;margin:0;pointer-events:all}.loader.sk-folding-cube{margin:80px auto;width:80px;height:80px;position:relative;-webkit-transform:rotateZ(45deg);transform:rotateZ(45deg)}.loader.sk-folding-cube .sk-cube{float:left;width:50%;height:50%;position:relative;-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.loader.sk-folding-cube .sk-cube:before{content:'';position:absolute;top:0;left:0;width:100%;height:100%;background-color:#777;-webkit-animation:sk-foldCubeAngle 2.4s infinite linear both;animation:sk-foldCubeAngle 2.4s infinite linear both;-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.loader.sk-folding-cube .sk-cube2{-webkit-transform:scale(1.1) rotateZ(90deg);transform:scale(1.1) rotateZ(90deg)}.loader.sk-folding-cube .sk-cube3{-webkit-transform:scale(1.1) rotateZ(180deg);transform:scale(1.1) rotateZ(180deg)}.loader.sk-folding-cube .sk-cube4{-webkit-transform:scale(1.1) rotateZ(270deg);transform:scale(1.1) rotateZ(270deg)}.loader.sk-folding-cube .sk-cube2:before{-webkit-animation-delay:.3s;animation-delay:.3s}.loader.sk-folding-cube .sk-cube3:before{-webkit-animation-delay:.6s;animation-delay:.6s}.loader.sk-folding-cube .sk-cube4:before{-webkit-animation-delay:.9s;animation-delay:.9s}@-webkit-keyframes sk-foldCubeAngle{0%,10%{-webkit-transform:perspective(140px) rotateX(-180deg);transform:perspective(140px) rotateX(-180deg);opacity:0}25%,75%{-webkit-transform:perspective(140px) rotateX(0);transform:perspective(140px) rotateX(0);opacity:1}100%,90%{-webkit-transform:perspective(140px) rotateY(180deg);transform:perspective(140px) rotateY(180deg);opacity:0}}@keyframes sk-foldCubeAngle{0%,10%{-webkit-transform:perspective(140px) rotateX(-180deg);transform:perspective(140px) rotateX(-180deg);opacity:0}25%,75%{-webkit-transform:perspective(140px) rotateX(0);transform:perspective(140px) rotateX(0);opacity:1}100%,90%{-webkit-transform:perspective(140px) rotateY(180deg);transform:perspective(140px) rotateY(180deg);opacity:0}}.loader-compact{margin:0 auto;width:50px;text-align:center}.loader-compact>div{width:10px;height:10px;background-color:#333;border-radius:100%;-webkit-animation:sk-bouncedelay 1.4s infinite ease-in-out both;animation:sk-bouncedelay 1.4s infinite ease-in-out both}.loader-compact .bounce1{-webkit-animation-delay:-.32s;animation-delay:-.32s}.loader-compact .bounce2{margin:0 4px;-webkit-animation-delay:-.16s;animation-delay:-.16s}@-webkit-keyframes sk-bouncedelay{0%,100%,80%{-webkit-transform:scale(.5)}40%{-webkit-transform:scale(1)}}@keyframes sk-bouncedelay{0%,100%,80%{-webkit-transform:scale(.5);transform:scale(.5)}40%{-webkit-transform:scale(1);transform:scale(1)}}.page-loading .lead{margin-top:-40px;margin-bottom:80px;color:#777;text-align:center}.navbar{margin-bottom:0}.navbar .navbar-full .navbar-brand img{height:16px}.navbar .navbar-full .nav-guest,.navbar .navbar-full .nav-user{float:right}.navbar .navbar-full .nav-guest .navbar-btn,.navbar .navbar-full .nav-user .navbar-btn{margin-left:15px}.navbar .navbar-full .nav-user .dropdown-toggle{padding:8px}.navbar .navbar-full .nav-user .dropdown-toggle img{width:34px;height:34px}.navbar ul.navbar-compact-nav{margin:0;display:table;width:100%}.navbar ul.navbar-compact-nav>li{display:table-cell}.navbar ul.navbar-compact-nav>li>a,.navbar ul.navbar-compact-nav>li>button{background:0 0;border:none;margin:0;padding-top:10px;padding-bottom:10px;width:100%;color:#777;text-align:center}.navbar ul.navbar-compact-nav>li>a:focus,.navbar ul.navbar-compact-nav>li>a:hover,.navbar ul.navbar-compact-nav>li>button:focus,.navbar ul.navbar-compact-nav>li>button:hover{color:#333;background-color:transparent}.navbar ul.navbar-compact-nav>li>a>img,.navbar ul.navbar-compact-nav>li>button>img{width:24px;height:24px}.navbar ul.navbar-compact-nav>li>button{padding-top:10px;padding-bottom:10px}.navbar ul.navbar-compact-nav>li>a>.material-icon{font-size:24px;line-height:24px}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(../fonts/MaterialIcons-Regular.eot);src:local('Material Icons'),local('MaterialIcons-Regular'),url(../fonts/MaterialIcons-Regular.woff2) format('woff2'),url(../fonts/MaterialIcons-Regular.woff) format('woff'),url(../fonts/MaterialIcons-Regular.ttf) format('truetype')}.material-icon{font-family:'Material Icons';font-style:normal;display:inline-block;width:1em;height:1em;line-height:1;text-align:center;text-transform:none;letter-spacing:normal;vertical-align:middle;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:'liga'}@media screen and (max-width:991px){.modal-message{text-align:center}.modal-message .message-icon{margin:30px}.modal-message .message-icon .material-icon{font-size:160px}}@media screen and (min-width:992px){.modal-message .message-icon{float:left}.modal-message .message-icon .material-icon{font-size:80px}.modal-message .message-body{margin-left:100px}}@media screen and (max-width:991px){.modal-register .modal-footer{text-align:center}.modal-register .modal-footer a{display:block}.modal-register .modal-footer .btn{display:block;float:none;margin-top:10px;width:100%}}.material-icon.form-control-feedback{top:6px;right:24px;font-size:1.42857143;line-height:1.42857143}.well.well-form.well-done{font-size:18px;text-align:center}.well.well-form.well-done .message-icon{margin-bottom:10px;font-size:90px;line-height:90px}.well.well-form.well-done .message-body{margin-bottom:6.67px}.well.well-form.well-noscript{font-size:18px;text-align:center}.well.well-form.well-noscript .message-icon{margin-bottom:10px;font-size:90px;line-height:90px}.btn.btn-loading,.btn.btn-loading:active,.btn.btn-loading:focus,.btn.btn-loading:hover,.btn.btn-loading:link,.btn.btn-loading:visited{color:transparent}.btn.btn-loading .loader-compact,.btn.btn-loading:active .loader-compact,.btn.btn-loading:focus .loader-compact,.btn.btn-loading:hover .loader-compact,.btn.btn-loading:link .loader-compact,.btn.btn-loading:visited .loader-compact{margin-top:-20px;height:20px;position:relative;top:0}.btn.btn-loading.btn-default .loader-compact>div{background-color:#333}.btn.btn-loading.btn-danger .loader-compact>div,.btn.btn-loading.btn-info .loader-compact>div,.btn.btn-loading.btn-primary .loader-compact>div,.btn.btn-loading.btn-success .loader-compact>div,.btn.btn-loading.btn-warning .loader-compact>div{background-color:#fff}.dropdown-menu>li>.btn-link,.dropdown-menu>li>a{display:block;border:none;clear:both;float:none;padding:4px 20px;width:100%;color:#333;font-weight:400;line-height:1.42857143;text-align:left;white-space:nowrap}.dropdown-menu>li>.btn-link:focus,.dropdown-menu>li>.btn-link:hover,.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#f5f5f5;color:#262626;text-decoration:none}.dropdown-menu>li>.btn-link .material-icon,.dropdown-menu>li>a .material-icon{margin:-2px 7px -2px 0;position:relative;bottom:1px;font-size:18px}.dropdown-menu .dropdown-footer{padding:6px 20px}.mobile-dropdown{position:static;margin:0}.mobile-dropdown.open>.dropdown-menu{border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none;display:block;margin:0;width:100%;position:static}.user-dropdown .guest-preview{text-align:center}.user-dropdown .guest-preview .row{margin:0}.navbar .user-dropdown{width:240px}.user-dropdown .dropdown-header{padding:6px 20px;font-size:18px}.misago-footer{margin-top:30px;margin-bottom:50px}.misago-footer .footer-content{border-top:1px solid #eee;padding-top:30px}.misago-footer .noscript-message .material-icon{position:relative;bottom:1px;font-size:18px}@media screen and (max-width:991px){.page-error,.page-message{text-align:center}.page-error .message-icon,.page-message .message-icon{margin:30px}.page-error .message-icon .material-icon,.page-message .message-icon .material-icon{font-size:160px}}@media screen and (min-width:992px){.page-error .message-panel,.page-message .message-panel{margin:60px auto;max-width:779.35px;overflow:auto}.page-error .message-icon,.page-message .message-icon{float:left}.page-error .message-icon .material-icon,.page-message .message-icon .material-icon{font-size:80px}.page-error .message-body,.page-message .message-body{margin-left:100px}}
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+  font-family: sans-serif;
+  -ms-text-size-adjust: 100%;
+  -webkit-text-size-adjust: 100%;
+}
+body {
+  margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+  display: block;
+}
+audio,
+canvas,
+progress,
+video {
+  display: inline-block;
+  vertical-align: baseline;
+}
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+[hidden],
+template {
+  display: none;
+}
+a {
+  background-color: transparent;
+}
+a:active,
+a:hover {
+  outline: 0;
+}
+abbr[title] {
+  border-bottom: 1px dotted;
+}
+b,
+strong {
+  font-weight: bold;
+}
+dfn {
+  font-style: italic;
+}
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+mark {
+  background: #ff0;
+  color: #000;
+}
+small {
+  font-size: 80%;
+}
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sup {
+  top: -0.5em;
+}
+sub {
+  bottom: -0.25em;
+}
+img {
+  border: 0;
+}
+svg:not(:root) {
+  overflow: hidden;
+}
+figure {
+  margin: 1em 40px;
+}
+hr {
+  box-sizing: content-box;
+  height: 0;
+}
+pre {
+  overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+  color: inherit;
+  font: inherit;
+  margin: 0;
+}
+button {
+  overflow: visible;
+}
+button,
+select {
+  text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  -webkit-appearance: button;
+  cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+  cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+  border: 0;
+  padding: 0;
+}
+input {
+  line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+  box-sizing: border-box;
+  padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+input[type="search"] {
+  -webkit-appearance: textfield;
+  box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+fieldset {
+  border: 1px solid #c0c0c0;
+  margin: 0 2px;
+  padding: 0.35em 0.625em 0.75em;
+}
+legend {
+  border: 0;
+  padding: 0;
+}
+textarea {
+  overflow: auto;
+}
+optgroup {
+  font-weight: bold;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+td,
+th {
+  padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+  *,
+  *:before,
+  *:after {
+    background: transparent !important;
+    color: #000 !important;
+    box-shadow: none !important;
+    text-shadow: none !important;
+  }
+  a,
+  a:visited {
+    text-decoration: underline;
+  }
+  a[href]:after {
+    content: " (" attr(href) ")";
+  }
+  abbr[title]:after {
+    content: " (" attr(title) ")";
+  }
+  a[href^="#"]:after,
+  a[href^="javascript:"]:after {
+    content: "";
+  }
+  pre,
+  blockquote {
+    border: 1px solid #999;
+    page-break-inside: avoid;
+  }
+  thead {
+    display: table-header-group;
+  }
+  tr,
+  img {
+    page-break-inside: avoid;
+  }
+  img {
+    max-width: 100% !important;
+  }
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3;
+  }
+  h2,
+  h3 {
+    page-break-after: avoid;
+  }
+  .navbar {
+    display: none;
+  }
+  .btn > .caret,
+  .dropup > .btn > .caret {
+    border-top-color: #000 !important;
+  }
+  .label {
+    border: 1px solid #000;
+  }
+  .table {
+    border-collapse: collapse !important;
+  }
+  .table td,
+  .table th {
+    background-color: #fff !important;
+  }
+  .table-bordered th,
+  .table-bordered td {
+    border: 1px solid #ddd !important;
+  }
+}
+* {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+*:before,
+*:after {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+html {
+  font-size: 10px;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 14px;
+  line-height: 1.42857143;
+  color: #333333;
+  background-color: #fff;
+}
+input,
+button,
+select,
+textarea {
+  font-family: inherit;
+  font-size: inherit;
+  line-height: inherit;
+}
+a {
+  color: #337ab7;
+  text-decoration: none;
+}
+a:hover,
+a:focus {
+  color: #23527c;
+  text-decoration: underline;
+}
+a:focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+figure {
+  margin: 0;
+}
+img {
+  vertical-align: middle;
+}
+.img-responsive {
+  display: block;
+  max-width: 100%;
+  height: auto;
+}
+.img-rounded {
+  border-radius: 6px;
+}
+.img-thumbnail {
+  padding: 4px;
+  line-height: 1.42857143;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  border-radius: 4px;
+  -webkit-transition: all 0.2s ease-in-out;
+  -o-transition: all 0.2s ease-in-out;
+  transition: all 0.2s ease-in-out;
+  display: inline-block;
+  max-width: 100%;
+  height: auto;
+}
+.img-circle {
+  border-radius: 50%;
+}
+hr {
+  margin-top: 20px;
+  margin-bottom: 20px;
+  border: 0;
+  border-top: 1px solid #eeeeee;
+}
+.sr-only {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  margin: -1px;
+  padding: 0;
+  overflow: hidden;
+  clip: rect(0, 0, 0, 0);
+  border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+  position: static;
+  width: auto;
+  height: auto;
+  margin: 0;
+  overflow: visible;
+  clip: auto;
+}
+[role="button"] {
+  cursor: pointer;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+  font-family: inherit;
+  font-weight: 500;
+  line-height: 1.1;
+  color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+  font-weight: normal;
+  line-height: 1;
+  color: #777777;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+  margin-top: 20px;
+  margin-bottom: 10px;
+}
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+  font-size: 65%;
+}
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+  font-size: 75%;
+}
+h1,
+.h1 {
+  font-size: 36px;
+}
+h2,
+.h2 {
+  font-size: 30px;
+}
+h3,
+.h3 {
+  font-size: 24px;
+}
+h4,
+.h4 {
+  font-size: 18px;
+}
+h5,
+.h5 {
+  font-size: 14px;
+}
+h6,
+.h6 {
+  font-size: 12px;
+}
+p {
+  margin: 0 0 10px;
+}
+.lead {
+  margin-bottom: 20px;
+  font-size: 16px;
+  font-weight: 300;
+  line-height: 1.4;
+}
+@media (min-width: 768px) {
+  .lead {
+    font-size: 21px;
+  }
+}
+small,
+.small {
+  font-size: 85%;
+}
+mark,
+.mark {
+  background-color: #fcf8e3;
+  padding: .2em;
+}
+.text-left {
+  text-align: left;
+}
+.text-right {
+  text-align: right;
+}
+.text-center {
+  text-align: center;
+}
+.text-justify {
+  text-align: justify;
+}
+.text-nowrap {
+  white-space: nowrap;
+}
+.text-lowercase {
+  text-transform: lowercase;
+}
+.text-uppercase {
+  text-transform: uppercase;
+}
+.text-capitalize {
+  text-transform: capitalize;
+}
+.text-muted {
+  color: #777777;
+}
+.text-primary {
+  color: #337ab7;
+}
+a.text-primary:hover,
+a.text-primary:focus {
+  color: #286090;
+}
+.text-success {
+  color: #3c763d;
+}
+a.text-success:hover,
+a.text-success:focus {
+  color: #2b542c;
+}
+.text-info {
+  color: #31708f;
+}
+a.text-info:hover,
+a.text-info:focus {
+  color: #245269;
+}
+.text-warning {
+  color: #8a6d3b;
+}
+a.text-warning:hover,
+a.text-warning:focus {
+  color: #66512c;
+}
+.text-danger {
+  color: #a94442;
+}
+a.text-danger:hover,
+a.text-danger:focus {
+  color: #843534;
+}
+.bg-primary {
+  color: #fff;
+  background-color: #337ab7;
+}
+a.bg-primary:hover,
+a.bg-primary:focus {
+  background-color: #286090;
+}
+.bg-success {
+  background-color: #dff0d8;
+}
+a.bg-success:hover,
+a.bg-success:focus {
+  background-color: #c1e2b3;
+}
+.bg-info {
+  background-color: #d9edf7;
+}
+a.bg-info:hover,
+a.bg-info:focus {
+  background-color: #afd9ee;
+}
+.bg-warning {
+  background-color: #fcf8e3;
+}
+a.bg-warning:hover,
+a.bg-warning:focus {
+  background-color: #f7ecb5;
+}
+.bg-danger {
+  background-color: #f2dede;
+}
+a.bg-danger:hover,
+a.bg-danger:focus {
+  background-color: #e4b9b9;
+}
+.page-header {
+  padding-bottom: 9px;
+  margin: 40px 0 20px;
+  border-bottom: 1px solid #eeeeee;
+}
+ul,
+ol {
+  margin-top: 0;
+  margin-bottom: 10px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+  margin-bottom: 0;
+}
+.list-unstyled {
+  padding-left: 0;
+  list-style: none;
+}
+.list-inline {
+  padding-left: 0;
+  list-style: none;
+  margin-left: -5px;
+}
+.list-inline > li {
+  display: inline-block;
+  padding-left: 5px;
+  padding-right: 5px;
+}
+dl {
+  margin-top: 0;
+  margin-bottom: 20px;
+}
+dt,
+dd {
+  line-height: 1.42857143;
+}
+dt {
+  font-weight: bold;
+}
+dd {
+  margin-left: 0;
+}
+@media (min-width: 768px) {
+  .dl-horizontal dt {
+    float: left;
+    width: 160px;
+    clear: left;
+    text-align: right;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .dl-horizontal dd {
+    margin-left: 180px;
+  }
+}
+abbr[title],
+abbr[data-original-title] {
+  cursor: help;
+  border-bottom: 1px dotted #777777;
+}
+.initialism {
+  font-size: 90%;
+  text-transform: uppercase;
+}
+blockquote {
+  padding: 10px 20px;
+  margin: 0 0 20px;
+  font-size: 17.5px;
+  border-left: 5px solid #eeeeee;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+  margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+  display: block;
+  font-size: 80%;
+  line-height: 1.42857143;
+  color: #777777;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+  content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+  padding-right: 15px;
+  padding-left: 0;
+  border-right: 5px solid #eeeeee;
+  border-left: 0;
+  text-align: right;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+  content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+  content: '\00A0 \2014';
+}
+address {
+  margin-bottom: 20px;
+  font-style: normal;
+  line-height: 1.42857143;
+}
+code,
+kbd,
+pre,
+samp {
+  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+code {
+  padding: 2px 4px;
+  font-size: 90%;
+  color: #c7254e;
+  background-color: #f9f2f4;
+  border-radius: 4px;
+}
+kbd {
+  padding: 2px 4px;
+  font-size: 90%;
+  color: #fff;
+  background-color: #333;
+  border-radius: 3px;
+  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+kbd kbd {
+  padding: 0;
+  font-size: 100%;
+  font-weight: bold;
+  box-shadow: none;
+}
+pre {
+  display: block;
+  padding: 9.5px;
+  margin: 0 0 10px;
+  font-size: 13px;
+  line-height: 1.42857143;
+  word-break: break-all;
+  word-wrap: break-word;
+  color: #333333;
+  background-color: #f5f5f5;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+}
+pre code {
+  padding: 0;
+  font-size: inherit;
+  color: inherit;
+  white-space: pre-wrap;
+  background-color: transparent;
+  border-radius: 0;
+}
+.pre-scrollable {
+  max-height: 340px;
+  overflow-y: scroll;
+}
+.container {
+  margin-right: auto;
+  margin-left: auto;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+@media (min-width: 768px) {
+  .container {
+    width: 750px;
+  }
+}
+@media (min-width: 992px) {
+  .container {
+    width: 970px;
+  }
+}
+@media (min-width: 1200px) {
+  .container {
+    width: 1170px;
+  }
+}
+.container-fluid {
+  margin-right: auto;
+  margin-left: auto;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+.row {
+  margin-left: -15px;
+  margin-right: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+  position: relative;
+  min-height: 1px;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+  float: left;
+}
+.col-xs-12 {
+  width: 100%;
+}
+.col-xs-11 {
+  width: 91.66666667%;
+}
+.col-xs-10 {
+  width: 83.33333333%;
+}
+.col-xs-9 {
+  width: 75%;
+}
+.col-xs-8 {
+  width: 66.66666667%;
+}
+.col-xs-7 {
+  width: 58.33333333%;
+}
+.col-xs-6 {
+  width: 50%;
+}
+.col-xs-5 {
+  width: 41.66666667%;
+}
+.col-xs-4 {
+  width: 33.33333333%;
+}
+.col-xs-3 {
+  width: 25%;
+}
+.col-xs-2 {
+  width: 16.66666667%;
+}
+.col-xs-1 {
+  width: 8.33333333%;
+}
+.col-xs-pull-12 {
+  right: 100%;
+}
+.col-xs-pull-11 {
+  right: 91.66666667%;
+}
+.col-xs-pull-10 {
+  right: 83.33333333%;
+}
+.col-xs-pull-9 {
+  right: 75%;
+}
+.col-xs-pull-8 {
+  right: 66.66666667%;
+}
+.col-xs-pull-7 {
+  right: 58.33333333%;
+}
+.col-xs-pull-6 {
+  right: 50%;
+}
+.col-xs-pull-5 {
+  right: 41.66666667%;
+}
+.col-xs-pull-4 {
+  right: 33.33333333%;
+}
+.col-xs-pull-3 {
+  right: 25%;
+}
+.col-xs-pull-2 {
+  right: 16.66666667%;
+}
+.col-xs-pull-1 {
+  right: 8.33333333%;
+}
+.col-xs-pull-0 {
+  right: auto;
+}
+.col-xs-push-12 {
+  left: 100%;
+}
+.col-xs-push-11 {
+  left: 91.66666667%;
+}
+.col-xs-push-10 {
+  left: 83.33333333%;
+}
+.col-xs-push-9 {
+  left: 75%;
+}
+.col-xs-push-8 {
+  left: 66.66666667%;
+}
+.col-xs-push-7 {
+  left: 58.33333333%;
+}
+.col-xs-push-6 {
+  left: 50%;
+}
+.col-xs-push-5 {
+  left: 41.66666667%;
+}
+.col-xs-push-4 {
+  left: 33.33333333%;
+}
+.col-xs-push-3 {
+  left: 25%;
+}
+.col-xs-push-2 {
+  left: 16.66666667%;
+}
+.col-xs-push-1 {
+  left: 8.33333333%;
+}
+.col-xs-push-0 {
+  left: auto;
+}
+.col-xs-offset-12 {
+  margin-left: 100%;
+}
+.col-xs-offset-11 {
+  margin-left: 91.66666667%;
+}
+.col-xs-offset-10 {
+  margin-left: 83.33333333%;
+}
+.col-xs-offset-9 {
+  margin-left: 75%;
+}
+.col-xs-offset-8 {
+  margin-left: 66.66666667%;
+}
+.col-xs-offset-7 {
+  margin-left: 58.33333333%;
+}
+.col-xs-offset-6 {
+  margin-left: 50%;
+}
+.col-xs-offset-5 {
+  margin-left: 41.66666667%;
+}
+.col-xs-offset-4 {
+  margin-left: 33.33333333%;
+}
+.col-xs-offset-3 {
+  margin-left: 25%;
+}
+.col-xs-offset-2 {
+  margin-left: 16.66666667%;
+}
+.col-xs-offset-1 {
+  margin-left: 8.33333333%;
+}
+.col-xs-offset-0 {
+  margin-left: 0%;
+}
+@media (min-width: 768px) {
+  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+    float: left;
+  }
+  .col-sm-12 {
+    width: 100%;
+  }
+  .col-sm-11 {
+    width: 91.66666667%;
+  }
+  .col-sm-10 {
+    width: 83.33333333%;
+  }
+  .col-sm-9 {
+    width: 75%;
+  }
+  .col-sm-8 {
+    width: 66.66666667%;
+  }
+  .col-sm-7 {
+    width: 58.33333333%;
+  }
+  .col-sm-6 {
+    width: 50%;
+  }
+  .col-sm-5 {
+    width: 41.66666667%;
+  }
+  .col-sm-4 {
+    width: 33.33333333%;
+  }
+  .col-sm-3 {
+    width: 25%;
+  }
+  .col-sm-2 {
+    width: 16.66666667%;
+  }
+  .col-sm-1 {
+    width: 8.33333333%;
+  }
+  .col-sm-pull-12 {
+    right: 100%;
+  }
+  .col-sm-pull-11 {
+    right: 91.66666667%;
+  }
+  .col-sm-pull-10 {
+    right: 83.33333333%;
+  }
+  .col-sm-pull-9 {
+    right: 75%;
+  }
+  .col-sm-pull-8 {
+    right: 66.66666667%;
+  }
+  .col-sm-pull-7 {
+    right: 58.33333333%;
+  }
+  .col-sm-pull-6 {
+    right: 50%;
+  }
+  .col-sm-pull-5 {
+    right: 41.66666667%;
+  }
+  .col-sm-pull-4 {
+    right: 33.33333333%;
+  }
+  .col-sm-pull-3 {
+    right: 25%;
+  }
+  .col-sm-pull-2 {
+    right: 16.66666667%;
+  }
+  .col-sm-pull-1 {
+    right: 8.33333333%;
+  }
+  .col-sm-pull-0 {
+    right: auto;
+  }
+  .col-sm-push-12 {
+    left: 100%;
+  }
+  .col-sm-push-11 {
+    left: 91.66666667%;
+  }
+  .col-sm-push-10 {
+    left: 83.33333333%;
+  }
+  .col-sm-push-9 {
+    left: 75%;
+  }
+  .col-sm-push-8 {
+    left: 66.66666667%;
+  }
+  .col-sm-push-7 {
+    left: 58.33333333%;
+  }
+  .col-sm-push-6 {
+    left: 50%;
+  }
+  .col-sm-push-5 {
+    left: 41.66666667%;
+  }
+  .col-sm-push-4 {
+    left: 33.33333333%;
+  }
+  .col-sm-push-3 {
+    left: 25%;
+  }
+  .col-sm-push-2 {
+    left: 16.66666667%;
+  }
+  .col-sm-push-1 {
+    left: 8.33333333%;
+  }
+  .col-sm-push-0 {
+    left: auto;
+  }
+  .col-sm-offset-12 {
+    margin-left: 100%;
+  }
+  .col-sm-offset-11 {
+    margin-left: 91.66666667%;
+  }
+  .col-sm-offset-10 {
+    margin-left: 83.33333333%;
+  }
+  .col-sm-offset-9 {
+    margin-left: 75%;
+  }
+  .col-sm-offset-8 {
+    margin-left: 66.66666667%;
+  }
+  .col-sm-offset-7 {
+    margin-left: 58.33333333%;
+  }
+  .col-sm-offset-6 {
+    margin-left: 50%;
+  }
+  .col-sm-offset-5 {
+    margin-left: 41.66666667%;
+  }
+  .col-sm-offset-4 {
+    margin-left: 33.33333333%;
+  }
+  .col-sm-offset-3 {
+    margin-left: 25%;
+  }
+  .col-sm-offset-2 {
+    margin-left: 16.66666667%;
+  }
+  .col-sm-offset-1 {
+    margin-left: 8.33333333%;
+  }
+  .col-sm-offset-0 {
+    margin-left: 0%;
+  }
+}
+@media (min-width: 992px) {
+  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+    float: left;
+  }
+  .col-md-12 {
+    width: 100%;
+  }
+  .col-md-11 {
+    width: 91.66666667%;
+  }
+  .col-md-10 {
+    width: 83.33333333%;
+  }
+  .col-md-9 {
+    width: 75%;
+  }
+  .col-md-8 {
+    width: 66.66666667%;
+  }
+  .col-md-7 {
+    width: 58.33333333%;
+  }
+  .col-md-6 {
+    width: 50%;
+  }
+  .col-md-5 {
+    width: 41.66666667%;
+  }
+  .col-md-4 {
+    width: 33.33333333%;
+  }
+  .col-md-3 {
+    width: 25%;
+  }
+  .col-md-2 {
+    width: 16.66666667%;
+  }
+  .col-md-1 {
+    width: 8.33333333%;
+  }
+  .col-md-pull-12 {
+    right: 100%;
+  }
+  .col-md-pull-11 {
+    right: 91.66666667%;
+  }
+  .col-md-pull-10 {
+    right: 83.33333333%;
+  }
+  .col-md-pull-9 {
+    right: 75%;
+  }
+  .col-md-pull-8 {
+    right: 66.66666667%;
+  }
+  .col-md-pull-7 {
+    right: 58.33333333%;
+  }
+  .col-md-pull-6 {
+    right: 50%;
+  }
+  .col-md-pull-5 {
+    right: 41.66666667%;
+  }
+  .col-md-pull-4 {
+    right: 33.33333333%;
+  }
+  .col-md-pull-3 {
+    right: 25%;
+  }
+  .col-md-pull-2 {
+    right: 16.66666667%;
+  }
+  .col-md-pull-1 {
+    right: 8.33333333%;
+  }
+  .col-md-pull-0 {
+    right: auto;
+  }
+  .col-md-push-12 {
+    left: 100%;
+  }
+  .col-md-push-11 {
+    left: 91.66666667%;
+  }
+  .col-md-push-10 {
+    left: 83.33333333%;
+  }
+  .col-md-push-9 {
+    left: 75%;
+  }
+  .col-md-push-8 {
+    left: 66.66666667%;
+  }
+  .col-md-push-7 {
+    left: 58.33333333%;
+  }
+  .col-md-push-6 {
+    left: 50%;
+  }
+  .col-md-push-5 {
+    left: 41.66666667%;
+  }
+  .col-md-push-4 {
+    left: 33.33333333%;
+  }
+  .col-md-push-3 {
+    left: 25%;
+  }
+  .col-md-push-2 {
+    left: 16.66666667%;
+  }
+  .col-md-push-1 {
+    left: 8.33333333%;
+  }
+  .col-md-push-0 {
+    left: auto;
+  }
+  .col-md-offset-12 {
+    margin-left: 100%;
+  }
+  .col-md-offset-11 {
+    margin-left: 91.66666667%;
+  }
+  .col-md-offset-10 {
+    margin-left: 83.33333333%;
+  }
+  .col-md-offset-9 {
+    margin-left: 75%;
+  }
+  .col-md-offset-8 {
+    margin-left: 66.66666667%;
+  }
+  .col-md-offset-7 {
+    margin-left: 58.33333333%;
+  }
+  .col-md-offset-6 {
+    margin-left: 50%;
+  }
+  .col-md-offset-5 {
+    margin-left: 41.66666667%;
+  }
+  .col-md-offset-4 {
+    margin-left: 33.33333333%;
+  }
+  .col-md-offset-3 {
+    margin-left: 25%;
+  }
+  .col-md-offset-2 {
+    margin-left: 16.66666667%;
+  }
+  .col-md-offset-1 {
+    margin-left: 8.33333333%;
+  }
+  .col-md-offset-0 {
+    margin-left: 0%;
+  }
+}
+@media (min-width: 1200px) {
+  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+    float: left;
+  }
+  .col-lg-12 {
+    width: 100%;
+  }
+  .col-lg-11 {
+    width: 91.66666667%;
+  }
+  .col-lg-10 {
+    width: 83.33333333%;
+  }
+  .col-lg-9 {
+    width: 75%;
+  }
+  .col-lg-8 {
+    width: 66.66666667%;
+  }
+  .col-lg-7 {
+    width: 58.33333333%;
+  }
+  .col-lg-6 {
+    width: 50%;
+  }
+  .col-lg-5 {
+    width: 41.66666667%;
+  }
+  .col-lg-4 {
+    width: 33.33333333%;
+  }
+  .col-lg-3 {
+    width: 25%;
+  }
+  .col-lg-2 {
+    width: 16.66666667%;
+  }
+  .col-lg-1 {
+    width: 8.33333333%;
+  }
+  .col-lg-pull-12 {
+    right: 100%;
+  }
+  .col-lg-pull-11 {
+    right: 91.66666667%;
+  }
+  .col-lg-pull-10 {
+    right: 83.33333333%;
+  }
+  .col-lg-pull-9 {
+    right: 75%;
+  }
+  .col-lg-pull-8 {
+    right: 66.66666667%;
+  }
+  .col-lg-pull-7 {
+    right: 58.33333333%;
+  }
+  .col-lg-pull-6 {
+    right: 50%;
+  }
+  .col-lg-pull-5 {
+    right: 41.66666667%;
+  }
+  .col-lg-pull-4 {
+    right: 33.33333333%;
+  }
+  .col-lg-pull-3 {
+    right: 25%;
+  }
+  .col-lg-pull-2 {
+    right: 16.66666667%;
+  }
+  .col-lg-pull-1 {
+    right: 8.33333333%;
+  }
+  .col-lg-pull-0 {
+    right: auto;
+  }
+  .col-lg-push-12 {
+    left: 100%;
+  }
+  .col-lg-push-11 {
+    left: 91.66666667%;
+  }
+  .col-lg-push-10 {
+    left: 83.33333333%;
+  }
+  .col-lg-push-9 {
+    left: 75%;
+  }
+  .col-lg-push-8 {
+    left: 66.66666667%;
+  }
+  .col-lg-push-7 {
+    left: 58.33333333%;
+  }
+  .col-lg-push-6 {
+    left: 50%;
+  }
+  .col-lg-push-5 {
+    left: 41.66666667%;
+  }
+  .col-lg-push-4 {
+    left: 33.33333333%;
+  }
+  .col-lg-push-3 {
+    left: 25%;
+  }
+  .col-lg-push-2 {
+    left: 16.66666667%;
+  }
+  .col-lg-push-1 {
+    left: 8.33333333%;
+  }
+  .col-lg-push-0 {
+    left: auto;
+  }
+  .col-lg-offset-12 {
+    margin-left: 100%;
+  }
+  .col-lg-offset-11 {
+    margin-left: 91.66666667%;
+  }
+  .col-lg-offset-10 {
+    margin-left: 83.33333333%;
+  }
+  .col-lg-offset-9 {
+    margin-left: 75%;
+  }
+  .col-lg-offset-8 {
+    margin-left: 66.66666667%;
+  }
+  .col-lg-offset-7 {
+    margin-left: 58.33333333%;
+  }
+  .col-lg-offset-6 {
+    margin-left: 50%;
+  }
+  .col-lg-offset-5 {
+    margin-left: 41.66666667%;
+  }
+  .col-lg-offset-4 {
+    margin-left: 33.33333333%;
+  }
+  .col-lg-offset-3 {
+    margin-left: 25%;
+  }
+  .col-lg-offset-2 {
+    margin-left: 16.66666667%;
+  }
+  .col-lg-offset-1 {
+    margin-left: 8.33333333%;
+  }
+  .col-lg-offset-0 {
+    margin-left: 0%;
+  }
+}
+table {
+  background-color: transparent;
+}
+caption {
+  padding-top: 8px;
+  padding-bottom: 8px;
+  color: #777777;
+  text-align: left;
+}
+th {
+  text-align: left;
+}
+.table {
+  width: 100%;
+  max-width: 100%;
+  margin-bottom: 20px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+  padding: 8px;
+  line-height: 1.42857143;
+  vertical-align: top;
+  border-top: 1px solid #ddd;
+}
+.table > thead > tr > th {
+  vertical-align: bottom;
+  border-bottom: 2px solid #ddd;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+  border-top: 0;
+}
+.table > tbody + tbody {
+  border-top: 2px solid #ddd;
+}
+.table .table {
+  background-color: #fff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+  padding: 5px;
+}
+.table-bordered {
+  border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+  border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+  border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-of-type(odd) {
+  background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+  background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+  position: static;
+  float: none;
+  display: table-column;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+  position: static;
+  float: none;
+  display: table-cell;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+  background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+  background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+  background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+  background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+  background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+  background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+  background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+  background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+  background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+  background-color: #ebcccc;
+}
+.table-responsive {
+  overflow-x: auto;
+  min-height: 0.01%;
+}
+@media screen and (max-width: 767px) {
+  .table-responsive {
+    width: 100%;
+    margin-bottom: 15px;
+    overflow-y: hidden;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+    border: 1px solid #ddd;
+  }
+  .table-responsive > .table {
+    margin-bottom: 0;
+  }
+  .table-responsive > .table > thead > tr > th,
+  .table-responsive > .table > tbody > tr > th,
+  .table-responsive > .table > tfoot > tr > th,
+  .table-responsive > .table > thead > tr > td,
+  .table-responsive > .table > tbody > tr > td,
+  .table-responsive > .table > tfoot > tr > td {
+    white-space: nowrap;
+  }
+  .table-responsive > .table-bordered {
+    border: 0;
+  }
+  .table-responsive > .table-bordered > thead > tr > th:first-child,
+  .table-responsive > .table-bordered > tbody > tr > th:first-child,
+  .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+  .table-responsive > .table-bordered > thead > tr > td:first-child,
+  .table-responsive > .table-bordered > tbody > tr > td:first-child,
+  .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+    border-left: 0;
+  }
+  .table-responsive > .table-bordered > thead > tr > th:last-child,
+  .table-responsive > .table-bordered > tbody > tr > th:last-child,
+  .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+  .table-responsive > .table-bordered > thead > tr > td:last-child,
+  .table-responsive > .table-bordered > tbody > tr > td:last-child,
+  .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+    border-right: 0;
+  }
+  .table-responsive > .table-bordered > tbody > tr:last-child > th,
+  .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+  .table-responsive > .table-bordered > tbody > tr:last-child > td,
+  .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+    border-bottom: 0;
+  }
+}
+fieldset {
+  padding: 0;
+  margin: 0;
+  border: 0;
+  min-width: 0;
+}
+legend {
+  display: block;
+  width: 100%;
+  padding: 0;
+  margin-bottom: 20px;
+  font-size: 21px;
+  line-height: inherit;
+  color: #333333;
+  border: 0;
+  border-bottom: 1px solid #e5e5e5;
+}
+label {
+  display: inline-block;
+  max-width: 100%;
+  margin-bottom: 5px;
+  font-weight: bold;
+}
+input[type="search"] {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+  margin: 4px 0 0;
+  margin-top: 1px \9;
+  line-height: normal;
+}
+input[type="file"] {
+  display: block;
+}
+input[type="range"] {
+  display: block;
+  width: 100%;
+}
+select[multiple],
+select[size] {
+  height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+output {
+  display: block;
+  padding-top: 7px;
+  font-size: 14px;
+  line-height: 1.42857143;
+  color: #555555;
+}
+.form-control {
+  display: block;
+  width: 100%;
+  height: 34px;
+  padding: 6px 12px;
+  font-size: 14px;
+  line-height: 1.42857143;
+  color: #555555;
+  background-color: #fff;
+  background-image: none;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+  -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+.form-control:focus {
+  border-color: #66afe9;
+  outline: 0;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+.form-control::-moz-placeholder {
+  color: #999;
+  opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+  color: #999;
+}
+.form-control::-webkit-input-placeholder {
+  color: #999;
+}
+.form-control::-ms-expand {
+  border: 0;
+  background-color: transparent;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+  background-color: #eeeeee;
+  opacity: 1;
+}
+.form-control[disabled],
+fieldset[disabled] .form-control {
+  cursor: not-allowed;
+}
+textarea.form-control {
+  height: auto;
+}
+input[type="search"] {
+  -webkit-appearance: none;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+  input[type="date"].form-control,
+  input[type="time"].form-control,
+  input[type="datetime-local"].form-control,
+  input[type="month"].form-control {
+    line-height: 34px;
+  }
+  input[type="date"].input-sm,
+  input[type="time"].input-sm,
+  input[type="datetime-local"].input-sm,
+  input[type="month"].input-sm,
+  .input-group-sm input[type="date"],
+  .input-group-sm input[type="time"],
+  .input-group-sm input[type="datetime-local"],
+  .input-group-sm input[type="month"] {
+    line-height: 30px;
+  }
+  input[type="date"].input-lg,
+  input[type="time"].input-lg,
+  input[type="datetime-local"].input-lg,
+  input[type="month"].input-lg,
+  .input-group-lg input[type="date"],
+  .input-group-lg input[type="time"],
+  .input-group-lg input[type="datetime-local"],
+  .input-group-lg input[type="month"] {
+    line-height: 46px;
+  }
+}
+.form-group {
+  margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+  position: relative;
+  display: block;
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+  min-height: 20px;
+  padding-left: 20px;
+  margin-bottom: 0;
+  font-weight: normal;
+  cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+  position: absolute;
+  margin-left: -20px;
+  margin-top: 4px \9;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+  margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+  position: relative;
+  display: inline-block;
+  padding-left: 20px;
+  margin-bottom: 0;
+  vertical-align: middle;
+  font-weight: normal;
+  cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+  margin-top: 0;
+  margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+  cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+  cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+  cursor: not-allowed;
+}
+.form-control-static {
+  padding-top: 7px;
+  padding-bottom: 7px;
+  margin-bottom: 0;
+  min-height: 34px;
+}
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+  padding-left: 0;
+  padding-right: 0;
+}
+.input-sm {
+  height: 30px;
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+select.input-sm {
+  height: 30px;
+  line-height: 30px;
+}
+textarea.input-sm,
+select[multiple].input-sm {
+  height: auto;
+}
+.form-group-sm .form-control {
+  height: 30px;
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.form-group-sm select.form-control {
+  height: 30px;
+  line-height: 30px;
+}
+.form-group-sm textarea.form-control,
+.form-group-sm select[multiple].form-control {
+  height: auto;
+}
+.form-group-sm .form-control-static {
+  height: 30px;
+  min-height: 32px;
+  padding: 6px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+}
+.input-lg {
+  height: 46px;
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.3333333;
+  border-radius: 6px;
+}
+select.input-lg {
+  height: 46px;
+  line-height: 46px;
+}
+textarea.input-lg,
+select[multiple].input-lg {
+  height: auto;
+}
+.form-group-lg .form-control {
+  height: 46px;
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.3333333;
+  border-radius: 6px;
+}
+.form-group-lg select.form-control {
+  height: 46px;
+  line-height: 46px;
+}
+.form-group-lg textarea.form-control,
+.form-group-lg select[multiple].form-control {
+  height: auto;
+}
+.form-group-lg .form-control-static {
+  height: 46px;
+  min-height: 38px;
+  padding: 11px 16px;
+  font-size: 18px;
+  line-height: 1.3333333;
+}
+.has-feedback {
+  position: relative;
+}
+.has-feedback .form-control {
+  padding-right: 42.5px;
+}
+.form-control-feedback {
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: 2;
+  display: block;
+  width: 34px;
+  height: 34px;
+  line-height: 34px;
+  text-align: center;
+  pointer-events: none;
+}
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback,
+.form-group-lg .form-control + .form-control-feedback {
+  width: 46px;
+  height: 46px;
+  line-height: 46px;
+}
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback,
+.form-group-sm .form-control + .form-control-feedback {
+  width: 30px;
+  height: 30px;
+  line-height: 30px;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+  color: #3c763d;
+}
+.has-success .form-control {
+  border-color: #3c763d;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-success .form-control:focus {
+  border-color: #2b542c;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+}
+.has-success .input-group-addon {
+  color: #3c763d;
+  border-color: #3c763d;
+  background-color: #dff0d8;
+}
+.has-success .form-control-feedback {
+  color: #3c763d;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+  color: #8a6d3b;
+}
+.has-warning .form-control {
+  border-color: #8a6d3b;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-warning .form-control:focus {
+  border-color: #66512c;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+}
+.has-warning .input-group-addon {
+  color: #8a6d3b;
+  border-color: #8a6d3b;
+  background-color: #fcf8e3;
+}
+.has-warning .form-control-feedback {
+  color: #8a6d3b;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+  color: #a94442;
+}
+.has-error .form-control {
+  border-color: #a94442;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-error .form-control:focus {
+  border-color: #843534;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+}
+.has-error .input-group-addon {
+  color: #a94442;
+  border-color: #a94442;
+  background-color: #f2dede;
+}
+.has-error .form-control-feedback {
+  color: #a94442;
+}
+.has-feedback label ~ .form-control-feedback {
+  top: 25px;
+}
+.has-feedback label.sr-only ~ .form-control-feedback {
+  top: 0;
+}
+.help-block {
+  display: block;
+  margin-top: 5px;
+  margin-bottom: 10px;
+  color: #737373;
+}
+@media (min-width: 768px) {
+  .form-inline .form-group {
+    display: inline-block;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .form-control {
+    display: inline-block;
+    width: auto;
+    vertical-align: middle;
+  }
+  .form-inline .form-control-static {
+    display: inline-block;
+  }
+  .form-inline .input-group {
+    display: inline-table;
+    vertical-align: middle;
+  }
+  .form-inline .input-group .input-group-addon,
+  .form-inline .input-group .input-group-btn,
+  .form-inline .input-group .form-control {
+    width: auto;
+  }
+  .form-inline .input-group > .form-control {
+    width: 100%;
+  }
+  .form-inline .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .radio,
+  .form-inline .checkbox {
+    display: inline-block;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .radio label,
+  .form-inline .checkbox label {
+    padding-left: 0;
+  }
+  .form-inline .radio input[type="radio"],
+  .form-inline .checkbox input[type="checkbox"] {
+    position: relative;
+    margin-left: 0;
+  }
+  .form-inline .has-feedback .form-control-feedback {
+    top: 0;
+  }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+  margin-top: 0;
+  margin-bottom: 0;
+  padding-top: 7px;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+  min-height: 27px;
+}
+.form-horizontal .form-group {
+  margin-left: -15px;
+  margin-right: -15px;
+}
+@media (min-width: 768px) {
+  .form-horizontal .control-label {
+    text-align: right;
+    margin-bottom: 0;
+    padding-top: 7px;
+  }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+  right: 15px;
+}
+@media (min-width: 768px) {
+  .form-horizontal .form-group-lg .control-label {
+    padding-top: 11px;
+    font-size: 18px;
+  }
+}
+@media (min-width: 768px) {
+  .form-horizontal .form-group-sm .control-label {
+    padding-top: 6px;
+    font-size: 12px;
+  }
+}
+.btn {
+  display: inline-block;
+  margin-bottom: 0;
+  font-weight: normal;
+  text-align: center;
+  vertical-align: middle;
+  touch-action: manipulation;
+  cursor: pointer;
+  background-image: none;
+  border: 1px solid transparent;
+  white-space: nowrap;
+  padding: 6px 12px;
+  font-size: 14px;
+  line-height: 1.42857143;
+  border-radius: 4px;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+  color: #333;
+  text-decoration: none;
+}
+.btn:active,
+.btn.active {
+  outline: 0;
+  background-image: none;
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+  cursor: not-allowed;
+  opacity: 0.65;
+  filter: alpha(opacity=65);
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+a.btn.disabled,
+fieldset[disabled] a.btn {
+  pointer-events: none;
+}
+.btn-default {
+  color: #333;
+  background-color: #fff;
+  border-color: #ccc;
+}
+.btn-default:focus,
+.btn-default.focus {
+  color: #333;
+  background-color: #e6e6e6;
+  border-color: #8c8c8c;
+}
+.btn-default:hover {
+  color: #333;
+  background-color: #e6e6e6;
+  border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+  color: #333;
+  background-color: #e6e6e6;
+  border-color: #adadad;
+}
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+  color: #333;
+  background-color: #d4d4d4;
+  border-color: #8c8c8c;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+  background-image: none;
+}
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus {
+  background-color: #fff;
+  border-color: #ccc;
+}
+.btn-default .badge {
+  color: #fff;
+  background-color: #333;
+}
+.btn-primary {
+  color: #fff;
+  background-color: #337ab7;
+  border-color: #2e6da4;
+}
+.btn-primary:focus,
+.btn-primary.focus {
+  color: #fff;
+  background-color: #286090;
+  border-color: #122b40;
+}
+.btn-primary:hover {
+  color: #fff;
+  background-color: #286090;
+  border-color: #204d74;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+  color: #fff;
+  background-color: #286090;
+  border-color: #204d74;
+}
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+  color: #fff;
+  background-color: #204d74;
+  border-color: #122b40;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+  background-image: none;
+}
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus {
+  background-color: #337ab7;
+  border-color: #2e6da4;
+}
+.btn-primary .badge {
+  color: #337ab7;
+  background-color: #fff;
+}
+.btn-success {
+  color: #fff;
+  background-color: #5cb85c;
+  border-color: #4cae4c;
+}
+.btn-success:focus,
+.btn-success.focus {
+  color: #fff;
+  background-color: #449d44;
+  border-color: #255625;
+}
+.btn-success:hover {
+  color: #fff;
+  background-color: #449d44;
+  border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+  color: #fff;
+  background-color: #449d44;
+  border-color: #398439;
+}
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+  color: #fff;
+  background-color: #398439;
+  border-color: #255625;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+  background-image: none;
+}
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus {
+  background-color: #5cb85c;
+  border-color: #4cae4c;
+}
+.btn-success .badge {
+  color: #5cb85c;
+  background-color: #fff;
+}
+.btn-info {
+  color: #fff;
+  background-color: #5bc0de;
+  border-color: #46b8da;
+}
+.btn-info:focus,
+.btn-info.focus {
+  color: #fff;
+  background-color: #31b0d5;
+  border-color: #1b6d85;
+}
+.btn-info:hover {
+  color: #fff;
+  background-color: #31b0d5;
+  border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+  color: #fff;
+  background-color: #31b0d5;
+  border-color: #269abc;
+}
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+  color: #fff;
+  background-color: #269abc;
+  border-color: #1b6d85;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+  background-image: none;
+}
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus {
+  background-color: #5bc0de;
+  border-color: #46b8da;
+}
+.btn-info .badge {
+  color: #5bc0de;
+  background-color: #fff;
+}
+.btn-warning {
+  color: #fff;
+  background-color: #f0ad4e;
+  border-color: #eea236;
+}
+.btn-warning:focus,
+.btn-warning.focus {
+  color: #fff;
+  background-color: #ec971f;
+  border-color: #985f0d;
+}
+.btn-warning:hover {
+  color: #fff;
+  background-color: #ec971f;
+  border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+  color: #fff;
+  background-color: #ec971f;
+  border-color: #d58512;
+}
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+  color: #fff;
+  background-color: #d58512;
+  border-color: #985f0d;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+  background-image: none;
+}
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus {
+  background-color: #f0ad4e;
+  border-color: #eea236;
+}
+.btn-warning .badge {
+  color: #f0ad4e;
+  background-color: #fff;
+}
+.btn-danger {
+  color: #fff;
+  background-color: #d9534f;
+  border-color: #d43f3a;
+}
+.btn-danger:focus,
+.btn-danger.focus {
+  color: #fff;
+  background-color: #c9302c;
+  border-color: #761c19;
+}
+.btn-danger:hover {
+  color: #fff;
+  background-color: #c9302c;
+  border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+  color: #fff;
+  background-color: #c9302c;
+  border-color: #ac2925;
+}
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+  color: #fff;
+  background-color: #ac2925;
+  border-color: #761c19;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+  background-image: none;
+}
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus {
+  background-color: #d9534f;
+  border-color: #d43f3a;
+}
+.btn-danger .badge {
+  color: #d9534f;
+  background-color: #fff;
+}
+.btn-link {
+  color: #337ab7;
+  font-weight: normal;
+  border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+  background-color: transparent;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+  border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+  color: #23527c;
+  text-decoration: underline;
+  background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+  color: #777777;
+  text-decoration: none;
+}
+.btn-lg {
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.3333333;
+  border-radius: 6px;
+}
+.btn-sm {
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-xs {
+  padding: 1px 5px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-block {
+  display: block;
+  width: 100%;
+}
+.btn-block + .btn-block {
+  margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+  width: 100%;
+}
+.fade {
+  opacity: 0;
+  -webkit-transition: opacity 0.15s linear;
+  -o-transition: opacity 0.15s linear;
+  transition: opacity 0.15s linear;
+}
+.fade.in {
+  opacity: 1;
+}
+.collapse {
+  display: none;
+}
+.collapse.in {
+  display: block;
+}
+tr.collapse.in {
+  display: table-row;
+}
+tbody.collapse.in {
+  display: table-row-group;
+}
+.collapsing {
+  position: relative;
+  height: 0;
+  overflow: hidden;
+  -webkit-transition-property: height, visibility;
+  transition-property: height, visibility;
+  -webkit-transition-duration: 0.35s;
+  transition-duration: 0.35s;
+  -webkit-transition-timing-function: ease;
+  transition-timing-function: ease;
+}
+.caret {
+  display: inline-block;
+  width: 0;
+  height: 0;
+  margin-left: 2px;
+  vertical-align: middle;
+  border-top: 4px dashed;
+  border-top: 4px solid \9;
+  border-right: 4px solid transparent;
+  border-left: 4px solid transparent;
+}
+.dropup,
+.dropdown {
+  position: relative;
+}
+.dropdown-toggle:focus {
+  outline: 0;
+}
+.dropdown-menu {
+  position: absolute;
+  top: 100%;
+  left: 0;
+  z-index: 1000;
+  display: none;
+  float: left;
+  min-width: 160px;
+  padding: 5px 0;
+  margin: 2px 0 0;
+  list-style: none;
+  font-size: 14px;
+  text-align: left;
+  background-color: #fff;
+  border: 1px solid #ccc;
+  border: 1px solid rgba(0, 0, 0, 0.15);
+  border-radius: 4px;
+  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+  background-clip: padding-box;
+}
+.dropdown-menu.pull-right {
+  right: 0;
+  left: auto;
+}
+.dropdown-menu .divider {
+  height: 1px;
+  margin: 9px 0;
+  overflow: hidden;
+  background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+  display: block;
+  padding: 3px 20px;
+  clear: both;
+  font-weight: normal;
+  line-height: 1.42857143;
+  color: #333333;
+  white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+  text-decoration: none;
+  color: #262626;
+  background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+  color: #fff;
+  text-decoration: none;
+  outline: 0;
+  background-color: #337ab7;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+  color: #777777;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+  text-decoration: none;
+  background-color: transparent;
+  background-image: none;
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  cursor: not-allowed;
+}
+.open > .dropdown-menu {
+  display: block;
+}
+.open > a {
+  outline: 0;
+}
+.dropdown-menu-right {
+  left: auto;
+  right: 0;
+}
+.dropdown-menu-left {
+  left: 0;
+  right: auto;
+}
+.dropdown-header {
+  display: block;
+  padding: 3px 20px;
+  font-size: 12px;
+  line-height: 1.42857143;
+  color: #777777;
+  white-space: nowrap;
+}
+.dropdown-backdrop {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 0;
+  z-index: 990;
+}
+.pull-right > .dropdown-menu {
+  right: 0;
+  left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+  border-top: 0;
+  border-bottom: 4px dashed;
+  border-bottom: 4px solid \9;
+  content: "";
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+  top: auto;
+  bottom: 100%;
+  margin-bottom: 2px;
+}
+@media (min-width: 768px) {
+  .navbar-right .dropdown-menu {
+    left: auto;
+    right: 0;
+  }
+  .navbar-right .dropdown-menu-left {
+    left: 0;
+    right: auto;
+  }
+}
+.nav {
+  margin-bottom: 0;
+  padding-left: 0;
+  list-style: none;
+}
+.nav > li {
+  position: relative;
+  display: block;
+}
+.nav > li > a {
+  position: relative;
+  display: block;
+  padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+  text-decoration: none;
+  background-color: #eeeeee;
+}
+.nav > li.disabled > a {
+  color: #777777;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+  color: #777777;
+  text-decoration: none;
+  background-color: transparent;
+  cursor: not-allowed;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+  background-color: #eeeeee;
+  border-color: #337ab7;
+}
+.nav .nav-divider {
+  height: 1px;
+  margin: 9px 0;
+  overflow: hidden;
+  background-color: #e5e5e5;
+}
+.nav > li > a > img {
+  max-width: none;
+}
+.nav-tabs {
+  border-bottom: 1px solid #ddd;
+}
+.nav-tabs > li {
+  float: left;
+  margin-bottom: -1px;
+}
+.nav-tabs > li > a {
+  margin-right: 2px;
+  line-height: 1.42857143;
+  border: 1px solid transparent;
+  border-radius: 4px 4px 0 0;
+}
+.nav-tabs > li > a:hover {
+  border-color: #eeeeee #eeeeee #ddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+  color: #555555;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  border-bottom-color: transparent;
+  cursor: default;
+}
+.nav-tabs.nav-justified {
+  width: 100%;
+  border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+  float: none;
+}
+.nav-tabs.nav-justified > li > a {
+  text-align: center;
+  margin-bottom: 5px;
+}
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+  top: auto;
+  left: auto;
+}
+@media (min-width: 768px) {
+  .nav-tabs.nav-justified > li {
+    display: table-cell;
+    width: 1%;
+  }
+  .nav-tabs.nav-justified > li > a {
+    margin-bottom: 0;
+  }
+}
+.nav-tabs.nav-justified > li > a {
+  margin-right: 0;
+  border-radius: 4px;
+}
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+  border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+  .nav-tabs.nav-justified > li > a {
+    border-bottom: 1px solid #ddd;
+    border-radius: 4px 4px 0 0;
+  }
+  .nav-tabs.nav-justified > .active > a,
+  .nav-tabs.nav-justified > .active > a:hover,
+  .nav-tabs.nav-justified > .active > a:focus {
+    border-bottom-color: #fff;
+  }
+}
+.nav-pills > li {
+  float: left;
+}
+.nav-pills > li > a {
+  border-radius: 4px;
+}
+.nav-pills > li + li {
+  margin-left: 2px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+  color: #fff;
+  background-color: #337ab7;
+}
+.nav-stacked > li {
+  float: none;
+}
+.nav-stacked > li + li {
+  margin-top: 2px;
+  margin-left: 0;
+}
+.nav-justified {
+  width: 100%;
+}
+.nav-justified > li {
+  float: none;
+}
+.nav-justified > li > a {
+  text-align: center;
+  margin-bottom: 5px;
+}
+.nav-justified > .dropdown .dropdown-menu {
+  top: auto;
+  left: auto;
+}
+@media (min-width: 768px) {
+  .nav-justified > li {
+    display: table-cell;
+    width: 1%;
+  }
+  .nav-justified > li > a {
+    margin-bottom: 0;
+  }
+}
+.nav-tabs-justified {
+  border-bottom: 0;
+}
+.nav-tabs-justified > li > a {
+  margin-right: 0;
+  border-radius: 4px;
+}
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+  border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+  .nav-tabs-justified > li > a {
+    border-bottom: 1px solid #ddd;
+    border-radius: 4px 4px 0 0;
+  }
+  .nav-tabs-justified > .active > a,
+  .nav-tabs-justified > .active > a:hover,
+  .nav-tabs-justified > .active > a:focus {
+    border-bottom-color: #fff;
+  }
+}
+.tab-content > .tab-pane {
+  display: none;
+}
+.tab-content > .active {
+  display: block;
+}
+.nav-tabs .dropdown-menu {
+  margin-top: -1px;
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+}
+.navbar {
+  position: relative;
+  min-height: 50px;
+  margin-bottom: 20px;
+  border: 1px solid transparent;
+}
+@media (min-width: 768px) {
+  .navbar {
+    border-radius: 4px;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-header {
+    float: left;
+  }
+}
+.navbar-collapse {
+  overflow-x: visible;
+  padding-right: 15px;
+  padding-left: 15px;
+  border-top: 1px solid transparent;
+  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
+  -webkit-overflow-scrolling: touch;
+}
+.navbar-collapse.in {
+  overflow-y: auto;
+}
+@media (min-width: 768px) {
+  .navbar-collapse {
+    width: auto;
+    border-top: 0;
+    box-shadow: none;
+  }
+  .navbar-collapse.collapse {
+    display: block !important;
+    height: auto !important;
+    padding-bottom: 0;
+    overflow: visible !important;
+  }
+  .navbar-collapse.in {
+    overflow-y: visible;
+  }
+  .navbar-fixed-top .navbar-collapse,
+  .navbar-static-top .navbar-collapse,
+  .navbar-fixed-bottom .navbar-collapse {
+    padding-left: 0;
+    padding-right: 0;
+  }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+  max-height: 340px;
+}
+@media (max-device-width: 480px) and (orientation: landscape) {
+  .navbar-fixed-top .navbar-collapse,
+  .navbar-fixed-bottom .navbar-collapse {
+    max-height: 200px;
+  }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+  margin-right: -15px;
+  margin-left: -15px;
+}
+@media (min-width: 768px) {
+  .container > .navbar-header,
+  .container-fluid > .navbar-header,
+  .container > .navbar-collapse,
+  .container-fluid > .navbar-collapse {
+    margin-right: 0;
+    margin-left: 0;
+  }
+}
+.navbar-static-top {
+  z-index: 1000;
+  border-width: 0 0 1px;
+}
+@media (min-width: 768px) {
+  .navbar-static-top {
+    border-radius: 0;
+  }
+}
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+  position: fixed;
+  right: 0;
+  left: 0;
+  z-index: 1030;
+}
+@media (min-width: 768px) {
+  .navbar-fixed-top,
+  .navbar-fixed-bottom {
+    border-radius: 0;
+  }
+}
+.navbar-fixed-top {
+  top: 0;
+  border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+  bottom: 0;
+  margin-bottom: 0;
+  border-width: 1px 0 0;
+}
+.navbar-brand {
+  float: left;
+  padding: 15px 15px;
+  font-size: 18px;
+  line-height: 20px;
+  height: 50px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+  text-decoration: none;
+}
+.navbar-brand > img {
+  display: block;
+}
+@media (min-width: 768px) {
+  .navbar > .container .navbar-brand,
+  .navbar > .container-fluid .navbar-brand {
+    margin-left: -15px;
+  }
+}
+.navbar-toggle {
+  position: relative;
+  float: right;
+  margin-right: 15px;
+  padding: 9px 10px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-color: transparent;
+  background-image: none;
+  border: 1px solid transparent;
+  border-radius: 4px;
+}
+.navbar-toggle:focus {
+  outline: 0;
+}
+.navbar-toggle .icon-bar {
+  display: block;
+  width: 22px;
+  height: 2px;
+  border-radius: 1px;
+}
+.navbar-toggle .icon-bar + .icon-bar {
+  margin-top: 4px;
+}
+@media (min-width: 768px) {
+  .navbar-toggle {
+    display: none;
+  }
+}
+.navbar-nav {
+  margin: 7.5px -15px;
+}
+.navbar-nav > li > a {
+  padding-top: 10px;
+  padding-bottom: 10px;
+  line-height: 20px;
+}
+@media (max-width: 767px) {
+  .navbar-nav .open .dropdown-menu {
+    position: static;
+    float: none;
+    width: auto;
+    margin-top: 0;
+    background-color: transparent;
+    border: 0;
+    box-shadow: none;
+  }
+  .navbar-nav .open .dropdown-menu > li > a,
+  .navbar-nav .open .dropdown-menu .dropdown-header {
+    padding: 5px 15px 5px 25px;
+  }
+  .navbar-nav .open .dropdown-menu > li > a {
+    line-height: 20px;
+  }
+  .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-nav .open .dropdown-menu > li > a:focus {
+    background-image: none;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-nav {
+    float: left;
+    margin: 0;
+  }
+  .navbar-nav > li {
+    float: left;
+  }
+  .navbar-nav > li > a {
+    padding-top: 15px;
+    padding-bottom: 15px;
+  }
+}
+.navbar-form {
+  margin-left: -15px;
+  margin-right: -15px;
+  padding: 10px 15px;
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+@media (min-width: 768px) {
+  .navbar-form .form-group {
+    display: inline-block;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .form-control {
+    display: inline-block;
+    width: auto;
+    vertical-align: middle;
+  }
+  .navbar-form .form-control-static {
+    display: inline-block;
+  }
+  .navbar-form .input-group {
+    display: inline-table;
+    vertical-align: middle;
+  }
+  .navbar-form .input-group .input-group-addon,
+  .navbar-form .input-group .input-group-btn,
+  .navbar-form .input-group .form-control {
+    width: auto;
+  }
+  .navbar-form .input-group > .form-control {
+    width: 100%;
+  }
+  .navbar-form .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio,
+  .navbar-form .checkbox {
+    display: inline-block;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio label,
+  .navbar-form .checkbox label {
+    padding-left: 0;
+  }
+  .navbar-form .radio input[type="radio"],
+  .navbar-form .checkbox input[type="checkbox"] {
+    position: relative;
+    margin-left: 0;
+  }
+  .navbar-form .has-feedback .form-control-feedback {
+    top: 0;
+  }
+}
+@media (max-width: 767px) {
+  .navbar-form .form-group {
+    margin-bottom: 5px;
+  }
+  .navbar-form .form-group:last-child {
+    margin-bottom: 0;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-form {
+    width: auto;
+    border: 0;
+    margin-left: 0;
+    margin-right: 0;
+    padding-top: 0;
+    padding-bottom: 0;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+  }
+}
+.navbar-nav > li > .dropdown-menu {
+  margin-top: 0;
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+  margin-bottom: 0;
+  border-top-right-radius: 4px;
+  border-top-left-radius: 4px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.navbar-btn {
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.navbar-btn.btn-sm {
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+.navbar-btn.btn-xs {
+  margin-top: 14px;
+  margin-bottom: 14px;
+}
+.navbar-text {
+  margin-top: 15px;
+  margin-bottom: 15px;
+}
+@media (min-width: 768px) {
+  .navbar-text {
+    float: left;
+    margin-left: 15px;
+    margin-right: 15px;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-left {
+    float: left !important;
+  }
+  .navbar-right {
+    float: right !important;
+    margin-right: -15px;
+  }
+  .navbar-right ~ .navbar-right {
+    margin-right: 0;
+  }
+}
+.navbar-default {
+  background-color: #f8f8f8;
+  border-color: #e7e7e7;
+}
+.navbar-default .navbar-brand {
+  color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+  color: #5e5e5e;
+  background-color: transparent;
+}
+.navbar-default .navbar-text {
+  color: #777;
+}
+.navbar-default .navbar-nav > li > a {
+  color: #777;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+  color: #333;
+  background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+  color: #555;
+  background-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+  color: #ccc;
+  background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+  border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+  background-color: #ddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+  background-color: #888;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+  border-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+  background-color: #e7e7e7;
+  color: #555;
+}
+@media (max-width: 767px) {
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+    color: #777;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+    color: #333;
+    background-color: transparent;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #555;
+    background-color: #e7e7e7;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+    color: #ccc;
+    background-color: transparent;
+  }
+}
+.navbar-default .navbar-link {
+  color: #777;
+}
+.navbar-default .navbar-link:hover {
+  color: #333;
+}
+.navbar-default .btn-link {
+  color: #777;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+  color: #333;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+  color: #ccc;
+}
+.navbar-inverse {
+  background-color: #222;
+  border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+  color: #9d9d9d;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+  color: #fff;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+  color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a {
+  color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+  color: #fff;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+  color: #fff;
+  background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+  color: #444;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+  border-color: #333;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+  background-color: #333;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+  background-color: #fff;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+  border-color: #101010;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+  background-color: #080808;
+  color: #fff;
+}
+@media (max-width: 767px) {
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+    border-color: #080808;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+    background-color: #080808;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+    color: #9d9d9d;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+    color: #fff;
+    background-color: transparent;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #fff;
+    background-color: #080808;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+    color: #444;
+    background-color: transparent;
+  }
+}
+.navbar-inverse .navbar-link {
+  color: #9d9d9d;
+}
+.navbar-inverse .navbar-link:hover {
+  color: #fff;
+}
+.navbar-inverse .btn-link {
+  color: #9d9d9d;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+  color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+  color: #444;
+}
+.alert {
+  padding: 15px;
+  margin-bottom: 20px;
+  border: 1px solid transparent;
+  border-radius: 4px;
+}
+.alert h4 {
+  margin-top: 0;
+  color: inherit;
+}
+.alert .alert-link {
+  font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+  margin-bottom: 0;
+}
+.alert > p + p {
+  margin-top: 5px;
+}
+.alert-dismissable,
+.alert-dismissible {
+  padding-right: 35px;
+}
+.alert-dismissable .close,
+.alert-dismissible .close {
+  position: relative;
+  top: -2px;
+  right: -21px;
+  color: inherit;
+}
+.alert-success {
+  background-color: #dff0d8;
+  border-color: #d6e9c6;
+  color: #3c763d;
+}
+.alert-success hr {
+  border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+  color: #2b542c;
+}
+.alert-info {
+  background-color: #d9edf7;
+  border-color: #bce8f1;
+  color: #31708f;
+}
+.alert-info hr {
+  border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+  color: #245269;
+}
+.alert-warning {
+  background-color: #fcf8e3;
+  border-color: #faebcc;
+  color: #8a6d3b;
+}
+.alert-warning hr {
+  border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+  color: #66512c;
+}
+.alert-danger {
+  background-color: #f2dede;
+  border-color: #ebccd1;
+  color: #a94442;
+}
+.alert-danger hr {
+  border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+  color: #843534;
+}
+@-webkit-keyframes progress-bar-stripes {
+  from {
+    background-position: 40px 0;
+  }
+  to {
+    background-position: 0 0;
+  }
+}
+@keyframes progress-bar-stripes {
+  from {
+    background-position: 40px 0;
+  }
+  to {
+    background-position: 0 0;
+  }
+}
+.progress {
+  overflow: hidden;
+  height: 20px;
+  margin-bottom: 20px;
+  background-color: #f5f5f5;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+.progress-bar {
+  float: left;
+  width: 0%;
+  height: 100%;
+  font-size: 12px;
+  line-height: 20px;
+  color: #fff;
+  text-align: center;
+  background-color: #337ab7;
+  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+  -webkit-transition: width 0.6s ease;
+  -o-transition: width 0.6s ease;
+  transition: width 0.6s ease;
+}
+.progress-striped .progress-bar,
+.progress-bar-striped {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-size: 40px 40px;
+}
+.progress.active .progress-bar,
+.progress-bar.active {
+  -webkit-animation: progress-bar-stripes 2s linear infinite;
+  -o-animation: progress-bar-stripes 2s linear infinite;
+  animation: progress-bar-stripes 2s linear infinite;
+}
+.progress-bar-success {
+  background-color: #5cb85c;
+}
+.progress-striped .progress-bar-success {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+  background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+  background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+  background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.media {
+  margin-top: 15px;
+}
+.media:first-child {
+  margin-top: 0;
+}
+.media,
+.media-body {
+  zoom: 1;
+  overflow: hidden;
+}
+.media-body {
+  width: 10000px;
+}
+.media-object {
+  display: block;
+}
+.media-object.img-thumbnail {
+  max-width: none;
+}
+.media-right,
+.media > .pull-right {
+  padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+  padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+  display: table-cell;
+  vertical-align: top;
+}
+.media-middle {
+  vertical-align: middle;
+}
+.media-bottom {
+  vertical-align: bottom;
+}
+.media-heading {
+  margin-top: 0;
+  margin-bottom: 5px;
+}
+.media-list {
+  padding-left: 0;
+  list-style: none;
+}
+.well {
+  min-height: 20px;
+  padding: 19px;
+  margin-bottom: 20px;
+  background-color: #f5f5f5;
+  border: 1px solid #e3e3e3;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+.well blockquote {
+  border-color: #ddd;
+  border-color: rgba(0, 0, 0, 0.15);
+}
+.well-lg {
+  padding: 24px;
+  border-radius: 6px;
+}
+.well-sm {
+  padding: 9px;
+  border-radius: 3px;
+}
+.close {
+  float: right;
+  font-size: 21px;
+  font-weight: bold;
+  line-height: 1;
+  color: #000;
+  text-shadow: 0 1px 0 #fff;
+  opacity: 0.2;
+  filter: alpha(opacity=20);
+}
+.close:hover,
+.close:focus {
+  color: #000;
+  text-decoration: none;
+  cursor: pointer;
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+}
+button.close {
+  padding: 0;
+  cursor: pointer;
+  background: transparent;
+  border: 0;
+  -webkit-appearance: none;
+}
+.modal-open {
+  overflow: hidden;
+}
+.modal {
+  display: none;
+  overflow: hidden;
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1050;
+  -webkit-overflow-scrolling: touch;
+  outline: 0;
+}
+.modal.fade .modal-dialog {
+  -webkit-transform: translate(0, -25%);
+  -ms-transform: translate(0, -25%);
+  -o-transform: translate(0, -25%);
+  transform: translate(0, -25%);
+  -webkit-transition: -webkit-transform 0.3s ease-out;
+  -moz-transition: -moz-transform 0.3s ease-out;
+  -o-transition: -o-transform 0.3s ease-out;
+  transition: transform 0.3s ease-out;
+}
+.modal.in .modal-dialog {
+  -webkit-transform: translate(0, 0);
+  -ms-transform: translate(0, 0);
+  -o-transform: translate(0, 0);
+  transform: translate(0, 0);
+}
+.modal-open .modal {
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.modal-dialog {
+  position: relative;
+  width: auto;
+  margin: 10px;
+}
+.modal-content {
+  position: relative;
+  background-color: #fff;
+  border: 1px solid #999;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  border-radius: 6px;
+  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+  background-clip: padding-box;
+  outline: 0;
+}
+.modal-backdrop {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1040;
+  background-color: #000;
+}
+.modal-backdrop.fade {
+  opacity: 0;
+  filter: alpha(opacity=0);
+}
+.modal-backdrop.in {
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+}
+.modal-header {
+  padding: 15px;
+  border-bottom: 1px solid #e5e5e5;
+}
+.modal-header .close {
+  margin-top: -2px;
+}
+.modal-title {
+  margin: 0;
+  line-height: 1.42857143;
+}
+.modal-body {
+  position: relative;
+  padding: 15px;
+}
+.modal-footer {
+  padding: 15px;
+  text-align: right;
+  border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+  margin-left: 5px;
+  margin-bottom: 0;
+}
+.modal-footer .btn-group .btn + .btn {
+  margin-left: -1px;
+}
+.modal-footer .btn-block + .btn-block {
+  margin-left: 0;
+}
+.modal-scrollbar-measure {
+  position: absolute;
+  top: -9999px;
+  width: 50px;
+  height: 50px;
+  overflow: scroll;
+}
+@media (min-width: 768px) {
+  .modal-dialog {
+    width: 600px;
+    margin: 30px auto;
+  }
+  .modal-content {
+    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+  }
+  .modal-sm {
+    width: 300px;
+  }
+}
+@media (min-width: 992px) {
+  .modal-lg {
+    width: 900px;
+  }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.modal-header:before,
+.modal-header:after,
+.modal-footer:before,
+.modal-footer:after {
+  content: " ";
+  display: table;
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.modal-header:after,
+.modal-footer:after {
+  clear: both;
+}
+.center-block {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+.pull-right {
+  float: right !important;
+}
+.pull-left {
+  float: left !important;
+}
+.hide {
+  display: none !important;
+}
+.show {
+  display: block !important;
+}
+.invisible {
+  visibility: hidden;
+}
+.text-hide {
+  font: 0/0 a;
+  color: transparent;
+  text-shadow: none;
+  background-color: transparent;
+  border: 0;
+}
+.hidden {
+  display: none !important;
+}
+.affix {
+  position: fixed;
+}
+@-ms-viewport {
+  width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+  display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+  display: none !important;
+}
+@media (max-width: 767px) {
+  .visible-xs {
+    display: block !important;
+  }
+  table.visible-xs {
+    display: table !important;
+  }
+  tr.visible-xs {
+    display: table-row !important;
+  }
+  th.visible-xs,
+  td.visible-xs {
+    display: table-cell !important;
+  }
+}
+@media (max-width: 767px) {
+  .visible-xs-block {
+    display: block !important;
+  }
+}
+@media (max-width: 767px) {
+  .visible-xs-inline {
+    display: inline !important;
+  }
+}
+@media (max-width: 767px) {
+  .visible-xs-inline-block {
+    display: inline-block !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm {
+    display: block !important;
+  }
+  table.visible-sm {
+    display: table !important;
+  }
+  tr.visible-sm {
+    display: table-row !important;
+  }
+  th.visible-sm,
+  td.visible-sm {
+    display: table-cell !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm-block {
+    display: block !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm-inline {
+    display: inline !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm-inline-block {
+    display: inline-block !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md {
+    display: block !important;
+  }
+  table.visible-md {
+    display: table !important;
+  }
+  tr.visible-md {
+    display: table-row !important;
+  }
+  th.visible-md,
+  td.visible-md {
+    display: table-cell !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md-block {
+    display: block !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md-inline {
+    display: inline !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md-inline-block {
+    display: inline-block !important;
+  }
+}
+@media (min-width: 1200px) {
+  .visible-lg {
+    display: block !important;
+  }
+  table.visible-lg {
+    display: table !important;
+  }
+  tr.visible-lg {
+    display: table-row !important;
+  }
+  th.visible-lg,
+  td.visible-lg {
+    display: table-cell !important;
+  }
+}
+@media (min-width: 1200px) {
+  .visible-lg-block {
+    display: block !important;
+  }
+}
+@media (min-width: 1200px) {
+  .visible-lg-inline {
+    display: inline !important;
+  }
+}
+@media (min-width: 1200px) {
+  .visible-lg-inline-block {
+    display: inline-block !important;
+  }
+}
+@media (max-width: 767px) {
+  .hidden-xs {
+    display: none !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .hidden-sm {
+    display: none !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .hidden-md {
+    display: none !important;
+  }
+}
+@media (min-width: 1200px) {
+  .hidden-lg {
+    display: none !important;
+  }
+}
+.visible-print {
+  display: none !important;
+}
+@media print {
+  .visible-print {
+    display: block !important;
+  }
+  table.visible-print {
+    display: table !important;
+  }
+  tr.visible-print {
+    display: table-row !important;
+  }
+  th.visible-print,
+  td.visible-print {
+    display: table-cell !important;
+  }
+}
+.visible-print-block {
+  display: none !important;
+}
+@media print {
+  .visible-print-block {
+    display: block !important;
+  }
+}
+.visible-print-inline {
+  display: none !important;
+}
+@media print {
+  .visible-print-inline {
+    display: inline !important;
+  }
+}
+.visible-print-inline-block {
+  display: none !important;
+}
+@media print {
+  .visible-print-inline-block {
+    display: inline-block !important;
+  }
+}
+@media print {
+  .hidden-print {
+    display: none !important;
+  }
+}
+.auth-changed-message {
+  width: 100%;
+  position: fixed;
+  top: 0px;
+  left: 0px;
+  z-index: 1070;
+  transition: top 300ms ease;
+}
+.auth-changed-message > div {
+  position: absolute;
+  bottom: 0px;
+  width: 100%;
+  background-color: #eeeeee;
+  padding: 20px 0px;
+}
+.auth-changed-message.show > div {
+  top: 0px;
+  bottom: auto;
+}
+.auth-changed-message p {
+  padding: 10px 0px;
+  color: #222222;
+  font-size: 18px;
+}
+@media screen and (max-width: 991px) {
+  .auth-changed-message {
+    text-align: center;
+  }
+  .auth-changed-message .btn {
+    padding: 10px 16px;
+    font-size: 18px;
+  }
+}
+.alerts-snackbar {
+  position: fixed;
+  top: -100%;
+  width: 100%;
+  z-index: 1060;
+  text-align: center;
+  font-size: 18px;
+  transition: top 300ms ease;
+  pointer-events: none;
+}
+.alerts-snackbar.in {
+  top: 0px;
+  transition: top 200ms ease;
+}
+.alerts-snackbar p {
+  display: inline-block;
+  border-radius: 0px 0px 4px 4px;
+  margin: 0px;
+  pointer-events: all;
+}
+.loader-compact {
+  width: 100%;
+  height: 49px;
+  text-align: center;
+}
+.loader-spinning-wheel {
+  width: 49px;
+  height: 49px;
+  margin: 0 auto;
+  border: 3px solid #000000;
+  border-radius: 50%;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  animation: cssload-spin 575ms infinite linear;
+  -o-animation: cssload-spin 575ms infinite linear;
+  -ms-animation: cssload-spin 575ms infinite linear;
+  -webkit-animation: cssload-spin 575ms infinite linear;
+  -moz-animation: cssload-spin 575ms infinite linear;
+}
+@keyframes cssload-spin {
+  100% {
+    transform: rotate(360deg);
+  }
+}
+@-o-keyframes cssload-spin {
+  100% {
+    -o-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@-ms-keyframes cssload-spin {
+  100% {
+    -ms-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@-webkit-keyframes cssload-spin {
+  100% {
+    -webkit-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@-moz-keyframes cssload-spin {
+  100% {
+    -moz-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+.navbar {
+  margin-bottom: 0px;
+}
+.navbar .navbar-full .navbar-brand > * {
+  display: inline-block;
+}
+.navbar .navbar-full .navbar-brand img {
+  height: 16px;
+}
+.navbar .navbar-full .nav-guest,
+.navbar .navbar-full .nav-user {
+  float: right;
+}
+.navbar .navbar-full .nav-guest .navbar-btn,
+.navbar .navbar-full .nav-user .navbar-btn {
+  margin-left: 15px;
+}
+.navbar .navbar-full .nav-user .dropdown-toggle {
+  padding: 8px;
+}
+.navbar .navbar-full .nav-user .dropdown-toggle img {
+  width: 34px;
+  height: 34px;
+}
+.navbar ul.navbar-compact-nav {
+  margin: 0px;
+  display: table;
+  width: 100%;
+}
+.navbar ul.navbar-compact-nav > li {
+  display: table-cell;
+}
+.navbar ul.navbar-compact-nav > li > a,
+.navbar ul.navbar-compact-nav > li > button {
+  background: none;
+  border: none;
+  margin: 0px;
+  padding-top: 10px;
+  padding-bottom: 10px;
+  width: 100%;
+  color: #777;
+  text-align: center;
+}
+.navbar ul.navbar-compact-nav > li > a:hover,
+.navbar ul.navbar-compact-nav > li > button:hover,
+.navbar ul.navbar-compact-nav > li > a:focus,
+.navbar ul.navbar-compact-nav > li > button:focus {
+  color: #333;
+  background-color: transparent;
+}
+.navbar ul.navbar-compact-nav > li > a > img,
+.navbar ul.navbar-compact-nav > li > button > img {
+  width: 24px;
+  height: 24px;
+}
+.navbar ul.navbar-compact-nav > li > button {
+  padding-top: 10px;
+  padding-bottom: 10px;
+}
+.navbar ul.navbar-compact-nav > li > a > .material-icon {
+  font-size: 24px;
+  line-height: 24px;
+}
+@media (max-width: 767px) {
+  .navbar.navbar-misago {
+    min-height: auto;
+  }
+}
+@font-face {
+  font-family: 'Material Icons';
+  font-style: normal;
+  font-weight: 400;
+  src: url(../fonts/MaterialIcons-Regular.eot);
+  /* For IE6-8 */
+  src: local('Material Icons'), local('MaterialIcons-Regular'), url(../fonts/MaterialIcons-Regular.woff2) format('woff2'), url(../fonts/MaterialIcons-Regular.woff) format('woff'), url(../fonts/MaterialIcons-Regular.ttf) format('truetype');
+}
+.material-icon {
+  font-family: 'Material Icons';
+  font-weight: normal;
+  font-style: normal;
+  display: inline-block;
+  width: 1em;
+  height: 1em;
+  line-height: 1;
+  text-align: center;
+  text-transform: none;
+  letter-spacing: normal;
+  vertical-align: middle;
+  /* Support for all WebKit browsers. */
+  -webkit-font-smoothing: antialiased;
+  /* Support for Safari and Chrome. */
+  text-rendering: optimizeLegibility;
+  /* Support for Firefox. */
+  -moz-osx-font-smoothing: grayscale;
+  /* Support for IE. */
+  font-feature-settings: 'liga';
+}
+@media screen and (max-width: 991px) {
+  .modal-message {
+    text-align: center;
+  }
+  .modal-message .message-icon {
+    margin: 30px;
+  }
+  .modal-message .message-icon .material-icon {
+    font-size: 160px;
+  }
+}
+@media screen and (min-width: 992px) {
+  .modal-message .message-icon {
+    float: left;
+  }
+  .modal-message .message-icon .material-icon {
+    font-size: 80px;
+  }
+  .modal-message .message-body {
+    margin-left: 100px;
+  }
+}
+@media screen and (max-width: 991px) {
+  .modal-register .modal-footer {
+    text-align: center;
+  }
+  .modal-register .modal-footer a {
+    display: block;
+  }
+  .modal-register .modal-footer .btn {
+    display: block;
+    float: none;
+    margin-top: 10px;
+    width: 100%;
+  }
+}
+.material-icon.form-control-feedback {
+  top: 6px;
+  right: 24px;
+  font-size: 1.42857143;
+  line-height: 1.42857143;
+}
+.well.well-form.well-done {
+  font-size: 18px;
+  text-align: center;
+}
+.well.well-form.well-done .message-icon {
+  margin-bottom: 10px;
+  font-size: 90px;
+  line-height: 90px;
+}
+.well.well-form.well-done .message-body {
+  margin-bottom: 6.66666667px;
+}
+.well.well-form.well-noscript {
+  font-size: 18px;
+  text-align: center;
+}
+.well.well-form.well-noscript .message-icon {
+  margin-bottom: 10px;
+  font-size: 90px;
+  line-height: 90px;
+}
+.btn.btn-loading,
+.btn.btn-loading:link,
+.btn.btn-loading:active,
+.btn.btn-loading:visited,
+.btn.btn-loading:hover,
+.btn.btn-loading:focus {
+  color: transparent;
+}
+.btn.btn-loading .loader-compact,
+.btn.btn-loading:link .loader-compact,
+.btn.btn-loading:active .loader-compact,
+.btn.btn-loading:visited .loader-compact,
+.btn.btn-loading:hover .loader-compact,
+.btn.btn-loading:focus .loader-compact {
+  height: 20px;
+}
+.btn.btn-loading .loader-compact > div,
+.btn.btn-loading:link .loader-compact > div,
+.btn.btn-loading:active .loader-compact > div,
+.btn.btn-loading:visited .loader-compact > div,
+.btn.btn-loading:hover .loader-compact > div,
+.btn.btn-loading:focus .loader-compact > div {
+  width: 20px;
+  height: 20px;
+}
+.btn.btn-loading.btn-default .loader-compact > div {
+  border-top-color: #333;
+  border-bottom-color: #333;
+}
+.btn.btn-loading.btn-primary .loader-compact > div {
+  border-top-color: #fff;
+  border-bottom-color: #fff;
+}
+.btn.btn-loading.btn-success .loader-compact > div {
+  border-top-color: #fff;
+  border-bottom-color: #fff;
+}
+.btn.btn-loading.btn-info .loader-compact > div {
+  border-top-color: #fff;
+  border-bottom-color: #fff;
+}
+.btn.btn-loading.btn-warning .loader-compact > div {
+  border-top-color: #fff;
+  border-bottom-color: #fff;
+}
+.btn.btn-loading.btn-danger .loader-compact > div {
+  border-top-color: #fff;
+  border-bottom-color: #fff;
+}
+.dropdown-menu > li > a,
+.dropdown-menu > li > .btn-link {
+  display: block;
+  border: none;
+  clear: both;
+  float: none;
+  padding: 4px 20px;
+  width: 100%;
+  color: #333333;
+  font-weight: normal;
+  line-height: 1.42857143;
+  text-align: left;
+  white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > .btn-link:hover,
+.dropdown-menu > li > a:focus,
+.dropdown-menu > li > .btn-link:focus {
+  background-color: #f5f5f5;
+  color: #262626;
+  text-decoration: none;
+}
+.dropdown-menu > li > a .material-icon,
+.dropdown-menu > li > .btn-link .material-icon {
+  margin: -2px 0px;
+  margin-right: 7px;
+  position: relative;
+  bottom: 1px;
+  font-size: 18px;
+}
+.dropdown-menu .dropdown-footer {
+  padding: 6px 20px;
+}
+.mobile-dropdown {
+  position: static;
+  margin: 0px;
+}
+.mobile-dropdown.open > .dropdown-menu {
+  border: none;
+  border-radius: 0;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+  display: block;
+  margin: 0px;
+  width: 100%;
+  position: static;
+}
+.user-dropdown .guest-preview {
+  text-align: center;
+}
+.user-dropdown .guest-preview .row {
+  margin: 0px;
+}
+.navbar .user-dropdown {
+  width: 240px;
+}
+.user-dropdown .dropdown-header {
+  padding: 6px 20px;
+  font-size: 18px;
+}
+.user-dropdown .dropdown-header strong {
+  font-weight: normal;
+}
+.misago-footer {
+  margin-top: 30px;
+  margin-bottom: 50px;
+}
+.misago-footer .footer-content {
+  border-top: 1px solid #eeeeee;
+  padding-top: 30px;
+}
+.misago-footer .noscript-message .material-icon {
+  position: relative;
+  bottom: 1px;
+  font-size: 18px;
+}
+@media screen and (max-width: 991px) {
+  .page-message,
+  .page-error {
+    text-align: center;
+  }
+  .page-message .message-icon,
+  .page-error .message-icon {
+    margin: 30px;
+  }
+  .page-message .message-icon .material-icon,
+  .page-error .message-icon .material-icon {
+    font-size: 160px;
+  }
+}
+@media screen and (min-width: 992px) {
+  .page-message .message-panel,
+  .page-error .message-panel {
+    margin: 60px auto;
+    max-width: 779.35px;
+    overflow: auto;
+  }
+  .page-message .message-icon,
+  .page-error .message-icon {
+    float: left;
+  }
+  .page-message .message-icon .material-icon,
+  .page-error .message-icon .material-icon {
+    font-size: 80px;
+  }
+  .page-message .message-body,
+  .page-error .message-body {
+    margin-left: 100px;
+  }
+}

BIN
misago/static/misago/img/site-icon.png


BIN
misago/static/misago/img/site-logo.png


+ 2466 - 2
misago/static/misago/js/misago.js

@@ -1,2 +1,2466 @@
-!function e(t,n,r){function o(u,i){if(!n[u]){if(!t[u]){var l="function"==typeof require&&require;if(!i&&l)return l(u,!0);if(a)return a(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var c=n[u]={exports:{}};t[u][0].call(c.exports,function(e){var n=t[u][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[u].exports}for(var a="function"==typeof require&&require,u=0;u<r.length;u++)o(r[u]);return o}({1:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0});var l=e("react"),s=r(l),c=e("./loader"),f=r(c),d=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),i(t,[{key:"render",value:function(){var e=null;e=this.props.loading?s["default"].createElement(f["default"],null):this.props.children;var t="btn "+this.props.className;return s["default"].createElement("button",{type:this.props.type,className:t,disabled:this.props.disabled,onClick:this.props.onClick},e)}}]),t}(s["default"].Component);n["default"]=d,d.defaultProps={className:"btn-default",type:"submit",loading:!1,disabled:!1,onClick:null}},{"./loader":2,react:"react"}],2:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0});var l=e("react"),s=r(l),c=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),i(t,[{key:"render",value:function(){return s["default"].createElement("div",{className:"loader-compact"},s["default"].createElement("div",{className:"bounce1"}),s["default"].createElement("div",{className:"bounce2"}),s["default"].createElement("div",{className:"bounce3"}))}}]),t}(s["default"].Component);n["default"]=c},{react:"react"}],3:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(n,"__esModule",{value:!0});var i=e("./button"),l=r(i),s=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),t}(l["default"]);n["default"]=s},{"./button":1}],4:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0});var l=e("react"),s=r(l),c=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),i(t,[{key:"render",value:function(){return s["default"].createElement("div",{className:"modal-dialog"},s["default"].createElement("div",{className:"modal-content"},s["default"].createElement("div",{className:"modal-header"},s["default"].createElement("button",{type:"button",className:"close","data-dismiss":"modal","aria-label":"Close"},s["default"].createElement("span",{"aria-hidden":"true"},"×")),s["default"].createElement("h4",{className:"modal-title"},gettext("Register"))),s["default"].createElement("div",{className:"modal-body"},s["default"].createElement("p",null,"This will be registration form!")),s["default"].createElement("div",{className:"modal-footer"},s["default"].createElement("button",{type:"button",className:"btn btn-default","data-dismiss":"modal"},"Close"))))}}]),t}(s["default"].Component);n["default"]=c},{react:"react"}],5:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0});var l=e("react"),s=r(l),c=e("../../services/snackbar"),f=r(c),d=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),i(t,[{key:"info",value:function(){f["default"].info("Lorem ipsum dolor met")}},{key:"success",value:function(){f["default"].success("Lorem ipsum dolor met")}},{key:"warning",value:function(){f["default"].warning("Lorem ipsum dolor met")}},{key:"error",value:function(){f["default"].error("Lorem ipsum dolor met")}},{key:"render",value:function(){return s["default"].createElement("div",{className:"modal-dialog"},s["default"].createElement("div",{className:"modal-content"},s["default"].createElement("div",{className:"modal-header"},s["default"].createElement("button",{type:"button",className:"close","data-dismiss":"modal","aria-label":"Close"},s["default"].createElement("span",{"aria-hidden":"true"},"×")),s["default"].createElement("h4",{className:"modal-title"},gettext("Sign in"))),s["default"].createElement("div",{className:"modal-body"},s["default"].createElement("p",null,"This will be sign in form!"),s["default"].createElement("button",{type:"button",className:"btn btn-primary",onClick:this.info},"Test info alert"),s["default"].createElement("br",null),s["default"].createElement("button",{type:"button",className:"btn btn-success",onClick:this.success},"Test success alert"),s["default"].createElement("br",null),s["default"].createElement("button",{type:"button",className:"btn btn-warning",onClick:this.warning},"Test warning alert"),s["default"].createElement("br",null),s["default"].createElement("button",{type:"button",className:"btn btn-danger",onClick:this.error},"Test error alert")),s["default"].createElement("div",{className:"modal-footer"},s["default"].createElement("button",{type:"button",className:"btn btn-default","data-dismiss":"modal"},"Close"))))}}]),t}(s["default"].Component);n["default"]=d},{"../../services/snackbar":21,react:"react"}],6:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function i(e){return e.snackbar}var l=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0}),n.Snackbar=void 0,n.select=i;var s=e("react"),c=r(s),f={info:"alert-info",success:"alert-success",warning:"alert-warning",error:"alert-danger"};n.Snackbar=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),l(t,[{key:"render",value:function(){var e="alert "+f[this.props.type],t="alerts-snackbar";return t+=this.props.isVisible?" in":" out",c["default"].createElement("div",{className:t},c["default"].createElement("p",{className:e},this.props.message))}}]),t}(c["default"].Component)},{react:"react"}],7:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0});var l=e("react"),s=r(l),c=e("../button"),f=r(c),d=e("../../services/modal"),p=r(d),b=e("../sign-in/root.js"),m=r(b),y=e("../register/root.js"),h=r(y),v=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),i(t,[{key:"showSignInModal",value:function(){p["default"].show(m["default"])}},{key:"showRegisterModal",value:function(){p["default"].show(h["default"])}},{key:"render",value:function(){return s["default"].createElement("div",{className:"nav nav-guest"},s["default"].createElement(f["default"],{type:"button",className:"navbar-btn btn-default",onClick:this.showSignInModal},"Sign in"),s["default"].createElement(f["default"],{type:"button",className:"navbar-btn btn-primary",onClick:this.showRegisterModal},"Register"))}}]),t}(s["default"].Component);n["default"]=v},{"../../services/modal":20,"../button":1,"../register/root.js":4,"../sign-in/root.js":5,react:"react"}],8:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function i(e){return e.auth}var l=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0}),n.UserMenu=void 0,n.select=i;var s=e("react"),c=r(s),f=e("./guest-nav"),d=r(f),p=e("./user-nav"),b=r(p);n.UserMenu=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),l(t,[{key:"render",value:function(){return this.props.isAuthenticated?c["default"].createElement(b["default"],{user:this.props.user}):c["default"].createElement(d["default"],null)}}]),t}(c["default"].Component)},{"./guest-nav":7,"./user-nav":9,react:"react"}],9:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0});var l=e("react"),s=r(l),c=function(e){function t(){return o(this,t),a(this,Object.getPrototypeOf(t).apply(this,arguments))}return u(t,e),i(t,[{key:"render",value:function(){return s["default"].createElement("ul",{"class":"ul nav navbar-nav nav-user"})}}]),t}(s["default"].Component);n["default"]=c},{react:"react"}],10:[function(e,t,n){(function(t){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0}),n.Misago=void 0;var u=e("./utils/ordered-list"),i=r(u),l=n.Misago=function(){function e(){o(this,e),this._initializers=[],this._context={}}return a(e,[{key:"addInitializer",value:function(e){this._initializers.push({key:e.name,item:e.initializer,after:e.after,before:e.before})}},{key:"init",value:function(e){var t=this;this._context=e;var n=new i["default"](this._initializers).orderedValues();n.forEach(function(e){e(t)})}},{key:"has",value:function(e){return this._context.hasOwnProperty(e)}},{key:"get",value:function(e,t){return this.has(e)?this._context[e]:t||void 0}}]),e}(),s=new l;t.misago=s,n["default"]=s}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./utils/ordered-list":24}],11:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e){c["default"].addReducer("auth",l["default"],{isAuthenticated:e.get("isAuthenticated"),isAnonymous:!e.get("isAuthenticated"),user:e.get("user")})}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=o;var a=e("../index"),u=r(a),i=e("../reducers/auth"),l=r(i),s=e("../services/store"),c=r(s);u["default"].addInitializer({name:"reducer:auth",initializer:o,before:"store"})},{"../index":10,"../reducers/auth":18,"../services/store":22}],12:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(){var e=document.getElementById("modal-mount");e&&l["default"].init(e)}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=o;var a=e("../index"),u=r(a),i=e("../services/modal"),l=r(i);u["default"].addInitializer({name:"modal",initializer:o,before:"store"})},{"../index":10,"../services/modal":20}],13:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(){(0,c["default"])((0,a.connect)(l.select)(l.Snackbar),"snackbar-mount")}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=o;var a=e("react-redux"),u=e("../index"),i=r(u),l=e("../components/snackbar"),s=e("../utils/mount-component"),c=r(s);i["default"].addInitializer({name:"component:snackbar",initializer:o,after:"snackbar"})},{"../components/snackbar":6,"../index":10,"../utils/mount-component":23,"react-redux":"react-redux"}],14:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(){c["default"].addReducer("snackbar",l["default"],i.initialState)}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=o;var a=e("../index"),u=r(a),i=e("../reducers/snackbar"),l=r(i),s=e("../services/store"),c=r(s);u["default"].addInitializer({name:"reducer:snackbar",initializer:o,before:"store"})},{"../index":10,"../reducers/snackbar":19,"../services/store":22}],15:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(){l["default"].init(c["default"])}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=o;var a=e("../index"),u=r(a),i=e("../services/snackbar"),l=r(i),s=e("../services/store"),c=r(s);u["default"].addInitializer({name:"snackbar",initializer:o,after:"store"})},{"../index":10,"../services/snackbar":21,"../services/store":22}],16:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(){l["default"].init()}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=o;var a=e("../index"),u=r(a),i=e("../services/store"),l=r(i);u["default"].addInitializer({name:"store",initializer:o,before:"_end"})},{"../index":10,"../services/store":22}],17:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(){(0,c["default"])((0,a.connect)(l.select)(l.UserMenu),"user-menu-mount")}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=o;var a=e("react-redux"),u=e("../index"),i=r(u),l=e("../components/user-menu/root"),s=e("../utils/mount-component"),c=r(s);i["default"].addInitializer({name:"component:user-menu",initializer:o,after:"store"})},{"../components/user-menu/root":8,"../index":10,"../utils/mount-component":23,"react-redux":"react-redux"}],18:[function(e,t,n){"use strict";function r(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];arguments.length<=1||void 0===arguments[1]?null:arguments[1];return e}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=r},{}],19:[function(e,t,n){"use strict";function r(e,t){return{type:i,message:e,messageType:t}}function o(){return{type:l}}function a(){var e=arguments.length<=0||void 0===arguments[0]?u:arguments[0],t=arguments.length<=1||void 0===arguments[1]?null:arguments[1];return t.type===i?{type:t.messageType,message:t.message,isVisible:!0}:t.type===l?Object.assign({},e,{isVisible:!1}):e}Object.defineProperty(n,"__esModule",{value:!0}),n.showSnackbar=r,n.hideSnackbar=o,n["default"]=a;var u=n.initialState={type:"info",message:"",isVisible:!1},i=n.SHOW_SNACKBAR="SHOW_SNACKBAR",l=n.HIDE_SNACKBAR="HIDE_SNACKBAR"},{}],20:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0}),n.Modal=void 0;var u=e("react-dom"),i=r(u),l=e("../utils/mount-component"),s=r(l),c=n.Modal=function(){function e(){o(this,e)}return a(e,[{key:"init",value:function(e){var t=this;this._element=e,this._modal=$(e).modal({show:!1}),this._modal.on("hidden.bs.modal",function(){i["default"].unmountComponentAtNode(t._element)})}},{key:"show",value:function(e){(0,s["default"])(e,this._element.id),this._modal.modal("show")}},{key:"hide",value:function(){this._modal.modal("hide")}}]),e}();n["default"]=new c},{"../utils/mount-component":23,"react-dom":"react-dom"}],21:[function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0}),n.Snackbar=void 0;var a=e("../reducers/snackbar"),u=300,i=5e3,l=n.Snackbar=function(){function e(){r(this,e)}return o(e,[{key:"init",value:function(e){this._store=e,this._timeout=null}},{key:"alert",value:function(e,t){var n=this;this._timeout?(window.clearTimeout(this._timeout),this._store.dispatch((0,a.hideSnackbar)()),this._timeout=window.setTimeout(function(){n._timeout=null,n.alert(e,t)},u)):(this._store.dispatch((0,a.showSnackbar)(e,t)),this._timeout=window.setTimeout(function(){n._store.dispatch((0,a.hideSnackbar)()),n._timeout=null},i))}},{key:"info",value:function(e){this.alert(e,"info")}},{key:"success",value:function(e){this.alert(e,"success")}},{key:"warning",value:function(e){this.alert(e,"warning")}},{key:"error",value:function(e){this.alert(e,"error")}}]),e}();n["default"]=new l},{"../reducers/snackbar":19}],22:[function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0}),n.StoreWrapper=void 0;var a=e("redux"),u=n.StoreWrapper=function(){function e(){r(this,e),this._store=null,this._reducers={},this._initialState={}}return o(e,[{key:"addReducer",value:function(e,t,n){this._reducers[e]=t,this._initialState[e]=n}},{key:"init",value:function(){this._store=(0,a.createStore)((0,a.combineReducers)(this._reducers),this._initialState)}},{key:"getStore",value:function(){return this._store}},{key:"getState",value:function(){return this._store.getState()}},{key:"dispatch",value:function(e){return this._store.dispatch(e)}}]),e}();n["default"]=new u},{redux:"redux"}],23:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){var n=arguments.length<=2||void 0===arguments[2]?!0:arguments[2],r=document.getElementById(t);r&&(n?l["default"].render(u["default"].createElement(s.Provider,{store:f["default"].getStore()},u["default"].createElement(e,null)),r):l["default"].render(u["default"].createElement(e,null),r))}Object.defineProperty(n,"__esModule",{value:!0}),n["default"]=o;var a=e("react"),u=r(a),i=e("react-dom"),l=r(i),s=e("react-redux"),c=e("../services/store"),f=r(c)},{"../services/store":22,react:"react","react-dom":"react-dom","react-redux":"react-redux"}],24:[function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function e(t){r(this,e),this.isOrdered=!1,this._items=t||[]}return o(e,[{key:"add",value:function(e,t,n){this._items.push({key:e,item:t,after:n?n.after||null:null,before:n?n.before||null:null})}},{key:"get",value:function(e,t){for(var n=0;n<this._items.length;n++)if(this._items[n].key===e)return this._items[n].item;return t}},{key:"has",value:function(e){return void 0!==this.get(e)}},{key:"values",value:function t(){for(var t=[],e=0;e<this._items.length;e++)t.push(this._items[e].item);return t}},{key:"order",value:function(e){return this.isOrdered||(this._items=this._order(this._items),this.isOrdered=!0),e||"undefined"==typeof e?this.values():this._items}},{key:"orderedValues",value:function(){return this.order(!0)}},{key:"_order",value:function(e){function t(e){var t=-1;-1===o.indexOf(e.key)&&(e.after?(t=o.indexOf(e.after),-1!==t&&(t+=1)):e.before&&(t=o.indexOf(e.before)),-1!==t&&(r.splice(t,0,e),o.splice(t,0,e.key)))}var n=[];e.forEach(function(e){n.push(e.key)});var r=[],o=[];e.forEach(function(e){e.after||e.before||(r.push(e),o.push(e.key))}),e.forEach(function(e){"_end"===e.before&&(r.push(e),o.push(e.key))});for(var a=200;a>0&&n.length!==o.length;)a-=1,e.forEach(t);return r}}]),e}();n["default"]=a},{}]},{},[10,11,12,13,14,15,16,17,1,2,3,6,4,5,8]);
-//# sourceMappingURL=misago.js.map
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var BASE_URL = $('base').attr('href') + 'user-avatar/';
+
+var _class = (function (_React$Component) {
+  _inherits(_class, _React$Component);
+
+  function _class() {
+    _classCallCheck(this, _class);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(_class).apply(this, arguments));
+  }
+
+  _createClass(_class, [{
+    key: 'getSrc',
+    value: function getSrc() {
+      var size = this.props.size || 100; // jshint ignore:line
+      var url = BASE_URL;
+
+      if (this.props.user && this.props.user.id) {
+        // just avatar hash, size and user id
+        url += this.props.user.avatar_hash + '/' + size + '/' + this.props.user.id + '.png';
+      } else {
+        // just append avatar size to file to produce no-avatar placeholder
+        url += size + '.png';
+      }
+
+      return url;
+    }
+  }, {
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement('img', { src: this.getSrc(),
+        className: this.props.className || 'user-avatar',
+        title: gettext("User avatar") });
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return _class;
+})(_react2.default.Component);
+
+exports.default = _class;
+
+},{"react":"react"}],2:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _moment = require('moment');
+
+var _moment2 = _interopRequireDefault(_moment);
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var _class = (function (_React$Component) {
+  _inherits(_class, _React$Component);
+
+  function _class() {
+    _classCallCheck(this, _class);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(_class).apply(this, arguments));
+  }
+
+  _createClass(_class, [{
+    key: 'getReasonMessage',
+    value: function getReasonMessage() {
+      /* jshint ignore:start */
+      if (this.props.message.html) {
+        return _react2.default.createElement('div', { className: 'lead',
+          dangerouslySetInnerHTML: { __html: this.props.message.html } });
+      } else {
+        return _react2.default.createElement(
+          'p',
+          { className: 'lead' },
+          this.props.message.plain
+        );
+      }
+      /* jshint ignore:end */
+    }
+  }, {
+    key: 'getExpirationMessage',
+    value: function getExpirationMessage() {
+      if (this.props.expires) {
+        if (this.props.expires.isAfter((0, _moment2.default)())) {
+          return interpolate(gettext('This ban expires %(expires_on)s.'), { 'expires_on': this.props.expires.fromNow() }, true);
+        } else {
+          return gettext('This ban has expired.');
+        }
+      } else {
+        return gettext('This ban is permanent.');
+      }
+    }
+  }, {
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        'div',
+        { className: 'page page-error page-error-baned' },
+        _react2.default.createElement(
+          'div',
+          { className: 'container' },
+          _react2.default.createElement(
+            'div',
+            { className: 'message-panel' },
+            _react2.default.createElement(
+              'div',
+              { className: 'message-icon' },
+              _react2.default.createElement(
+                'span',
+                { className: 'material-icon' },
+                'highlight_off'
+              )
+            ),
+            _react2.default.createElement(
+              'div',
+              { className: 'message-body' },
+              this.getReasonMessage(),
+              _react2.default.createElement(
+                'p',
+                null,
+                this.getExpirationMessage()
+              )
+            )
+          )
+        )
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return _class;
+})(_react2.default.Component);
+
+exports.default = _class;
+
+},{"moment":"moment","react":"react"}],3:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _loader = require('./loader');
+
+var _loader2 = _interopRequireDefault(_loader);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+// jshint ignore:line
+
+var Button = (function (_React$Component) {
+  _inherits(Button, _React$Component);
+
+  function Button() {
+    _classCallCheck(this, Button);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(Button).apply(this, arguments));
+  }
+
+  _createClass(Button, [{
+    key: 'render',
+    value: function render() {
+      var content = null;
+      var className = 'btn ' + this.props.className;
+      var disabled = this.props.disabled;
+
+      if (this.props.loading) {
+        /* jshint ignore:start */
+        content = _react2.default.createElement(_loader2.default, null);
+        /* jshint ignore:end */
+        className += ' btn-loading';
+        disabled = true;
+      } else {
+        content = this.props.children;
+      }
+
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        'button',
+        { type: this.props.onClick ? 'button' : 'submit',
+          className: className,
+          disabled: disabled,
+          onClick: this.props.onClick },
+        content
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return Button;
+})(_react2.default.Component);
+
+exports.default = Button;
+
+Button.defaultProps = {
+  className: "btn-default",
+
+  type: "submit",
+
+  loading: false,
+  disabled: false,
+
+  onClick: null
+};
+
+},{"./loader":5,"react":"react"}],4:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _validators = require('../utils/validators');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var _class = (function (_React$Component) {
+  _inherits(_class, _React$Component);
+
+  function _class() {
+    var _Object$getPrototypeO;
+
+    var _temp, _this, _ret;
+
+    _classCallCheck(this, _class);
+
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
+
+    return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(_class)).call.apply(_Object$getPrototypeO, [this].concat(args))), _this), _this.bindInput = function (name) {
+      return function (event) {
+        var newState = {};
+        newState[name] = event.target.value;
+        _this.setState(newState);
+      };
+    }, _this.handleSubmit = function (event) {
+      // we don't reload page on submissions
+      event.preventDefault();
+
+      if (_this.state.isLoading) {
+        return;
+      }
+
+      if (_this.clean()) {
+        _this.setState({ 'isLoading': true });
+        var promise = _this.send();
+
+        if (promise) {
+          promise.then(function (success) {
+            _this.handleSuccess(success);
+            _this.setState({ 'isLoading': false });
+          }, function (rejection) {
+            _this.handleError(rejection);
+            _this.setState({ 'isLoading': false });
+          });
+        } else {
+          _this.setState({ 'isLoading': false });
+        }
+      }
+    }, _temp), _possibleConstructorReturn(_this, _ret);
+  }
+
+  _createClass(_class, [{
+    key: 'validate',
+    value: function validate() {
+      var isValid = true;
+      var errors = {};
+
+      for (var key in this.state.validators) {
+        if (this.state.validators.hasOwnProperty(key)) {
+          var value = this.state[key];
+          errors[key] = this.validateField(value, this.state.validators[key]);
+          if (errors[key] !== null) {
+            isValid = false;
+          }
+        }
+      }
+
+      return isValid ? null : errors;
+    }
+  }, {
+    key: 'validateField',
+    value: function validateField(value, validators) {
+      var result = (0, _validators.required)()(value);
+      var errors = [];
+
+      if (result) {
+        return [result];
+      } else {
+        for (var i in validators) {
+          result = validators[i](value);
+          if (result) {
+            errors.push(result);
+          }
+        }
+      }
+
+      return errors.length ? errors : null;
+    }
+  }, {
+    key: 'changeValue',
+    value: function changeValue(name, value) {
+      var errors = null;
+      if (this.state.validators.name) {
+        errors = this.validateField(name, value);
+      }
+    }
+
+    /* jshint ignore:start */
+
+  }, {
+    key: 'clean',
+    value: function clean() {
+      return true;
+    }
+  }, {
+    key: 'send',
+    value: function send() {
+      return null;
+    }
+  }, {
+    key: 'handleSuccess',
+    value: function handleSuccess(success) {
+      return;
+    }
+  }, {
+    key: 'handleError',
+
+    /* jshint ignore:end */
+    value: function handleError(rejection) {
+      return;
+    }
+  }]);
+
+  return _class;
+})(_react2.default.Component);
+
+exports.default = _class;
+
+},{"../utils/validators":36,"react":"react"}],5:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _react = require("react");
+
+var _react2 = _interopRequireDefault(_react);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var _class = (function (_React$Component) {
+  _inherits(_class, _React$Component);
+
+  function _class() {
+    _classCallCheck(this, _class);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(_class).apply(this, arguments));
+  }
+
+  _createClass(_class, [{
+    key: "render",
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        "div",
+        { className: "loader-compact" },
+        _react2.default.createElement("div", { className: "loader-spinning-wheel" })
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return _class;
+})(_react2.default.Component);
+
+exports.default = _class;
+
+},{"react":"react"}],6:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _react = require("react");
+
+var _react2 = _interopRequireDefault(_react);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var _class = (function (_React$Component) {
+  _inherits(_class, _React$Component);
+
+  function _class() {
+    _classCallCheck(this, _class);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(_class).apply(this, arguments));
+  }
+
+  _createClass(_class, [{
+    key: "render",
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        "div",
+        { className: "modal-dialog modal-register" },
+        _react2.default.createElement(
+          "div",
+          { className: "modal-content" },
+          _react2.default.createElement(
+            "div",
+            { className: "modal-header" },
+            _react2.default.createElement(
+              "button",
+              { type: "button", className: "close", "data-dismiss": "modal", "aria-label": "Close" },
+              _react2.default.createElement(
+                "span",
+                { "aria-hidden": "true" },
+                "×"
+              )
+            ),
+            _react2.default.createElement(
+              "h4",
+              { className: "modal-title" },
+              gettext("Register")
+            )
+          ),
+          _react2.default.createElement(
+            "div",
+            { className: "modal-body" },
+            _react2.default.createElement(
+              "p",
+              null,
+              "This will be registration form!"
+            )
+          ),
+          _react2.default.createElement(
+            "div",
+            { className: "modal-footer" },
+            _react2.default.createElement(
+              "button",
+              { type: "button", className: "btn btn-default", "data-dismiss": "modal" },
+              "Close"
+            )
+          )
+        )
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return _class;
+})(_react2.default.Component);
+
+exports.default = _class;
+
+},{"react":"react"}],7:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _button = require('./button');
+
+var _button2 = _interopRequireDefault(_button);
+
+var _form = require('./form');
+
+var _form2 = _interopRequireDefault(_form);
+
+var _ajax = require('../services/ajax');
+
+var _ajax2 = _interopRequireDefault(_ajax);
+
+var _modal = require('../services/modal');
+
+var _modal2 = _interopRequireDefault(_modal);
+
+var _snackbar = require('../services/snackbar');
+
+var _snackbar2 = _interopRequireDefault(_snackbar);
+
+var _bannedPage = require('../utils/banned-page');
+
+var _bannedPage2 = _interopRequireDefault(_bannedPage);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // jshint ignore:line
+// jshint ignore:line
+
+var _class = (function (_Form) {
+  _inherits(_class, _Form);
+
+  function _class(props) {
+    _classCallCheck(this, _class);
+
+    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(_class).call(this, props));
+
+    _this.state = {
+      'isLoading': false,
+      'showActivation': false,
+
+      'username': '',
+      'password': '',
+
+      validators: {
+        'username': [],
+        'password': []
+      }
+    };
+    return _this;
+  }
+
+  _createClass(_class, [{
+    key: 'clean',
+    value: function clean() {
+      if (this.validate()) {
+        _snackbar2.default.error(gettext("Fill out both fields."));
+        return false;
+      } else {
+        return true;
+      }
+    }
+  }, {
+    key: 'send',
+    value: function send() {
+      return _ajax2.default.post(_index2.default.get('AUTH_API'), {
+        'username': this.state.username,
+        'password': this.state.password
+      });
+    }
+  }, {
+    key: 'handleSuccess',
+    value: function handleSuccess() {
+      _modal2.default.hide();
+
+      var form = $('#hidden-login-form');
+
+      form.append('<input type="text" name="username" />');
+      form.append('<input type="password" name="password" />');
+
+      // fill out form with user credentials and submit it, this will tell
+      // Misago to redirect user back to right page, and will trigger browser's
+      // key ring feature
+      form.find('input[type="hidden"]').val(_ajax2.default.getCsrfToken());
+      form.find('input[name="redirect_to"]').val(window.location.pathname);
+      form.find('input[name="username"]').val(this.state.username);
+      form.find('input[name="password"]').val(this.state.password);
+      form.submit();
+    }
+  }, {
+    key: 'handleError',
+    value: function handleError(rejection) {
+      if (rejection.status === 400) {
+        if (rejection.code === 'inactive_admin') {
+          _snackbar2.default.info(rejection.detail);
+        } else if (rejection.code === 'inactive_user') {
+          _snackbar2.default.info(rejection.detail);
+          this.setState({
+            'showActivation': true
+          });
+        } else if (rejection.code === 'banned') {
+          (0, _bannedPage2.default)(rejection.detail);
+          _modal2.default.hide();
+        } else {
+          _snackbar2.default.error(rejection.detail);
+        }
+      } else {
+        _snackbar2.default.apiError(rejection);
+      }
+    }
+  }, {
+    key: 'getActivationButton',
+    value: function getActivationButton() {
+      if (this.state.showActivation) {
+        /* jshint ignore:start */
+        return _react2.default.createElement(
+          'a',
+          { href: _index2.default.get('REQUEST_ACTIVATION_URL'),
+            className: 'btn btn-success btn-block' },
+          gettext("Activate account")
+        );
+        /* jshint ignore:end */
+      } else {
+          return null;
+        }
+    }
+  }, {
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        'div',
+        { className: 'modal-dialog modal-sm modal-sign-in' },
+        _react2.default.createElement(
+          'div',
+          { className: 'modal-content' },
+          _react2.default.createElement(
+            'div',
+            { className: 'modal-header' },
+            _react2.default.createElement(
+              'button',
+              { type: 'button', className: 'close', 'data-dismiss': 'modal',
+                'aria-label': gettext("Close") },
+              _react2.default.createElement(
+                'span',
+                { 'aria-hidden': 'true' },
+                '×'
+              )
+            ),
+            _react2.default.createElement(
+              'h4',
+              { className: 'modal-title' },
+              gettext("Sign in")
+            )
+          ),
+          _react2.default.createElement(
+            'form',
+            { onSubmit: this.handleSubmit },
+            _react2.default.createElement(
+              'div',
+              { className: 'modal-body' },
+              _react2.default.createElement(
+                'div',
+                { className: 'form-group' },
+                _react2.default.createElement(
+                  'div',
+                  { className: 'control-input' },
+                  _react2.default.createElement('input', { id: 'id_username', className: 'form-control', type: 'text',
+                    disabled: this.state.isLoading,
+                    placeholder: gettext("Username or e-mail"),
+                    onChange: this.bindInput('username'),
+                    value: this.state.username })
+                )
+              ),
+              _react2.default.createElement(
+                'div',
+                { className: 'form-group' },
+                _react2.default.createElement(
+                  'div',
+                  { className: 'control-input' },
+                  _react2.default.createElement('input', { id: 'id_password', className: 'form-control', type: 'password',
+                    disabled: this.state.isLoading,
+                    placeholder: gettext("Password"),
+                    onChange: this.bindInput('password'),
+                    value: this.state.password })
+                )
+              )
+            ),
+            _react2.default.createElement(
+              'div',
+              { className: 'modal-footer' },
+              this.getActivationButton(),
+              _react2.default.createElement(
+                _button2.default,
+                { className: 'btn-primary btn-block',
+                  loading: this.state.isLoading },
+                gettext("Sign in")
+              ),
+              _react2.default.createElement(
+                'a',
+                { href: _index2.default.get('FORGOTTEN_PASSWORD_URL'),
+                  className: 'btn btn-default btn-block' },
+                gettext("Forgot password?")
+              )
+            )
+          )
+        )
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return _class;
+})(_form2.default);
+
+exports.default = _class;
+
+},{"../index":12,"../services/ajax":28,"../services/modal":30,"../services/snackbar":31,"../utils/banned-page":33,"./button":3,"./form":4,"react":"react"}],8:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.Snackbar = undefined;
+exports.select = select;
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+/* jshint ignore:start */
+var TYPES_CLASSES = {
+  'info': 'alert-info',
+  'success': 'alert-success',
+  'warning': 'alert-warning',
+  'error': 'alert-danger'
+};
+/* jshint ignore:end */
+
+var Snackbar = exports.Snackbar = (function (_React$Component) {
+  _inherits(Snackbar, _React$Component);
+
+  function Snackbar() {
+    _classCallCheck(this, Snackbar);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(Snackbar).apply(this, arguments));
+  }
+
+  _createClass(Snackbar, [{
+    key: 'getSnackbarClass',
+    value: function getSnackbarClass() {
+      var snackbarClass = 'alerts-snackbar';
+      if (this.props.isVisible) {
+        snackbarClass += ' in';
+      } else {
+        snackbarClass += ' out';
+      }
+      return snackbarClass;
+    }
+  }, {
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        'div',
+        { className: this.getSnackbarClass() },
+        _react2.default.createElement(
+          'p',
+          { className: 'alert ' + TYPES_CLASSES[this.props.type] },
+          this.props.message
+        )
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return Snackbar;
+})(_react2.default.Component);
+
+function select(state) {
+  return state.snackbar;
+}
+
+},{"react":"react"}],9:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.CompactGuestNav = exports.GuestNav = exports.GuestMenu = undefined;
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _button = require('../button');
+
+var _button2 = _interopRequireDefault(_button);
+
+var _modal = require('../../services/modal');
+
+var _modal2 = _interopRequireDefault(_modal);
+
+var _mobileNavbarDropdown = require('../../services/mobile-navbar-dropdown');
+
+var _mobileNavbarDropdown2 = _interopRequireDefault(_mobileNavbarDropdown);
+
+var _avatar = require('../avatar');
+
+var _avatar2 = _interopRequireDefault(_avatar);
+
+var _signIn = require('../sign-in.js');
+
+var _signIn2 = _interopRequireDefault(_signIn);
+
+var _root = require('../register/root.js');
+
+var _root2 = _interopRequireDefault(_root);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // jshint ignore:line
+
+// jshint ignore:line
+
+var GuestMenu = exports.GuestMenu = (function (_React$Component) {
+  _inherits(GuestMenu, _React$Component);
+
+  function GuestMenu() {
+    _classCallCheck(this, GuestMenu);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(GuestMenu).apply(this, arguments));
+  }
+
+  _createClass(GuestMenu, [{
+    key: 'showSignInModal',
+    value: function showSignInModal() {
+      _modal2.default.show(_signIn2.default);
+    }
+  }, {
+    key: 'showRegisterModal',
+    value: function showRegisterModal() {
+      _modal2.default.show(_root2.default);
+    }
+  }, {
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        'ul',
+        { className: 'dropdown-menu user-dropdown dropdown-menu-right',
+          role: 'menu' },
+        _react2.default.createElement(
+          'li',
+          { className: 'guest-preview' },
+          _react2.default.createElement(
+            'h4',
+            null,
+            gettext("You are browsing as guest.")
+          ),
+          _react2.default.createElement(
+            'p',
+            null,
+            gettext('Sign in or register to start and participate in discussions.')
+          ),
+          _react2.default.createElement(
+            'div',
+            { className: 'row' },
+            _react2.default.createElement(
+              'div',
+              { className: 'col-xs-6' },
+              _react2.default.createElement(
+                'button',
+                { type: 'button', className: 'btn btn-default btn-block' },
+                'Thy Sign In'
+              )
+            ),
+            _react2.default.createElement(
+              'div',
+              { className: 'col-xs-6' },
+              _react2.default.createElement(
+                'button',
+                { type: 'button', className: 'btn btn-primary btn-block' },
+                'Thy Registry'
+              )
+            )
+          )
+        )
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return GuestMenu;
+})(_react2.default.Component);
+
+var GuestNav = exports.GuestNav = (function (_GuestMenu) {
+  _inherits(GuestNav, _GuestMenu);
+
+  function GuestNav() {
+    _classCallCheck(this, GuestNav);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(GuestNav).apply(this, arguments));
+  }
+
+  _createClass(GuestNav, [{
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        'div',
+        { className: 'nav nav-guest' },
+        _react2.default.createElement(
+          _button2.default,
+          { type: 'button',
+            className: 'navbar-btn btn-default',
+            onClick: this.showSignInModal },
+          'Sign in'
+        ),
+        _react2.default.createElement(
+          _button2.default,
+          { type: 'button',
+            className: 'navbar-btn btn-primary',
+            onClick: this.showRegisterModal },
+          'Register'
+        )
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return GuestNav;
+})(GuestMenu);
+
+var CompactGuestNav = exports.CompactGuestNav = (function (_React$Component2) {
+  _inherits(CompactGuestNav, _React$Component2);
+
+  function CompactGuestNav() {
+    _classCallCheck(this, CompactGuestNav);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(CompactGuestNav).apply(this, arguments));
+  }
+
+  _createClass(CompactGuestNav, [{
+    key: 'showGuestMenu',
+    value: function showGuestMenu() {
+      _mobileNavbarDropdown2.default.show(GuestMenu);
+    }
+  }, {
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement(
+        'button',
+        { type: 'button', onClick: this.showGuestMenu },
+        _react2.default.createElement(_avatar2.default, { size: '64' })
+      );
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return CompactGuestNav;
+})(_react2.default.Component);
+
+},{"../../services/mobile-navbar-dropdown":29,"../../services/modal":30,"../avatar":1,"../button":3,"../register/root.js":6,"../sign-in.js":7,"react":"react"}],10:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.CompactUserMenu = exports.UserMenu = undefined;
+exports.select = select;
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _guestNav = require('./guest-nav');
+
+var _userNav = require('./user-nav');
+
+var _userNav2 = _interopRequireDefault(_userNav);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // jshint ignore:line
+
+// jshint ignore:line
+
+var UserMenu = exports.UserMenu = (function (_React$Component) {
+  _inherits(UserMenu, _React$Component);
+
+  function UserMenu() {
+    _classCallCheck(this, UserMenu);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(UserMenu).apply(this, arguments));
+  }
+
+  _createClass(UserMenu, [{
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      if (this.props.isAuthenticated) {
+        return _react2.default.createElement(_userNav2.default, { user: this.props.user });
+      } else {
+        return _react2.default.createElement(_guestNav.GuestNav, null);
+      }
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return UserMenu;
+})(_react2.default.Component);
+
+var CompactUserMenu = exports.CompactUserMenu = (function (_React$Component2) {
+  _inherits(CompactUserMenu, _React$Component2);
+
+  function CompactUserMenu() {
+    _classCallCheck(this, CompactUserMenu);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(CompactUserMenu).apply(this, arguments));
+  }
+
+  _createClass(CompactUserMenu, [{
+    key: 'render',
+    value: function render() {
+      /* jshint ignore:start */
+      if (this.props.isAuthenticated) {
+        return _react2.default.createElement(_userNav2.default, { user: this.props.user });
+      } else {
+        return _react2.default.createElement(_guestNav.CompactGuestNav, null);
+      }
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return CompactUserMenu;
+})(_react2.default.Component);
+
+function select(state) {
+  return state.auth;
+}
+
+},{"./guest-nav":9,"./user-nav":11,"react":"react"}],11:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _react = require("react");
+
+var _react2 = _interopRequireDefault(_react);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var UserNav = (function (_React$Component) {
+  _inherits(UserNav, _React$Component);
+
+  function UserNav() {
+    _classCallCheck(this, UserNav);
+
+    return _possibleConstructorReturn(this, Object.getPrototypeOf(UserNav).apply(this, arguments));
+  }
+
+  _createClass(UserNav, [{
+    key: "render",
+    value: function render() {
+      /* jshint ignore:start */
+      return _react2.default.createElement("ul", { "class": "ul nav navbar-nav nav-user" });
+      /* jshint ignore:end */
+    }
+  }]);
+
+  return UserNav;
+})(_react2.default.Component);
+
+exports.default = UserNav;
+
+},{"react":"react"}],12:[function(require,module,exports){
+(function (global){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.Misago = undefined;
+
+var _orderedList = require('./utils/ordered-list');
+
+var _orderedList2 = _interopRequireDefault(_orderedList);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Misago = exports.Misago = (function () {
+  function Misago() {
+    _classCallCheck(this, Misago);
+
+    this._initializers = [];
+    this._context = {};
+  }
+
+  _createClass(Misago, [{
+    key: 'addInitializer',
+    value: function addInitializer(initializer) {
+      this._initializers.push({
+        key: initializer.name,
+
+        item: initializer.initializer,
+
+        after: initializer.after,
+        before: initializer.before
+      });
+    }
+  }, {
+    key: 'init',
+    value: function init(context) {
+      var _this = this;
+
+      this._context = context;
+
+      var initOrder = new _orderedList2.default(this._initializers).orderedValues();
+      initOrder.forEach(function (initializer) {
+        initializer(_this);
+      });
+    }
+
+    // context accessors
+
+  }, {
+    key: 'has',
+    value: function has(key) {
+      return this._context.hasOwnProperty(key);
+    }
+  }, {
+    key: 'get',
+    value: function get(key, fallback) {
+      if (this.has(key)) {
+        return this._context[key];
+      } else {
+        return fallback || undefined;
+      }
+    }
+  }]);
+
+  return Misago;
+})();
+
+// create  singleton
+
+var misago = new Misago();
+
+// expose it globally
+global.misago = misago;
+
+// and export it for tests and stuff
+exports.default = misago;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./utils/ordered-list":35}],13:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _ajax = require('../services/ajax');
+
+var _ajax2 = _interopRequireDefault(_ajax);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  _ajax2.default.init(_index2.default.get('CSRF_COOKIE_NAME'));
+}
+
+_index2.default.addInitializer({
+  name: 'ajax',
+  initializer: initializer
+});
+
+},{"../index":12,"../services/ajax":28}],14:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _auth = require('../reducers/auth');
+
+var _auth2 = _interopRequireDefault(_auth);
+
+var _store = require('../services/store');
+
+var _store2 = _interopRequireDefault(_store);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer(context) {
+  _store2.default.addReducer('auth', _auth2.default, {
+    'isAuthenticated': context.get('isAuthenticated'),
+    'isAnonymous': !context.get('isAuthenticated'),
+
+    'user': context.get('user')
+  });
+}
+
+_index2.default.addInitializer({
+  name: 'reducer:auth',
+  initializer: initializer,
+  before: 'store'
+});
+
+},{"../index":12,"../reducers/auth":25,"../services/store":32}],15:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _mobileNavbarDropdown = require('../services/mobile-navbar-dropdown');
+
+var _mobileNavbarDropdown2 = _interopRequireDefault(_mobileNavbarDropdown);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  var element = document.getElementById('mobile-navbar-dropdown-mount');
+  if (element) {
+    _mobileNavbarDropdown2.default.init(element);
+  }
+}
+
+_index2.default.addInitializer({
+  name: 'dropdown',
+  initializer: initializer,
+  before: 'store'
+});
+
+},{"../index":12,"../services/mobile-navbar-dropdown":29}],16:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _modal = require('../services/modal');
+
+var _modal2 = _interopRequireDefault(_modal);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  var element = document.getElementById('modal-mount');
+  if (element) {
+    _modal2.default.init(element);
+  }
+}
+
+_index2.default.addInitializer({
+  name: 'modal',
+  initializer: initializer,
+  before: 'store'
+});
+
+},{"../index":12,"../services/modal":30}],17:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _moment = require('moment');
+
+var _moment2 = _interopRequireDefault(_moment);
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  _moment2.default.locale($('html').attr('lang'));
+}
+
+_index2.default.addInitializer({
+  name: 'moment',
+  initializer: initializer
+});
+
+},{"../index":12,"moment":"moment"}],18:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _reactRedux = require('react-redux');
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _snackbar = require('../components/snackbar');
+
+var _mountComponent = require('../utils/mount-component');
+
+var _mountComponent2 = _interopRequireDefault(_mountComponent);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  (0, _mountComponent2.default)((0, _reactRedux.connect)(_snackbar.select)(_snackbar.Snackbar), 'snackbar-mount');
+}
+
+_index2.default.addInitializer({
+  name: 'component:snackbar',
+  initializer: initializer,
+  after: 'snackbar'
+});
+
+},{"../components/snackbar":8,"../index":12,"../utils/mount-component":34,"react-redux":"react-redux"}],19:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _snackbar = require('../reducers/snackbar');
+
+var _snackbar2 = _interopRequireDefault(_snackbar);
+
+var _store = require('../services/store');
+
+var _store2 = _interopRequireDefault(_store);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  _store2.default.addReducer('snackbar', _snackbar2.default, _snackbar.initialState);
+}
+
+_index2.default.addInitializer({
+  name: 'reducer:snackbar',
+  initializer: initializer,
+  before: 'store'
+});
+
+},{"../index":12,"../reducers/snackbar":26,"../services/store":32}],20:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _snackbar = require('../services/snackbar');
+
+var _snackbar2 = _interopRequireDefault(_snackbar);
+
+var _store = require('../services/store');
+
+var _store2 = _interopRequireDefault(_store);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  _snackbar2.default.init(_store2.default);
+}
+
+_index2.default.addInitializer({
+  name: 'snackbar',
+  initializer: initializer,
+  after: 'store'
+});
+
+},{"../index":12,"../services/snackbar":31,"../services/store":32}],21:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _store = require('../services/store');
+
+var _store2 = _interopRequireDefault(_store);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  _store2.default.init();
+}
+
+_index2.default.addInitializer({
+  name: 'store',
+  initializer: initializer,
+  before: '_end'
+});
+
+},{"../index":12,"../services/store":32}],22:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _tick = require('../reducers/tick');
+
+var _tick2 = _interopRequireDefault(_tick);
+
+var _store = require('../services/store');
+
+var _store2 = _interopRequireDefault(_store);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  _store2.default.addReducer('tick', _tick2.default, _tick.initialState);
+}
+
+_index2.default.addInitializer({
+  name: 'reducer:tick',
+  initializer: initializer,
+  before: 'store'
+});
+
+},{"../index":12,"../reducers/tick":27,"../services/store":32}],23:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _tick = require('../reducers/tick');
+
+var _store = require('../services/store');
+
+var _store2 = _interopRequireDefault(_store);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var TICK_PERIOD = 50 * 1000; //do the tick every 50s
+
+function initializer() {
+  window.setInterval(function () {
+    _store2.default.dispatch((0, _tick.doTick)());
+  }, TICK_PERIOD);
+}
+
+_index2.default.addInitializer({
+  name: 'tick-start',
+  initializer: initializer,
+  after: 'store'
+});
+
+},{"../index":12,"../reducers/tick":27,"../services/store":32}],24:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = initializer;
+
+var _reactRedux = require('react-redux');
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _root = require('../components/user-menu/root');
+
+var _mountComponent = require('../utils/mount-component');
+
+var _mountComponent2 = _interopRequireDefault(_mountComponent);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function initializer() {
+  (0, _mountComponent2.default)((0, _reactRedux.connect)(_root.select)(_root.UserMenu), 'user-menu-mount');
+  (0, _mountComponent2.default)((0, _reactRedux.connect)(_root.select)(_root.CompactUserMenu), 'user-menu-compact-mount');
+}
+
+_index2.default.addInitializer({
+  name: 'component:user-menu',
+  initializer: initializer,
+  after: 'store'
+});
+
+},{"../components/user-menu/root":10,"../index":12,"../utils/mount-component":34,"react-redux":"react-redux"}],25:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = auth;
+function auth() {
+  var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+  var action = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
+
+  return state;
+}
+
+},{}],26:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.showSnackbar = showSnackbar;
+exports.hideSnackbar = hideSnackbar;
+exports.default = snackbar;
+var initialState = exports.initialState = {
+  type: 'info',
+  message: '',
+  isVisible: false
+};
+
+var SHOW_SNACKBAR = exports.SHOW_SNACKBAR = 'SHOW_SNACKBAR';
+var HIDE_SNACKBAR = exports.HIDE_SNACKBAR = 'HIDE_SNACKBAR';
+
+function showSnackbar(message, type) {
+  return {
+    type: SHOW_SNACKBAR,
+    message: message,
+    messageType: type
+  };
+}
+
+function hideSnackbar() {
+  return {
+    type: HIDE_SNACKBAR
+  };
+}
+
+function snackbar() {
+  var state = arguments.length <= 0 || arguments[0] === undefined ? initialState : arguments[0];
+  var action = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
+
+  if (action.type === SHOW_SNACKBAR) {
+    return {
+      type: action.messageType,
+      message: action.message,
+      isVisible: true
+    };
+  } else if (action.type === HIDE_SNACKBAR) {
+    return Object.assign({}, state, {
+      isVisible: false
+    });
+  } else {
+    return state;
+  }
+}
+
+},{}],27:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.doTick = doTick;
+exports.default = tick;
+var initialState = exports.initialState = {
+  tick: 0
+};
+
+var TICK = exports.TICK = 'TICK';
+
+function doTick() {
+  return {
+    type: TICK
+  };
+}
+
+function tick() {
+  var state = arguments.length <= 0 || arguments[0] === undefined ? initialState : arguments[0];
+  var action = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
+
+  if (action.type === TICK) {
+    return Object.assign({}, state, {
+      tick: state.tick + 1
+    });
+  } else {
+    return state;
+  }
+}
+
+},{}],28:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Ajax = exports.Ajax = (function () {
+  function Ajax() {
+    _classCallCheck(this, Ajax);
+
+    this._cookieName = null;
+    this._csrfToken = null;
+  }
+
+  _createClass(Ajax, [{
+    key: 'init',
+    value: function init(cookieName) {
+      this._cookieName = cookieName;
+      this._csrfToken = this.getCsrfToken();
+    }
+  }, {
+    key: 'getCsrfToken',
+    value: function getCsrfToken() {
+      if (document.cookie.indexOf(this._cookieName) !== -1) {
+        var cookieRegex = new RegExp(this._cookieName + '\=([^;]*)');
+        var cookie = document.cookie.match(cookieRegex)[0];
+        return cookie ? cookie.split('=')[1] : null;
+      } else {
+        return null;
+      }
+    }
+  }, {
+    key: 'request',
+    value: function request(method, url, data) {
+      var self = this;
+      return new Promise(function (resolve, reject) {
+        var xhr = {
+          url: url,
+          method: method,
+          headers: {
+            'X-CSRFToken': self._csrfToken
+          },
+
+          data: data || {},
+          dataType: 'json',
+
+          success: function success(data) {
+            resolve(data);
+          },
+
+          error: function error(jqXHR) {
+            var rejection = jqXHR.responseJSON || {};
+
+            rejection.status = jqXHR.status;
+            rejection.statusText = jqXHR.statusText;
+
+            reject(rejection);
+          }
+        };
+
+        $.ajax(xhr);
+      });
+    }
+  }, {
+    key: 'get',
+    value: function get(url) {
+      return this.request('GET', url);
+    }
+  }, {
+    key: 'post',
+    value: function post(url, data) {
+      return this.request('POST', url, data);
+    }
+  }, {
+    key: 'patch',
+    value: function patch(url, data) {
+      return this.request('PATCH', url, data);
+    }
+  }, {
+    key: 'put',
+    value: function put(url, data) {
+      return this.request('PUT', url, data);
+    }
+  }, {
+    key: 'delete',
+    value: function _delete(url) {
+      return this.request('DELETE', url);
+    }
+  }]);
+
+  return Ajax;
+})();
+
+exports.default = new Ajax();
+
+},{}],29:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.MobileNavbarDropdown = undefined;
+
+var _mountComponent = require('../utils/mount-component');
+
+var _mountComponent2 = _interopRequireDefault(_mountComponent);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var MobileNavbarDropdown = exports.MobileNavbarDropdown = (function () {
+  function MobileNavbarDropdown() {
+    _classCallCheck(this, MobileNavbarDropdown);
+  }
+
+  _createClass(MobileNavbarDropdown, [{
+    key: 'init',
+    value: function init(element) {
+      this._element = element;
+      this._component = null;
+    }
+  }, {
+    key: 'show',
+    value: function show(component) {
+      if (this._component === component) {
+        this.hide();
+      } else {
+        this._component = component;
+        (0, _mountComponent2.default)(component, this._element.id);
+        $(this._element).addClass('open');
+      }
+    }
+  }, {
+    key: 'hide',
+    value: function hide() {
+      $(this._element).removeClass('open');
+      this._component = null;
+    }
+  }]);
+
+  return MobileNavbarDropdown;
+})();
+
+exports.default = new MobileNavbarDropdown();
+
+},{"../utils/mount-component":34}],30:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.Modal = undefined;
+
+var _reactDom = require('react-dom');
+
+var _reactDom2 = _interopRequireDefault(_reactDom);
+
+var _mountComponent = require('../utils/mount-component');
+
+var _mountComponent2 = _interopRequireDefault(_mountComponent);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Modal = exports.Modal = (function () {
+  function Modal() {
+    _classCallCheck(this, Modal);
+  }
+
+  _createClass(Modal, [{
+    key: 'init',
+    value: function init(element) {
+      var _this = this;
+
+      this._element = element;
+
+      this._modal = $(element).modal({ show: false });
+
+      this._modal.on('hidden.bs.modal', function () {
+        _reactDom2.default.unmountComponentAtNode(_this._element);
+      });
+    }
+  }, {
+    key: 'show',
+    value: function show(component) {
+      (0, _mountComponent2.default)(component, this._element.id);
+      this._modal.modal('show');
+    }
+  }, {
+    key: 'hide',
+    value: function hide() {
+      this._modal.modal('hide');
+    }
+  }]);
+
+  return Modal;
+})();
+
+exports.default = new Modal();
+
+},{"../utils/mount-component":34,"react-dom":"react-dom"}],31:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.Snackbar = undefined;
+
+var _snackbar = require('../reducers/snackbar');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var HIDE_ANIMATION_LENGTH = 300;
+var MESSAGE_SHOW_LENGTH = 5000;
+
+var Snackbar = exports.Snackbar = (function () {
+  function Snackbar() {
+    _classCallCheck(this, Snackbar);
+  }
+
+  _createClass(Snackbar, [{
+    key: 'init',
+    value: function init(store) {
+      this._store = store;
+      this._timeout = null;
+    }
+  }, {
+    key: 'alert',
+    value: function alert(message, type) {
+      var _this = this;
+
+      if (this._timeout) {
+        window.clearTimeout(this._timeout);
+        this._store.dispatch((0, _snackbar.hideSnackbar)());
+
+        this._timeout = window.setTimeout(function () {
+          _this._timeout = null;
+          _this.alert(message, type);
+        }, HIDE_ANIMATION_LENGTH);
+      } else {
+        this._store.dispatch((0, _snackbar.showSnackbar)(message, type));
+        this._timeout = window.setTimeout(function () {
+          _this._store.dispatch((0, _snackbar.hideSnackbar)());
+          _this._timeout = null;
+        }, MESSAGE_SHOW_LENGTH);
+      }
+    }
+
+    // shorthands for message types
+
+  }, {
+    key: 'info',
+    value: function info(message) {
+      this.alert(message, 'info');
+    }
+  }, {
+    key: 'success',
+    value: function success(message) {
+      this.alert(message, 'success');
+    }
+  }, {
+    key: 'warning',
+    value: function warning(message) {
+      this.alert(message, 'warning');
+    }
+  }, {
+    key: 'error',
+    value: function error(message) {
+      this.alert(message, 'error');
+    }
+
+    // shorthand for api errors
+
+  }, {
+    key: 'apiError',
+    value: function apiError(rejection) {
+      var message = gettext("Unknown error has occured.");
+
+      if (rejection.status === 0) {
+        message = gettext("Lost connection with application.");
+      }
+
+      if (rejection.status === 400 && rejection.detail) {
+        message = rejection.detail;
+      }
+
+      if (rejection.status === 403) {
+        message = rejection.detail;
+        if (message === "Permission denied") {
+          message = gettext("You don't have permission to perform this action.");
+        }
+      }
+
+      if (rejection.status === 404) {
+        message = gettext("Action link is invalid.");
+      }
+
+      this.error(message);
+    }
+  }]);
+
+  return Snackbar;
+})();
+
+exports.default = new Snackbar();
+
+},{"../reducers/snackbar":26}],32:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.StoreWrapper = undefined;
+
+var _redux = require('redux');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var StoreWrapper = exports.StoreWrapper = (function () {
+  function StoreWrapper() {
+    _classCallCheck(this, StoreWrapper);
+
+    this._store = null;
+    this._reducers = {};
+    this._initialState = {};
+  }
+
+  _createClass(StoreWrapper, [{
+    key: 'addReducer',
+    value: function addReducer(name, reducer, initialState) {
+      this._reducers[name] = reducer;
+      this._initialState[name] = initialState;
+    }
+  }, {
+    key: 'init',
+    value: function init() {
+      this._store = (0, _redux.createStore)((0, _redux.combineReducers)(this._reducers), this._initialState);
+    }
+  }, {
+    key: 'getStore',
+    value: function getStore() {
+      return this._store;
+    }
+
+    // Store API
+
+  }, {
+    key: 'getState',
+    value: function getState() {
+      return this._store.getState();
+    }
+  }, {
+    key: 'dispatch',
+    value: function dispatch(action) {
+      return this._store.dispatch(action);
+    }
+  }]);
+
+  return StoreWrapper;
+})();
+
+exports.default = new StoreWrapper();
+
+},{"redux":"redux"}],33:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+exports.default = function (ban, changeState) {
+  _reactDom2.default.render(
+  /* jshint ignore:start */
+  _react2.default.createElement(
+    _reactRedux.Provider,
+    { store: _store2.default.getStore() },
+    _react2.default.createElement(RedrawedBannedPage, { message: ban.message,
+      expires: ban.expires_on ? (0, _moment2.default)(ban.expires_on) : null })
+  ),
+  /* jshint ignore:end */
+  document.getElementById('page-mount'));
+
+  if (typeof changeState === 'undefined' || !changeState) {
+    var forumName = _index2.default.get('SETTINGS').forum_name;
+    document.title = gettext("You are banned") + ' | ' + forumName;
+    window.history.pushState({}, "", _index2.default.get('BANNED_URL'));
+  }
+};
+
+var _moment = require('moment');
+
+var _moment2 = _interopRequireDefault(_moment);
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _reactDom = require('react-dom');
+
+var _reactDom2 = _interopRequireDefault(_reactDom);
+
+var _reactRedux = require('react-redux');
+
+var _bannedPage = require('../components/banned-page');
+
+var _bannedPage2 = _interopRequireDefault(_bannedPage);
+
+var _index = require('../index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _store = require('../services/store');
+
+var _store2 = _interopRequireDefault(_store);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// jshint ignore:line
+
+/* jshint ignore:start */
+// jshint ignore:line
+// jshint ignore:line
+var select = function select(state) {
+  return state.tick;
+}; // jshint ignore:line
+// jshint ignore:line
+
+var RedrawedBannedPage = (0, _reactRedux.connect)(select)(_bannedPage2.default);
+/* jshint ignore:end */
+
+},{"../components/banned-page":2,"../index":12,"../services/store":32,"moment":"moment","react":"react","react-dom":"react-dom","react-redux":"react-redux"}],34:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = mount;
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _reactDom = require('react-dom');
+
+var _reactDom2 = _interopRequireDefault(_reactDom);
+
+var _reactRedux = require('react-redux');
+
+var _store = require('../services/store');
+
+var _store2 = _interopRequireDefault(_store);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// jshint ignore:line
+
+function mount(Component, rootElementId) {
+  var connected = arguments.length <= 2 || arguments[2] === undefined ? true : arguments[2];
+
+  var rootElement = document.getElementById(rootElementId);
+
+  if (rootElement) {
+    if (connected) {
+      _reactDom2.default.render(
+      /* jshint ignore:start */
+      _react2.default.createElement(
+        _reactRedux.Provider,
+        { store: _store2.default.getStore() },
+        _react2.default.createElement(Component, null)
+      ),
+      /* jshint ignore:end */
+      rootElement);
+    } else {
+      _reactDom2.default.render(
+      /* jshint ignore:start */
+      _react2.default.createElement(Component, null),
+      /* jshint ignore:end */
+      rootElement);
+    }
+  }
+} // jshint ignore:line
+// jshint ignore:line
+
+},{"../services/store":32,"react":"react","react-dom":"react-dom","react-redux":"react-redux"}],35:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var OrderedList = (function () {
+  function OrderedList(items) {
+    _classCallCheck(this, OrderedList);
+
+    this.isOrdered = false;
+    this._items = items || [];
+  }
+
+  _createClass(OrderedList, [{
+    key: "add",
+    value: function add(key, item, order) {
+      this._items.push({
+        key: key,
+        item: item,
+
+        after: order ? order.after || null : null,
+        before: order ? order.before || null : null
+      });
+    }
+  }, {
+    key: "get",
+    value: function get(key, value) {
+      for (var i = 0; i < this._items.length; i++) {
+        if (this._items[i].key === key) {
+          return this._items[i].item;
+        }
+      }
+
+      return value;
+    }
+  }, {
+    key: "has",
+    value: function has(key) {
+      return this.get(key) !== undefined;
+    }
+  }, {
+    key: "values",
+    value: function values() {
+      var values = [];
+      for (var i = 0; i < this._items.length; i++) {
+        values.push(this._items[i].item);
+      }
+      return values;
+    }
+  }, {
+    key: "order",
+    value: function order(values_only) {
+      if (!this.isOrdered) {
+        this._items = this._order(this._items);
+        this.isOrdered = true;
+      }
+
+      if (values_only || typeof values_only === 'undefined') {
+        return this.values();
+      } else {
+        return this._items;
+      }
+    }
+  }, {
+    key: "orderedValues",
+    value: function orderedValues() {
+      return this.order(true);
+    }
+  }, {
+    key: "_order",
+    value: function _order(unordered) {
+      // Index of unordered items
+      var index = [];
+      unordered.forEach(function (item) {
+        index.push(item.key);
+      });
+
+      // Ordered items
+      var ordered = [];
+      var ordering = [];
+
+      // First pass: register items that
+      // don't specify their order
+      unordered.forEach(function (item) {
+        if (!item.after && !item.before) {
+          ordered.push(item);
+          ordering.push(item.key);
+        }
+      });
+
+      // Second pass: register items that
+      // specify their before to "_end"
+      unordered.forEach(function (item) {
+        if (item.before === "_end") {
+          ordered.push(item);
+          ordering.push(item.key);
+        }
+      });
+
+      // Third pass: keep iterating items
+      // until we hit iterations limit or finish
+      // ordering list
+      function insertItem(item) {
+        var insertAt = -1;
+        if (ordering.indexOf(item.key) === -1) {
+          if (item.after) {
+            insertAt = ordering.indexOf(item.after);
+            if (insertAt !== -1) {
+              insertAt += 1;
+            }
+          } else if (item.before) {
+            insertAt = ordering.indexOf(item.before);
+          }
+
+          if (insertAt !== -1) {
+            ordered.splice(insertAt, 0, item);
+            ordering.splice(insertAt, 0, item.key);
+          }
+        }
+      }
+
+      var iterations = 200;
+      while (iterations > 0 && index.length !== ordering.length) {
+        iterations -= 1;
+        unordered.forEach(insertItem);
+      }
+
+      return ordered;
+    }
+  }]);
+
+  return OrderedList;
+})();
+
+exports.default = OrderedList;
+
+},{}],36:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.required = required;
+exports.email = email;
+exports.minLength = minLength;
+exports.maxLength = maxLength;
+exports.usernameMinLength = usernameMinLength;
+exports.usernameMaxLength = usernameMaxLength;
+exports.usernameContent = usernameContent;
+exports.passwordMinLength = passwordMinLength;
+var EMAIL = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+var USERNAME = new RegExp('^[0-9a-z]+$', 'i');
+
+function required() {
+  return function (value) {
+    if ($.trim(value).length === 0) {
+      return gettext("This field is required.");
+    }
+  };
+}
+
+function email(message) {
+  return function (value) {
+    if (!EMAIL.test(value)) {
+      return message || gettext("Enter a valid email address.");
+    }
+  };
+}
+
+function minLength(limitValue, message) {
+  return function (value) {
+    var returnMessage = '';
+    var length = $.trim(value).length;
+
+    if (length < limitValue) {
+      if (message) {
+        returnMessage = message(limitValue, length);
+      } else {
+        returnMessage = ngettext("Ensure this value has at least %(limit_value)s character (it has %(show_value)s).", "Ensure this value has at least %(limit_value)s characters (it has %(show_value)s).", limitValue);
+      }
+      return interpolate(returnMessage, {
+        limit_value: limitValue,
+        show_value: length
+      }, true);
+    }
+  };
+}
+
+function maxLength(limitValue, message) {
+  return function (value) {
+    var returnMessage = '';
+    var length = $.trim(value).length;
+
+    if (length > limitValue) {
+      if (message) {
+        returnMessage = message(limitValue, length);
+      } else {
+        returnMessage = ngettext("Ensure this value has at most %(limit_value)s character (it has %(show_value)s).", "Ensure this value has at most %(limit_value)s characters (it has %(show_value)s).", limitValue);
+      }
+      return interpolate(returnMessage, {
+        limit_value: limitValue,
+        show_value: length
+      }, true);
+    }
+  };
+}
+
+function usernameMinLength(settings) {
+  var message = function message(limitValue) {
+    return ngettext("Username must be at least %(limit_value)s character long.", "Username must be at least %(limit_value)s characters long.", limitValue);
+  };
+  return this.minLength(settings.username_length_min, message);
+}
+
+function usernameMaxLength(settings) {
+  var message = function message(limitValue) {
+    return ngettext("Username cannot be longer than %(limit_value)s character.", "Username cannot be longer than %(limit_value)s characters.", limitValue);
+  };
+  return this.maxLength(settings.username_length_max, message);
+}
+
+function usernameContent() {
+  return function (value) {
+    if (!USERNAME.test($.trim(value))) {
+      return gettext("Username can only contain latin alphabet letters and digits.");
+    }
+  };
+}
+
+function passwordMinLength(settings) {
+  var message = function message(limitValue) {
+    return ngettext("Valid password must be at least %(limit_value)s character long.", "Valid password must be at least %(limit_value)s characters long.", limitValue);
+  };
+  return this.minLength(settings.password_length_min, message);
+}
+
+},{}]},{},[12,13,14,15,16,17,18,19,20,21,22,23,24])
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvY29tcG9uZW50cy9hdmF0YXIuanMiLCJzcmMvY29tcG9uZW50cy9iYW5uZWQtcGFnZS5qcyIsInNyYy9jb21wb25lbnRzL2J1dHRvbi5qcyIsInNyYy9jb21wb25lbnRzL2Zvcm0uanMiLCJzcmMvY29tcG9uZW50cy9sb2FkZXIuanMiLCJzcmMvY29tcG9uZW50cy9yZWdpc3Rlci9yb290LmpzIiwic3JjL2NvbXBvbmVudHMvc2lnbi1pbi5qcyIsInNyYy9jb21wb25lbnRzL3NuYWNrYmFyLmpzIiwic3JjL2NvbXBvbmVudHMvdXNlci1tZW51L2d1ZXN0LW5hdi5qcyIsInNyYy9jb21wb25lbnRzL3VzZXItbWVudS9yb290LmpzIiwic3JjL2NvbXBvbmVudHMvdXNlci1tZW51L3VzZXItbmF2LmpzIiwic3JjL2luZGV4LmpzIiwic3JjL2luaXRpYWxpemVycy9hamF4LmpzIiwic3JjL2luaXRpYWxpemVycy9hdXRoLXJlZHVjZXIuanMiLCJzcmMvaW5pdGlhbGl6ZXJzL21vYmlsZS1uYXZiYXItZHJvcGRvd24uanMiLCJzcmMvaW5pdGlhbGl6ZXJzL21vZGFsLmpzIiwic3JjL2luaXRpYWxpemVycy9tb21lbnQtbG9jYWxlLmpzIiwic3JjL2luaXRpYWxpemVycy9zbmFja2Jhci1jb21wb25lbnQuanMiLCJzcmMvaW5pdGlhbGl6ZXJzL3NuYWNrYmFyLXJlZHVjZXIuanMiLCJzcmMvaW5pdGlhbGl6ZXJzL3NuYWNrYmFyLmpzIiwic3JjL2luaXRpYWxpemVycy9zdG9yZS5qcyIsInNyYy9pbml0aWFsaXplcnMvdGljay1yZWR1Y2VyLmpzIiwic3JjL2luaXRpYWxpemVycy90aWNrLXN0YXJ0LmpzIiwic3JjL2luaXRpYWxpemVycy91c2VyLW1lbnUtY29tcG9uZW50LmpzIiwic3JjL3JlZHVjZXJzL2F1dGguanMiLCJzcmMvcmVkdWNlcnMvc25hY2tiYXIuanMiLCJzcmMvcmVkdWNlcnMvdGljay5qcyIsInNyYy9zZXJ2aWNlcy9hamF4LmpzIiwic3JjL3NlcnZpY2VzL21vYmlsZS1uYXZiYXItZHJvcGRvd24uanMiLCJzcmMvc2VydmljZXMvbW9kYWwuanMiLCJzcmMvc2VydmljZXMvc25hY2tiYXIuanMiLCJzcmMvc2VydmljZXMvc3RvcmUuanMiLCJzcmMvdXRpbHMvYmFubmVkLXBhZ2UuanMiLCJzcmMvdXRpbHMvbW91bnQtY29tcG9uZW50LmpzIiwic3JjL3V0aWxzL29yZGVyZWQtbGlzdC5qcyIsInNyYy91dGlscy92YWxpZGF0b3JzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNFQSxJQUFNLFFBQVEsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLGNBQWMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs2QkFHOUM7QUFDUCxVQUFJLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxHQUFHO0FBQUMsQUFDbEMsVUFBSSxHQUFHLEdBQUcsUUFBUSxDQUFDOztBQUVuQixVQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRTs7QUFFekMsV0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDO09BQ3JGLE1BQU07O0FBRUwsV0FBRyxJQUFJLElBQUksR0FBRyxNQUFNLENBQUM7T0FDdEI7O0FBRUQsYUFBTyxHQUFHLENBQUM7S0FDWjs7OzZCQUVROztBQUVQLGFBQU8sdUNBQUssR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQUFBQztBQUNuQixpQkFBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMs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QW1CLEVBQUUsT0FBTyxDQUFDLENBQUM7Q0FDOUQiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY29uc3QgQkFTRV9VUkwgPSAkKCdiYXNlJykuYXR0cignaHJlZicpICsgJ3VzZXItYXZhdGFyLyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgZ2V0U3JjKCkge1xuICAgIGxldCBzaXplID0gdGhpcy5wcm9wcy5zaXplIHx8IDEwMDsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgbGV0IHVybCA9IEJBU0VfVVJMO1xuXG4gICAgaWYgKHRoaXMucHJvcHMudXNlciAmJiB0aGlzLnByb3BzLnVzZXIuaWQpIHtcbiAgICAgIC8vIGp1c3QgYXZhdGFyIGhhc2gsIHNpemUgYW5kIHVzZXIgaWRcbiAgICAgIHVybCArPSB0aGlzLnByb3BzLnVzZXIuYXZhdGFyX2hhc2ggKyAnLycgKyBzaXplICsgJy8nICsgdGhpcy5wcm9wcy51c2VyLmlkICsgJy5wbmcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBqdXN0IGFwcGVuZCBhdmF0YXIgc2l6ZSB0byBmaWxlIHRvIHByb2R1Y2Ugbm8tYXZhdGFyIHBsYWNlaG9sZGVyXG4gICAgICB1cmwgKz0gc2l6ZSArICcucG5nJztcbiAgICB9XG5cbiAgICByZXR1cm4gdXJsO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICByZXR1cm4gPGltZyBzcmM9e3RoaXMuZ2V0U3JjKCl9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPXt0aGlzLnByb3BzLmNsYXNzTmFtZSB8fCAndXNlci1hdmF0YXInfVxuICAgICAgICAgICAgICAgIHRpdGxlPXtnZXR0ZXh0KFwiVXNlciBhdmF0YXJcIil9Lz47XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgfVxufVxuIiwiaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBnZXRSZWFzb25NZXNzYWdlKCkge1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICBpZiAodGhpcy5wcm9wcy5tZXNzYWdlLmh0bWwpIHtcbiAgICAgIHJldHVybiA8ZGl2IGNsYXNzTmFtZT1cImxlYWRcIlxuICAgICAgICAgICAgICAgICAgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw9e3tfX2h0bWw6IHRoaXMucHJvcHMubWVzc2FnZS5odG1sfX0gLz47XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiA8cCBjbGFzc05hbWU9XCJsZWFkXCI+e3RoaXMucHJvcHMubWVzc2FnZS5wbGFpbn08L3A+O1xuICAgIH1cbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG5cbiAgZ2V0RXhwaXJhdGlvbk1lc3NhZ2UoKSB7XG4gICAgaWYgKHRoaXMucHJvcHMuZXhwaXJlcykge1xuICAgICAgaWYgKHRoaXMucHJvcHMuZXhwaXJlcy5pc0FmdGVyKG1vbWVudCgpKSkge1xuICAgICAgICByZXR1cm4gaW50ZXJwb2xhdGUoXG4gICAgICAgICAgZ2V0dGV4dCgnVGhpcyBiYW4gZXhwaXJlcyAlKGV4cGlyZXNfb24pcy4nKSxcbiAgICAgICAgICB7J2V4cGlyZXNfb24nOiB0aGlzLnByb3BzLmV4cGlyZXMuZnJvbU5vdygpfSxcbiAgICAgICAgICB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBnZXR0ZXh0KCdUaGlzIGJhbiBoYXMgZXhwaXJlZC4nKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGdldHRleHQoJ1RoaXMgYmFuIGlzIHBlcm1hbmVudC4nKTtcbiAgICB9XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIHJldHVybiA8ZGl2IGNsYXNzTmFtZT1cInBhZ2UgcGFnZS1lcnJvciBwYWdlLWVycm9yLWJhbmVkXCI+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImNvbnRhaW5lclwiPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm1lc3NhZ2UtcGFuZWxcIj5cblxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibWVzc2FnZS1pY29uXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJtYXRlcmlhbC1pY29uXCI+aGlnaGxpZ2h0X29mZjwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm1lc3NhZ2UtYm9keVwiPlxuICAgICAgICAgICAge3RoaXMuZ2V0UmVhc29uTWVzc2FnZSgpfVxuICAgICAgICAgICAgPHA+e3RoaXMuZ2V0RXhwaXJhdGlvbk1lc3NhZ2UoKX08L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+O1xuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gIH1cbn1cbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgTG9hZGVyIGZyb20gJ21pc2Fnby9jb21wb25lbnRzL2xvYWRlcic7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdXR0b24gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIoKSB7XG4gICAgbGV0IGNvbnRlbnQgPSBudWxsO1xuICAgIGxldCBjbGFzc05hbWUgPSAnYnRuICcgKyB0aGlzLnByb3BzLmNsYXNzTmFtZTtcbiAgICBsZXQgZGlzYWJsZWQgPSB0aGlzLnByb3BzLmRpc2FibGVkO1xuXG4gICAgaWYgKHRoaXMucHJvcHMubG9hZGluZykge1xuICAgICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgICAgY29udGVudCA9IDxMb2FkZXIgLz47XG4gICAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICAgICAgY2xhc3NOYW1lICs9ICcgYnRuLWxvYWRpbmcnO1xuICAgICAgZGlzYWJsZWQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50ID0gdGhpcy5wcm9wcy5jaGlsZHJlbjtcbiAgICB9XG5cbiAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgcmV0dXJuIDxidXR0b24gdHlwZT17dGhpcy5wcm9wcy5vbkNsaWNrID8gJ2J1dHRvbicgOiAnc3VibWl0J31cbiAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZX1cbiAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17ZGlzYWJsZWR9XG4gICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5wcm9wcy5vbkNsaWNrfT5cbiAgICAgIHtjb250ZW50fVxuICAgIDwvYnV0dG9uPjtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG59XG5cblxuQnV0dG9uLmRlZmF1bHRQcm9wcyA9IHtcbiAgY2xhc3NOYW1lOiBcImJ0bi1kZWZhdWx0XCIsXG5cbiAgdHlwZTogXCJzdWJtaXRcIixcblxuICBsb2FkaW5nOiBmYWxzZSxcbiAgZGlzYWJsZWQ6IGZhbHNlLFxuXG4gIG9uQ2xpY2s6IG51bGxcbn07XG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgcmVxdWlyZWQgfSBmcm9tICdtaXNhZ28vdXRpbHMvdmFsaWRhdG9ycyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgdmFsaWRhdGUoKSB7XG4gICAgbGV0IGlzVmFsaWQgPSB0cnVlO1xuICAgIGxldCBlcnJvcnMgPSB7fTtcblxuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLnN0YXRlLnZhbGlkYXRvcnMpIHtcbiAgICAgIGlmICh0aGlzLnN0YXRlLnZhbGlkYXRvcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLnN0YXRlW2tleV07XG4gICAgICAgIGVycm9yc1trZXldID0gdGhpcy52YWxpZGF0ZUZpZWxkKHZhbHVlLCB0aGlzLnN0YXRlLnZhbGlkYXRvcnNba2V5XSk7XG4gICAgICAgIGlmIChlcnJvcnNba2V5XSAhPT0gbnVsbCkge1xuICAgICAgICAgIGlzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpc1ZhbGlkID8gbnVsbCA6IGVycm9ycztcbiAgfVxuXG4gIHZhbGlkYXRlRmllbGQodmFsdWUsIHZhbGlkYXRvcnMpIHtcbiAgICBsZXQgcmVzdWx0ID0gcmVxdWlyZWQoKSh2YWx1ZSk7XG4gICAgbGV0IGVycm9ycyA9IFtdO1xuXG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgcmV0dXJuIFtyZXN1bHRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBpIGluIHZhbGlkYXRvcnMpIHtcbiAgICAgICAgcmVzdWx0ID0gdmFsaWRhdG9yc1tpXSh2YWx1ZSk7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBlcnJvcnMucHVzaChyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycy5sZW5ndGggPyBlcnJvcnMgOiBudWxsO1xuICB9XG5cbiAgY2hhbmdlVmFsdWUobmFtZSwgdmFsdWUpIHtcbiAgICBsZXQgZXJyb3JzID0gbnVsbDtcbiAgICBpZiAodGhpcy5zdGF0ZS52YWxpZGF0b3JzLm5hbWUpIHtcbiAgICAgIGVycm9ycyA9IHRoaXMudmFsaWRhdGVGaWVsZChuYW1lLCB2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICBiaW5kSW5wdXQgPSAobmFtZSkgPT4ge1xuICAgIHJldHVybiAoZXZlbnQpID0+IHtcbiAgICAgIGxldCBuZXdTdGF0ZSA9IHt9O1xuICAgICAgbmV3U3RhdGVbbmFtZV0gPSBldmVudC50YXJnZXQudmFsdWU7XG4gICAgICB0aGlzLnNldFN0YXRlKG5ld1N0YXRlKTtcbiAgICB9XG4gIH1cblxuICBjbGVhbigpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHNlbmQoKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBoYW5kbGVTdWNjZXNzKHN1Y2Nlc3MpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBoYW5kbGVFcnJvcihyZWplY3Rpb24pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBoYW5kbGVTdWJtaXQgPSAoZXZlbnQpID0+IHtcbiAgICAvLyB3ZSBkb24ndCByZWxvYWQgcGFnZSBvbiBzdWJtaXNzaW9uc1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbGVhbigpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsnaXNMb2FkaW5nJzogdHJ1ZX0pO1xuICAgICAgbGV0IHByb21pc2UgPSB0aGlzLnNlbmQoKTtcblxuICAgICAgaWYgKHByb21pc2UpIHtcbiAgICAgICAgcHJvbWlzZS50aGVuKChzdWNjZXNzKSA9PiB7XG4gICAgICAgICAgdGhpcy5oYW5kbGVTdWNjZXNzKHN1Y2Nlc3MpO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeydpc0xvYWRpbmcnOiBmYWxzZX0pO1xuICAgICAgICB9LCAocmVqZWN0aW9uKSA9PiB7XG4gICAgICAgICAgdGhpcy5oYW5kbGVFcnJvcihyZWplY3Rpb24pO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeydpc0xvYWRpbmcnOiBmYWxzZX0pO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeydpc0xvYWRpbmcnOiBmYWxzZX0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xufSIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyKCkge1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICByZXR1cm4gPGRpdiBjbGFzc05hbWU9XCJsb2FkZXItY29tcGFjdFwiPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJsb2FkZXItc3Bpbm5pbmctd2hlZWxcIj48L2Rpdj5cbiAgICA8L2Rpdj47XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgfVxufVxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIoKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIHJldHVybiA8ZGl2IGNsYXNzTmFtZT1cIm1vZGFsLWRpYWxvZyBtb2RhbC1yZWdpc3RlclwiPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJtb2RhbC1jb250ZW50XCI+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibW9kYWwtaGVhZGVyXCI+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiY2xvc2VcIiBkYXRhLWRpc21pc3M9XCJtb2RhbFwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPjxzcGFuIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiZ0aW1lczs8L3NwYW4+PC9idXR0b24+XG4gICAgICAgICAgPGg0IGNsYXNzTmFtZT1cIm1vZGFsLXRpdGxlXCI+e2dldHRleHQoXCJSZWdpc3RlclwiKX08L2g0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJtb2RhbC1ib2R5XCI+XG4gICAgICAgICAgPHA+VGhpcyB3aWxsIGJlIHJlZ2lzdHJhdGlvbiBmb3JtITwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibW9kYWwtZm9vdGVyXCI+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiYnRuIGJ0bi1kZWZhdWx0XCIgZGF0YS1kaXNtaXNzPVwibW9kYWxcIj5DbG9zZTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PjtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG59XG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbmltcG9ydCBtaXNhZ28gZnJvbSAnbWlzYWdvL2luZGV4JztcbmltcG9ydCBCdXR0b24gZnJvbSAnbWlzYWdvL2NvbXBvbmVudHMvYnV0dG9uJzsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5pbXBvcnQgRm9ybSBmcm9tICdtaXNhZ28vY29tcG9uZW50cy9mb3JtJztcbmltcG9ydCBhamF4IGZyb20gJ21pc2Fnby9zZXJ2aWNlcy9hamF4JztcbmltcG9ydCBtb2RhbCBmcm9tICdtaXNhZ28vc2VydmljZXMvbW9kYWwnO1xuaW1wb3J0IHNuYWNrYmFyIGZyb20gJ21pc2Fnby9zZXJ2aWNlcy9zbmFja2Jhcic7XG5pbXBvcnQgc2hvd0Jhbm5lZFBhZ2UgZnJvbSAnbWlzYWdvL3V0aWxzL2Jhbm5lZC1wYWdlJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgZXh0ZW5kcyBGb3JtIHtcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgJ2lzTG9hZGluZyc6IGZhbHNlLFxuICAgICAgJ3Nob3dBY3RpdmF0aW9uJzogZmFsc2UsXG5cbiAgICAgICd1c2VybmFtZSc6ICcnLFxuICAgICAgJ3Bhc3N3b3JkJzogJycsXG5cbiAgICAgIHZhbGlkYXRvcnM6IHtcbiAgICAgICAgJ3VzZXJuYW1lJzogW10sXG4gICAgICAgICdwYXNzd29yZCc6IFtdXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIGNsZWFuKCkge1xuICAgIGlmICh0aGlzLnZhbGlkYXRlKCkpIHtcbiAgICAgIHNuYWNrYmFyLmVycm9yKGdldHRleHQoXCJGaWxsIG91dCBib3RoIGZpZWxkcy5cIikpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBzZW5kKCkge1xuICAgIHJldHVybiBhamF4LnBvc3QobWlzYWdvLmdldCgnQVVUSF9BUEknKSwge1xuICAgICAgJ3VzZXJuYW1lJzogdGhpcy5zdGF0ZS51c2VybmFtZSxcbiAgICAgICdwYXNzd29yZCc6IHRoaXMuc3RhdGUucGFzc3dvcmRcbiAgICB9KTtcbiAgfVxuXG4gIGhhbmRsZVN1Y2Nlc3MoKSB7XG4gICAgbW9kYWwuaGlkZSgpO1xuXG4gICAgbGV0IGZvcm0gPSAkKCcjaGlkZGVuLWxvZ2luLWZvcm0nKTtcblxuICAgIGZvcm0uYXBwZW5kKCc8aW5wdXQgdHlwZT1cInRleHRcIiBuYW1lPVwidXNlcm5hbWVcIiAvPicpO1xuICAgIGZvcm0uYXBwZW5kKCc8aW5wdXQgdHlwZT1cInBhc3N3b3JkXCIgbmFtZT1cInBhc3N3b3JkXCIgLz4nKTtcblxuICAgIC8vIGZpbGwgb3V0IGZvcm0gd2l0aCB1c2VyIGNyZWRlbnRpYWxzIGFuZCBzdWJtaXQgaXQsIHRoaXMgd2lsbCB0ZWxsXG4gICAgLy8gTWlzYWdvIHRvIHJlZGlyZWN0IHVzZXIgYmFjayB0byByaWdodCBwYWdlLCBhbmQgd2lsbCB0cmlnZ2VyIGJyb3dzZXInc1xuICAgIC8vIGtleSByaW5nIGZlYXR1cmVcbiAgICBmb3JtLmZpbmQoJ2lucHV0W3R5cGU9XCJoaWRkZW5cIl0nKS52YWwoYWpheC5nZXRDc3JmVG9rZW4oKSk7XG4gICAgZm9ybS5maW5kKCdpbnB1dFtuYW1lPVwicmVkaXJlY3RfdG9cIl0nKS52YWwod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lKTtcbiAgICBmb3JtLmZpbmQoJ2lucHV0W25hbWU9XCJ1c2VybmFtZVwiXScpLnZhbCh0aGlzLnN0YXRlLnVzZXJuYW1lKTtcbiAgICBmb3JtLmZpbmQoJ2lucHV0W25hbWU9XCJwYXNzd29yZFwiXScpLnZhbCh0aGlzLnN0YXRlLnBhc3N3b3JkKTtcbiAgICBmb3JtLnN1Ym1pdCgpO1xuICB9XG5cbiAgaGFuZGxlRXJyb3IocmVqZWN0aW9uKSB7XG4gICAgaWYgKHJlamVjdGlvbi5zdGF0dXMgPT09IDQwMCkge1xuICAgICAgaWYgKHJlamVjdGlvbi5jb2RlID09PSAnaW5hY3RpdmVfYWRtaW4nKSB7XG4gICAgICAgIHNuYWNrYmFyLmluZm8ocmVqZWN0aW9uLmRldGFpbCk7XG4gICAgICB9IGVsc2UgaWYgKHJlamVjdGlvbi5jb2RlID09PSAnaW5hY3RpdmVfdXNlcicpIHtcbiAgICAgICAgc25hY2tiYXIuaW5mbyhyZWplY3Rpb24uZGV0YWlsKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgJ3Nob3dBY3RpdmF0aW9uJzogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocmVqZWN0aW9uLmNvZGUgPT09ICdiYW5uZWQnKSB7XG4gICAgICAgIHNob3dCYW5uZWRQYWdlKHJlamVjdGlvbi5kZXRhaWwpO1xuICAgICAgICBtb2RhbC5oaWRlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbmFja2Jhci5lcnJvcihyZWplY3Rpb24uZGV0YWlsKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc25hY2tiYXIuYXBpRXJyb3IocmVqZWN0aW9uKTtcbiAgICB9XG4gIH1cblxuICBnZXRBY3RpdmF0aW9uQnV0dG9uKCkge1xuICAgIGlmICh0aGlzLnN0YXRlLnNob3dBY3RpdmF0aW9uKSB7XG4gICAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgICByZXR1cm4gPGEgaHJlZj17bWlzYWdvLmdldCgnUkVRVUVTVF9BQ1RJVkFUSU9OX1VSTCcpfVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImJ0biBidG4tc3VjY2VzcyBidG4tYmxvY2tcIj5cbiAgICAgICAgIHtnZXR0ZXh0KFwiQWN0aXZhdGUgYWNjb3VudFwiKX1cbiAgICAgIDwvYT47XG4gICAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIHJldHVybiA8ZGl2IGNsYXNzTmFtZT1cIm1vZGFsLWRpYWxvZyBtb2RhbC1zbSBtb2RhbC1zaWduLWluXCI+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cIm1vZGFsLWNvbnRlbnRcIj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJtb2RhbC1oZWFkZXJcIj5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzc05hbWU9XCJjbG9zZVwiIGRhdGEtZGlzbWlzcz1cIm1vZGFsXCJcbiAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e2dldHRleHQoXCJDbG9zZVwiKX0+XG4gICAgICAgICAgICA8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj4mdGltZXM7PC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxoNCBjbGFzc05hbWU9XCJtb2RhbC10aXRsZVwiPntnZXR0ZXh0KFwiU2lnbiBpblwiKX08L2g0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGZvcm0gb25TdWJtaXQ9e3RoaXMuaGFuZGxlU3VibWl0fT5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm1vZGFsLWJvZHlcIj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY29udHJvbC1pbnB1dFwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cImlkX3VzZXJuYW1lXCIgY2xhc3NOYW1lPVwiZm9ybS1jb250cm9sXCIgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17dGhpcy5zdGF0ZS5pc0xvYWRpbmd9XG4gICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPXtnZXR0ZXh0KFwiVXNlcm5hbWUgb3IgZS1tYWlsXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5iaW5kSW5wdXQoJ3VzZXJuYW1lJyl9XG4gICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXt0aGlzLnN0YXRlLnVzZXJuYW1lfSAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJjb250cm9sLWlucHV0XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IGlkPVwiaWRfcGFzc3dvcmRcIiBjbGFzc05hbWU9XCJmb3JtLWNvbnRyb2xcIiB0eXBlPVwicGFzc3dvcmRcIlxuICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17dGhpcy5zdGF0ZS5pc0xvYWRpbmd9XG4gICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPXtnZXR0ZXh0KFwiUGFzc3dvcmRcIil9XG4gICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLmJpbmRJbnB1dCgncGFzc3dvcmQnKX1cbiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuc3RhdGUucGFzc3dvcmR9IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm1vZGFsLWZvb3RlclwiPlxuICAgICAgICAgICAge3RoaXMuZ2V0QWN0aXZhdGlvbkJ1dHRvbigpfVxuICAgICAgICAgICAgPEJ1dHRvbiBjbGFzc05hbWU9XCJidG4tcHJpbWFyeSBidG4tYmxvY2tcIlxuICAgICAgICAgICAgICAgICAgICBsb2FkaW5nPXt0aGlzLnN0YXRlLmlzTG9hZGluZ30+XG4gICAgICAgICAgICAgIHtnZXR0ZXh0KFwiU2lnbiBpblwiKX1cbiAgICAgICAgICAgIDwvQnV0dG9uPlxuICAgICAgICAgICAgPGEgaHJlZj17bWlzYWdvLmdldCgnRk9SR09UVEVOX1BBU1NXT1JEX1VSTCcpfVxuICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwiYnRuIGJ0bi1kZWZhdWx0IGJ0bi1ibG9ja1wiPlxuICAgICAgICAgICAgICAge2dldHRleHQoXCJGb3Jnb3QgcGFzc3dvcmQ/XCIpfVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zvcm0+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj47XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgfVxufVxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuY29uc3QgVFlQRVNfQ0xBU1NFUyA9IHtcbiAgJ2luZm8nOiAnYWxlcnQtaW5mbycsXG4gICdzdWNjZXNzJzogJ2FsZXJ0LXN1Y2Nlc3MnLFxuICAnd2FybmluZyc6ICdhbGVydC13YXJuaW5nJyxcbiAgJ2Vycm9yJzogJ2FsZXJ0LWRhbmdlcidcbn07XG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5leHBvcnQgY2xhc3MgU25hY2tiYXIgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBnZXRTbmFja2JhckNsYXNzKCkge1xuICAgIGxldCBzbmFja2JhckNsYXNzID0gJ2FsZXJ0cy1zbmFja2Jhcic7XG4gICAgaWYgKHRoaXMucHJvcHMuaXNWaXNpYmxlKSB7XG4gICAgICBzbmFja2JhckNsYXNzICs9ICcgaW4nO1xuICAgIH0gZWxzZSB7XG4gICAgICBzbmFja2JhckNsYXNzICs9ICcgb3V0JztcbiAgICB9XG4gICAgcmV0dXJuIHNuYWNrYmFyQ2xhc3M7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIHJldHVybiA8ZGl2IGNsYXNzTmFtZT17dGhpcy5nZXRTbmFja2JhckNsYXNzKCl9PlxuICAgICAgPHAgY2xhc3NOYW1lPXsnYWxlcnQgJyArIFRZUEVTX0NMQVNTRVNbdGhpcy5wcm9wcy50eXBlXX0+XG4gICAgICAgIHt0aGlzLnByb3BzLm1lc3NhZ2V9XG4gICAgICA8L3A+XG4gICAgPC9kaXY+O1xuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdChzdGF0ZSkge1xuICByZXR1cm4gc3RhdGUuc25hY2tiYXI7XG59XG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEJ1dHRvbiBmcm9tICdtaXNhZ28vY29tcG9uZW50cy9idXR0b24nOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuaW1wb3J0IG1vZGFsIGZyb20gJ21pc2Fnby9zZXJ2aWNlcy9tb2RhbCc7XG5pbXBvcnQgZHJvcGRvd24gZnJvbSAnbWlzYWdvL3NlcnZpY2VzL21vYmlsZS1uYXZiYXItZHJvcGRvd24nO1xuaW1wb3J0IEF2YXRhciBmcm9tICdtaXNhZ28vY29tcG9uZW50cy9hdmF0YXInOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbmltcG9ydCBTaWduSW5Nb2RhbCBmcm9tICdtaXNhZ28vY29tcG9uZW50cy9zaWduLWluLmpzJztcbmltcG9ydCBSZWdpc3Rlck1vZGFsIGZyb20gJ21pc2Fnby9jb21wb25lbnRzL3JlZ2lzdGVyL3Jvb3QuanMnO1xuXG5leHBvcnQgY2xhc3MgR3Vlc3RNZW51IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgc2hvd1NpZ25Jbk1vZGFsKCkge1xuICAgIG1vZGFsLnNob3coU2lnbkluTW9kYWwpO1xuICB9XG5cbiAgc2hvd1JlZ2lzdGVyTW9kYWwoKSB7XG4gICAgbW9kYWwuc2hvdyhSZWdpc3Rlck1vZGFsKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgcmV0dXJuIDx1bCBjbGFzc05hbWU9XCJkcm9wZG93bi1tZW51IHVzZXItZHJvcGRvd24gZHJvcGRvd24tbWVudS1yaWdodFwiXG4gICAgICAgICAgICAgICByb2xlPVwibWVudVwiPlxuICAgICAgPGxpIGNsYXNzTmFtZT1cImd1ZXN0LXByZXZpZXdcIj5cbiAgICAgICAgPGg0PntnZXR0ZXh0KFwiWW91IGFyZSBicm93c2luZyBhcyBndWVzdC5cIil9PC9oND5cbiAgICAgICAgPHA+XG4gICAgICAgICAge2dldHRleHQoJ1NpZ24gaW4gb3IgcmVnaXN0ZXIgdG8gc3RhcnQgYW5kIHBhcnRpY2lwYXRlIGluIGRpc2N1c3Npb25zLicpfVxuICAgICAgICA8L3A+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwicm93XCI+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImNvbC14cy02XCI+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzc05hbWU9XCJidG4gYnRuLWRlZmF1bHQgYnRuLWJsb2NrXCI+XG4gICAgICAgICAgICAgIFRoeSBTaWduIEluXG4gICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY29sLXhzLTZcIj5cblxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiYnRuIGJ0bi1wcmltYXJ5IGJ0bi1ibG9ja1wiPlxuICAgICAgICAgICAgICBUaHkgUmVnaXN0cnlcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9saT5cbiAgICA8L3VsPjtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBHdWVzdE5hdiBleHRlbmRzIEd1ZXN0TWVudSB7XG4gIHJlbmRlcigpIHtcbiAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgcmV0dXJuIDxkaXYgY2xhc3NOYW1lPVwibmF2IG5hdi1ndWVzdFwiPlxuICAgICAgPEJ1dHRvbiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibmF2YmFyLWJ0biBidG4tZGVmYXVsdFwiXG4gICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMuc2hvd1NpZ25Jbk1vZGFsfT5cbiAgICAgICAgU2lnbiBpblxuICAgICAgPC9CdXR0b24+XG4gICAgICA8QnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzc05hbWU9XCJuYXZiYXItYnRuIGJ0bi1wcmltYXJ5XCJcbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zaG93UmVnaXN0ZXJNb2RhbH0+XG4gICAgICAgIFJlZ2lzdGVyXG4gICAgICA8L0J1dHRvbj5cbiAgICA8L2Rpdj47XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29tcGFjdEd1ZXN0TmF2IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgc2hvd0d1ZXN0TWVudSgpIHtcbiAgICBkcm9wZG93bi5zaG93KEd1ZXN0TWVudSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIHJldHVybiA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBvbkNsaWNrPXt0aGlzLnNob3dHdWVzdE1lbnV9PlxuICAgICAgPEF2YXRhciBzaXplPVwiNjRcIiAvPlxuICAgIDwvYnV0dG9uPjtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG59XG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgR3Vlc3ROYXYsIENvbXBhY3RHdWVzdE5hdiB9IGZyb20gJ21pc2Fnby9jb21wb25lbnRzL3VzZXItbWVudS9ndWVzdC1uYXYnOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbmltcG9ydCBVc2VyTmF2IGZyb20gJ21pc2Fnby9jb21wb25lbnRzL3VzZXItbWVudS91c2VyLW5hdic7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuXG5leHBvcnQgY2xhc3MgVXNlck1lbnUgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIoKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIGlmICh0aGlzLnByb3BzLmlzQXV0aGVudGljYXRlZCkge1xuICAgICAgcmV0dXJuIDxVc2VyTmF2IHVzZXI9e3RoaXMucHJvcHMudXNlcn0gLz47XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiA8R3Vlc3ROYXYgLz47XG4gICAgfVxuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENvbXBhY3RVc2VyTWVudSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlcigpIHtcbiAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgaWYgKHRoaXMucHJvcHMuaXNBdXRoZW50aWNhdGVkKSB7XG4gICAgICByZXR1cm4gPFVzZXJOYXYgdXNlcj17dGhpcy5wcm9wcy51c2VyfSAvPjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDxDb21wYWN0R3Vlc3ROYXYgLz47XG4gICAgfVxuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdChzdGF0ZSkge1xuICByZXR1cm4gc3RhdGUuYXV0aDtcbn1cbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFVzZXJOYXYgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIoKSB7XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIHJldHVybiA8dWwgY2xhc3M9XCJ1bCBuYXYgbmF2YmFyLW5hdiBuYXYtdXNlclwiPlxuXG4gICAgPC91bD47XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgfVxufVxuIiwiaW1wb3J0IE9yZGVyZWRMaXN0IGZyb20gJ21pc2Fnby91dGlscy9vcmRlcmVkLWxpc3QnO1xuXG5leHBvcnQgY2xhc3MgTWlzYWdvIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5faW5pdGlhbGl6ZXJzID0gW107XG4gICAgdGhpcy5fY29udGV4dCA9IHt9O1xuICB9XG5cbiAgYWRkSW5pdGlhbGl6ZXIoaW5pdGlhbGl6ZXIpIHtcbiAgICB0aGlzLl9pbml0aWFsaXplcnMucHVzaCh7XG4gICAgICBrZXk6IGluaXRpYWxpemVyLm5hbWUsXG5cbiAgICAgIGl0ZW06IGluaXRpYWxpemVyLmluaXRpYWxpemVyLFxuXG4gICAgICBhZnRlcjogaW5pdGlhbGl6ZXIuYWZ0ZXIsXG4gICAgICBiZWZvcmU6IGluaXRpYWxpemVyLmJlZm9yZVxuICAgIH0pO1xuICB9XG5cbiAgaW5pdChjb250ZXh0KSB7XG4gICAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG5cbiAgICB2YXIgaW5pdE9yZGVyID0gbmV3IE9yZGVyZWRMaXN0KHRoaXMuX2luaXRpYWxpemVycykub3JkZXJlZFZhbHVlcygpO1xuICAgIGluaXRPcmRlci5mb3JFYWNoKGluaXRpYWxpemVyID0+IHtcbiAgICAgIGluaXRpYWxpemVyKHRoaXMpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gY29udGV4dCBhY2Nlc3NvcnNcbiAgaGFzKGtleSkge1xuICAgIHJldHVybiB0aGlzLl9jb250ZXh0Lmhhc093blByb3BlcnR5KGtleSk7XG4gIH1cblxuICBnZXQoa2V5LCBmYWxsYmFjaykge1xuICAgIGlmICh0aGlzLmhhcyhrZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY29udGV4dFtrZXldO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsbGJhY2sgfHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufVxuXG4vLyBjcmVhdGUgIHNpbmdsZXRvblxudmFyIG1pc2FnbyA9IG5ldyBNaXNhZ28oKTtcblxuLy8gZXhwb3NlIGl0IGdsb2JhbGx5XG5nbG9iYWwubWlzYWdvID0gbWlzYWdvO1xuXG4vLyBhbmQgZXhwb3J0IGl0IGZvciB0ZXN0cyBhbmQgc3R1ZmZcbmV4cG9ydCBkZWZhdWx0IG1pc2FnbztcbiIsImltcG9ydCBtaXNhZ28gZnJvbSAnbWlzYWdvL2luZGV4JztcbmltcG9ydCBhamF4IGZyb20gJ21pc2Fnby9zZXJ2aWNlcy9hamF4JztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaW5pdGlhbGl6ZXIoKSB7XG4gIGFqYXguaW5pdChtaXNhZ28uZ2V0KCdDU1JGX0NPT0tJRV9OQU1FJykpO1xufVxuXG5taXNhZ28uYWRkSW5pdGlhbGl6ZXIoe1xuICBuYW1lOiAnYWpheCcsXG4gIGluaXRpYWxpemVyOiBpbml0aWFsaXplclxufSk7XG4iLCJpbXBvcnQgbWlzYWdvIGZyb20gJ21pc2Fnby9pbmRleCc7XG5pbXBvcnQgcmVkdWNlciBmcm9tICdtaXNhZ28vcmVkdWNlcnMvYXV0aCc7XG5pbXBvcnQgc3RvcmUgZnJvbSAnbWlzYWdvL3NlcnZpY2VzL3N0b3JlJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaW5pdGlhbGl6ZXIoY29udGV4dCkge1xuICBzdG9yZS5hZGRSZWR1Y2VyKCdhdXRoJywgcmVkdWNlciwge1xuICAgICdpc0F1dGhlbnRpY2F0ZWQnOiBjb250ZXh0LmdldCgnaXNBdXRoZW50aWNhdGVkJyksXG4gICAgJ2lzQW5vbnltb3VzJzogIWNvbnRleHQuZ2V0KCdpc0F1dGhlbnRpY2F0ZWQnKSxcblxuICAgICd1c2VyJzogY29udGV4dC5nZXQoJ3VzZXInKVxuICB9KTtcbn1cblxubWlzYWdvLmFkZEluaXRpYWxpemVyKHtcbiAgbmFtZTogJ3JlZHVjZXI6YXV0aCcsXG4gIGluaXRpYWxpemVyOiBpbml0aWFsaXplcixcbiAgYmVmb3JlOiAnc3RvcmUnXG59KTtcbiIsImltcG9ydCBtaXNhZ28gZnJvbSAnbWlzYWdvL2luZGV4JztcbmltcG9ydCBkcm9wZG93biBmcm9tICdtaXNhZ28vc2VydmljZXMvbW9iaWxlLW5hdmJhci1kcm9wZG93bic7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGluaXRpYWxpemVyKCkge1xuICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2JpbGUtbmF2YmFyLWRyb3Bkb3duLW1vdW50Jyk7XG4gIGlmIChlbGVtZW50KSB7XG4gICAgZHJvcGRvd24uaW5pdChlbGVtZW50KTtcbiAgfVxufVxuXG5taXNhZ28uYWRkSW5pdGlhbGl6ZXIoe1xuICBuYW1lOiAnZHJvcGRvd24nLFxuICBpbml0aWFsaXplcjogaW5pdGlhbGl6ZXIsXG4gIGJlZm9yZTogJ3N0b3JlJ1xufSk7XG4iLCJpbXBvcnQgbWlzYWdvIGZyb20gJ21pc2Fnby9pbmRleCc7XG5pbXBvcnQgbW9kYWwgZnJvbSAnbWlzYWdvL3NlcnZpY2VzL21vZGFsJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaW5pdGlhbGl6ZXIoKSB7XG4gIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vZGFsLW1vdW50Jyk7XG4gIGlmIChlbGVtZW50KSB7XG4gICAgbW9kYWwuaW5pdChlbGVtZW50KTtcbiAgfVxufVxuXG5taXNhZ28uYWRkSW5pdGlhbGl6ZXIoe1xuICBuYW1lOiAnbW9kYWwnLFxuICBpbml0aWFsaXplcjogaW5pdGlhbGl6ZXIsXG4gIGJlZm9yZTogJ3N0b3JlJ1xufSk7XG4iLCJpbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgbWlzYWdvIGZyb20gJ21pc2Fnby9pbmRleCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGluaXRpYWxpemVyKCkge1xuICBtb21lbnQubG9jYWxlKCQoJ2h0bWwnKS5hdHRyKCdsYW5nJykpO1xufVxuXG5taXNhZ28uYWRkSW5pdGlhbGl6ZXIoe1xuICBuYW1lOiAnbW9tZW50JyxcbiAgaW5pdGlhbGl6ZXI6IGluaXRpYWxpemVyXG59KTtcbiIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgbWlzYWdvIGZyb20gJ21pc2Fnby9pbmRleCc7XG5pbXBvcnQgeyBTbmFja2Jhciwgc2VsZWN0IH0gZnJvbSAnbWlzYWdvL2NvbXBvbmVudHMvc25hY2tiYXInO1xuaW1wb3J0IG1vdW50IGZyb20gJ21pc2Fnby91dGlscy9tb3VudC1jb21wb25lbnQnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpbml0aWFsaXplcigpIHtcbiAgbW91bnQoY29ubmVjdChzZWxlY3QpKFNuYWNrYmFyKSwgJ3NuYWNrYmFyLW1vdW50Jyk7XG59XG5cbm1pc2Fnby5hZGRJbml0aWFsaXplcih7XG4gIG5hbWU6ICdjb21wb25lbnQ6c25hY2tiYXInLFxuICBpbml0aWFsaXplcjogaW5pdGlhbGl6ZXIsXG4gIGFmdGVyOiAnc25hY2tiYXInXG59KTtcbiIsImltcG9ydCBtaXNhZ28gZnJvbSAnbWlzYWdvL2luZGV4JztcbmltcG9ydCByZWR1Y2VyLCB7IGluaXRpYWxTdGF0ZSB9IGZyb20gJ21pc2Fnby9yZWR1Y2Vycy9zbmFja2Jhcic7XG5pbXBvcnQgc3RvcmUgZnJvbSAnbWlzYWdvL3NlcnZpY2VzL3N0b3JlJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaW5pdGlhbGl6ZXIoKSB7XG4gIHN0b3JlLmFkZFJlZHVjZXIoJ3NuYWNrYmFyJywgcmVkdWNlciwgaW5pdGlhbFN0YXRlKTtcbn1cblxubWlzYWdvLmFkZEluaXRpYWxpemVyKHtcbiAgbmFtZTogJ3JlZHVjZXI6c25hY2tiYXInLFxuICBpbml0aWFsaXplcjogaW5pdGlhbGl6ZXIsXG4gIGJlZm9yZTogJ3N0b3JlJ1xufSk7XG4iLCJpbXBvcnQgbWlzYWdvIGZyb20gJ21pc2Fnby9pbmRleCc7XG5pbXBvcnQgc25hY2tiYXIgZnJvbSAnbWlzYWdvL3NlcnZpY2VzL3NuYWNrYmFyJztcbmltcG9ydCBzdG9yZSBmcm9tICdtaXNhZ28vc2VydmljZXMvc3RvcmUnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpbml0aWFsaXplcigpIHtcbiAgc25hY2tiYXIuaW5pdChzdG9yZSk7XG59XG5cbm1pc2Fnby5hZGRJbml0aWFsaXplcih7XG4gIG5hbWU6ICdzbmFja2JhcicsXG4gIGluaXRpYWxpemVyOiBpbml0aWFsaXplcixcbiAgYWZ0ZXI6ICdzdG9yZSdcbn0pO1xuIiwiaW1wb3J0IG1pc2FnbyBmcm9tICdtaXNhZ28vaW5kZXgnO1xuaW1wb3J0IHN0b3JlIGZyb20gJ21pc2Fnby9zZXJ2aWNlcy9zdG9yZSc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGluaXRpYWxpemVyKCkge1xuICBzdG9yZS5pbml0KCk7XG59XG5cbm1pc2Fnby5hZGRJbml0aWFsaXplcih7XG4gIG5hbWU6ICdzdG9yZScsXG4gIGluaXRpYWxpemVyOiBpbml0aWFsaXplcixcbiAgYmVmb3JlOiAnX2VuZCdcbn0pO1xuIiwiaW1wb3J0IG1pc2FnbyBmcm9tICdtaXNhZ28vaW5kZXgnO1xuaW1wb3J0IHJlZHVjZXIsIHsgaW5pdGlhbFN0YXRlIH0gZnJvbSAnbWlzYWdvL3JlZHVjZXJzL3RpY2snO1xuaW1wb3J0IHN0b3JlIGZyb20gJ21pc2Fnby9zZXJ2aWNlcy9zdG9yZSc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGluaXRpYWxpemVyKCkge1xuICBzdG9yZS5hZGRSZWR1Y2VyKCd0aWNrJywgcmVkdWNlciwgaW5pdGlhbFN0YXRlKTtcbn1cblxubWlzYWdvLmFkZEluaXRpYWxpemVyKHtcbiAgbmFtZTogJ3JlZHVjZXI6dGljaycsXG4gIGluaXRpYWxpemVyOiBpbml0aWFsaXplcixcbiAgYmVmb3JlOiAnc3RvcmUnXG59KTtcbiIsImltcG9ydCBtaXNhZ28gZnJvbSAnbWlzYWdvL2luZGV4JztcbmltcG9ydCB7IGRvVGljayB9IGZyb20gJ21pc2Fnby9yZWR1Y2Vycy90aWNrJztcbmltcG9ydCBzdG9yZSBmcm9tICdtaXNhZ28vc2VydmljZXMvc3RvcmUnO1xuXG5jb25zdCBUSUNLX1BFUklPRCA9IDUwICogMTAwMDsgLy9kbyB0aGUgdGljayBldmVyeSA1MHNcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaW5pdGlhbGl6ZXIoKSB7XG4gIHdpbmRvdy5zZXRJbnRlcnZhbChmdW5jdGlvbigpIHtcbiAgICBzdG9yZS5kaXNwYXRjaChkb1RpY2soKSk7XG4gIH0sIFRJQ0tfUEVSSU9EKTtcbn1cblxubWlzYWdvLmFkZEluaXRpYWxpemVyKHtcbiAgbmFtZTogJ3RpY2stc3RhcnQnLFxuICBpbml0aWFsaXplcjogaW5pdGlhbGl6ZXIsXG4gIGFmdGVyOiAnc3RvcmUnXG59KTtcbiIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgbWlzYWdvIGZyb20gJ21pc2Fnby9pbmRleCc7XG5pbXBvcnQgeyBVc2VyTWVudSwgQ29tcGFjdFVzZXJNZW51LCBzZWxlY3QgfSBmcm9tICdtaXNhZ28vY29tcG9uZW50cy91c2VyLW1lbnUvcm9vdCc7XG5pbXBvcnQgbW91bnQgZnJvbSAnbWlzYWdvL3V0aWxzL21vdW50LWNvbXBvbmVudCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGluaXRpYWxpemVyKCkge1xuICBtb3VudChjb25uZWN0KHNlbGVjdCkoVXNlck1lbnUpLCAndXNlci1tZW51LW1vdW50Jyk7XG4gIG1vdW50KGNvbm5lY3Qoc2VsZWN0KShDb21wYWN0VXNlck1lbnUpLCAndXNlci1tZW51LWNvbXBhY3QtbW91bnQnKTtcbn1cblxubWlzYWdvLmFkZEluaXRpYWxpemVyKHtcbiAgbmFtZTogJ2NvbXBvbmVudDp1c2VyLW1lbnUnLFxuICBpbml0aWFsaXplcjogaW5pdGlhbGl6ZXIsXG4gIGFmdGVyOiAnc3RvcmUnXG59KTtcbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGF1dGgoc3RhdGU9e30sIGFjdGlvbj1udWxsKSB7XG4gIHJldHVybiBzdGF0ZTtcbn1cbiIsImV4cG9ydCB2YXIgaW5pdGlhbFN0YXRlID0ge1xuICB0eXBlOiAnaW5mbycsXG4gIG1lc3NhZ2U6ICcnLFxuICBpc1Zpc2libGU6IGZhbHNlXG59O1xuXG5leHBvcnQgY29uc3QgU0hPV19TTkFDS0JBUiA9ICdTSE9XX1NOQUNLQkFSJztcbmV4cG9ydCBjb25zdCBISURFX1NOQUNLQkFSID0gJ0hJREVfU05BQ0tCQVInO1xuXG5leHBvcnQgZnVuY3Rpb24gc2hvd1NuYWNrYmFyKG1lc3NhZ2UsIHR5cGUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBTSE9XX1NOQUNLQkFSLFxuICAgIG1lc3NhZ2UsXG4gICAgbWVzc2FnZVR5cGU6IHR5cGVcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhpZGVTbmFja2JhcigpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBISURFX1NOQUNLQkFSXG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNuYWNrYmFyKHN0YXRlPWluaXRpYWxTdGF0ZSwgYWN0aW9uPW51bGwpIHtcbiAgaWYgKGFjdGlvbi50eXBlID09PSBTSE9XX1NOQUNLQkFSKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IGFjdGlvbi5tZXNzYWdlVHlwZSxcbiAgICAgIG1lc3NhZ2U6IGFjdGlvbi5tZXNzYWdlLFxuICAgICAgaXNWaXNpYmxlOiB0cnVlXG4gICAgfTtcbiAgfSBlbHNlIGlmIChhY3Rpb24udHlwZSA9PT0gSElERV9TTkFDS0JBUikge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBpc1Zpc2libGU6IGZhbHNlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG4iLCJleHBvcnQgdmFyIGluaXRpYWxTdGF0ZSA9IHtcbiAgdGljazogMFxufTtcblxuZXhwb3J0IGNvbnN0IFRJQ0sgPSAnVElDSyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBkb1RpY2soKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogVElDS1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0aWNrKHN0YXRlPWluaXRpYWxTdGF0ZSwgYWN0aW9uPW51bGwpIHtcbiAgaWYgKGFjdGlvbi50eXBlID09PSBUSUNLKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHRpY2s6IHN0YXRlLnRpY2sgKyAxXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG4iLCJleHBvcnQgY2xhc3MgQWpheCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX2Nvb2tpZU5hbWUgPSBudWxsO1xuICAgIHRoaXMuX2NzcmZUb2tlbiA9IG51bGw7XG4gIH1cblxuICBpbml0KGNvb2tpZU5hbWUpIHtcbiAgICB0aGlzLl9jb29raWVOYW1lID0gY29va2llTmFtZTtcbiAgICB0aGlzLl9jc3JmVG9rZW4gPSB0aGlzLmdldENzcmZUb2tlbigpO1xuICB9XG5cbiAgZ2V0Q3NyZlRva2VuKCkge1xuICAgIGlmIChkb2N1bWVudC5jb29raWUuaW5kZXhPZih0aGlzLl9jb29raWVOYW1lKSAhPT0gLTEpIHtcbiAgICAgIHZhciBjb29raWVSZWdleCA9IG5ldyBSZWdFeHAodGhpcy5fY29va2llTmFtZSArICdcXD0oW147XSopJyk7XG4gICAgICB2YXIgY29va2llID0gZG9jdW1lbnQuY29va2llLm1hdGNoKGNvb2tpZVJlZ2V4KVswXTtcbiAgICAgIHJldHVybiBjb29raWUgPyBjb29raWUuc3BsaXQoJz0nKVsxXSA6IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHJlcXVlc3QobWV0aG9kLCB1cmwsIGRhdGEpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIHhociA9IHtcbiAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1gtQ1NSRlRva2VuJzogc2VsZi5fY3NyZlRva2VuXG4gICAgICAgIH0sXG5cbiAgICAgICAgZGF0YTogZGF0YSB8fCB7fSxcbiAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcblxuICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgfSxcblxuICAgICAgICBlcnJvcjogZnVuY3Rpb24oanFYSFIpIHtcbiAgICAgICAgICB2YXIgcmVqZWN0aW9uID0ganFYSFIucmVzcG9uc2VKU09OIHx8IHt9O1xuXG4gICAgICAgICAgcmVqZWN0aW9uLnN0YXR1cyA9IGpxWEhSLnN0YXR1cztcbiAgICAgICAgICByZWplY3Rpb24uc3RhdHVzVGV4dCA9IGpxWEhSLnN0YXR1c1RleHQ7XG5cbiAgICAgICAgICByZWplY3QocmVqZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgJC5hamF4KHhocik7XG4gICAgfSk7XG4gIH1cblxuICBnZXQodXJsKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnR0VUJywgdXJsKTtcbiAgfVxuXG4gIHBvc3QodXJsLCBkYXRhKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnUE9TVCcsIHVybCwgZGF0YSk7XG4gIH1cblxuICBwYXRjaCh1cmwsIGRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdQQVRDSCcsIHVybCwgZGF0YSk7XG4gIH1cblxuICBwdXQodXJsLCBkYXRhKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnUFVUJywgdXJsLCBkYXRhKTtcbiAgfVxuXG4gIGRlbGV0ZSh1cmwpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdERUxFVEUnLCB1cmwpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBBamF4KCk7XG4iLCJpbXBvcnQgbW91bnQgZnJvbSAnbWlzYWdvL3V0aWxzL21vdW50LWNvbXBvbmVudCc7XG5cbmV4cG9ydCBjbGFzcyBNb2JpbGVOYXZiYXJEcm9wZG93biB7XG4gIGluaXQoZWxlbWVudCkge1xuICAgIHRoaXMuX2VsZW1lbnQgPSBlbGVtZW50O1xuICAgIHRoaXMuX2NvbXBvbmVudCA9IG51bGw7XG4gIH1cblxuICBzaG93KGNvbXBvbmVudCkge1xuICAgIGlmICh0aGlzLl9jb21wb25lbnQgPT09IGNvbXBvbmVudCkge1xuICAgICAgdGhpcy5oaWRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2NvbXBvbmVudCA9IGNvbXBvbmVudDtcbiAgICAgIG1vdW50KGNvbXBvbmVudCwgdGhpcy5fZWxlbWVudC5pZCk7XG4gICAgICAkKHRoaXMuX2VsZW1lbnQpLmFkZENsYXNzKCdvcGVuJyk7XG4gICAgfVxuICB9XG5cbiAgaGlkZSgpIHtcbiAgICAkKHRoaXMuX2VsZW1lbnQpLnJlbW92ZUNsYXNzKCdvcGVuJyk7XG4gICAgdGhpcy5fY29tcG9uZW50ID0gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgTW9iaWxlTmF2YmFyRHJvcGRvd24oKTtcbiIsImltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xuaW1wb3J0IG1vdW50IGZyb20gJ21pc2Fnby91dGlscy9tb3VudC1jb21wb25lbnQnO1xuXG5leHBvcnQgY2xhc3MgTW9kYWwge1xuICBpbml0KGVsZW1lbnQpIHtcbiAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIHRoaXMuX21vZGFsID0gJChlbGVtZW50KS5tb2RhbCh7c2hvdzogZmFsc2V9KTtcblxuICAgIHRoaXMuX21vZGFsLm9uKCdoaWRkZW4uYnMubW9kYWwnLCAoKSA9PiB7XG4gICAgICBSZWFjdERPTS51bm1vdW50Q29tcG9uZW50QXROb2RlKHRoaXMuX2VsZW1lbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgc2hvdyhjb21wb25lbnQpIHtcbiAgICBtb3VudChjb21wb25lbnQsIHRoaXMuX2VsZW1lbnQuaWQpO1xuICAgIHRoaXMuX21vZGFsLm1vZGFsKCdzaG93Jyk7XG4gIH1cblxuICBoaWRlKCkge1xuICAgIHRoaXMuX21vZGFsLm1vZGFsKCdoaWRlJyk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IE1vZGFsKCk7XG4iLCJpbXBvcnQgeyBzaG93U25hY2tiYXIsIGhpZGVTbmFja2JhciB9IGZyb20gJ21pc2Fnby9yZWR1Y2Vycy9zbmFja2Jhcic7XG5cbmNvbnN0IEhJREVfQU5JTUFUSU9OX0xFTkdUSCA9IDMwMDtcbmNvbnN0IE1FU1NBR0VfU0hPV19MRU5HVEggPSA1MDAwO1xuXG5leHBvcnQgY2xhc3MgU25hY2tiYXIge1xuICBpbml0KHN0b3JlKSB7XG4gICAgdGhpcy5fc3RvcmUgPSBzdG9yZTtcbiAgICB0aGlzLl90aW1lb3V0ID0gbnVsbDtcbiAgfVxuXG4gIGFsZXJ0KG1lc3NhZ2UsIHR5cGUpIHtcbiAgICBpZiAodGhpcy5fdGltZW91dCkge1xuICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcbiAgICAgIHRoaXMuX3N0b3JlLmRpc3BhdGNoKGhpZGVTbmFja2JhcigpKTtcblxuICAgICAgdGhpcy5fdGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5fdGltZW91dCA9IG51bGw7XG4gICAgICAgIHRoaXMuYWxlcnQobWVzc2FnZSwgdHlwZSk7XG4gICAgICB9LCBISURFX0FOSU1BVElPTl9MRU5HVEgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zdG9yZS5kaXNwYXRjaChzaG93U25hY2tiYXIobWVzc2FnZSwgdHlwZSkpO1xuICAgICAgdGhpcy5fdGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5fc3RvcmUuZGlzcGF0Y2goaGlkZVNuYWNrYmFyKCkpO1xuICAgICAgICB0aGlzLl90aW1lb3V0ID0gbnVsbDtcbiAgICAgIH0sIE1FU1NBR0VfU0hPV19MRU5HVEgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHNob3J0aGFuZHMgZm9yIG1lc3NhZ2UgdHlwZXNcblxuICBpbmZvKG1lc3NhZ2UpIHtcbiAgICB0aGlzLmFsZXJ0KG1lc3NhZ2UsICdpbmZvJyk7XG4gIH1cblxuICBzdWNjZXNzKG1lc3NhZ2UpIHtcbiAgICB0aGlzLmFsZXJ0KG1lc3NhZ2UsICdzdWNjZXNzJyk7XG4gIH1cblxuICB3YXJuaW5nKG1lc3NhZ2UpIHtcbiAgICB0aGlzLmFsZXJ0KG1lc3NhZ2UsICd3YXJuaW5nJyk7XG4gIH1cblxuICBlcnJvcihtZXNzYWdlKSB7XG4gICAgdGhpcy5hbGVydChtZXNzYWdlLCAnZXJyb3InKTtcbiAgfVxuXG4gIC8vIHNob3J0aGFuZCBmb3IgYXBpIGVycm9yc1xuICBhcGlFcnJvcihyZWplY3Rpb24pIHtcbiAgICBsZXQgbWVzc2FnZSA9IGdldHRleHQoXCJVbmtub3duIGVycm9yIGhhcyBvY2N1cmVkLlwiKTtcblxuICAgIGlmIChyZWplY3Rpb24uc3RhdHVzID09PSAwKSB7XG4gICAgICBtZXNzYWdlID0gZ2V0dGV4dChcIkxvc3QgY29ubmVjdGlvbiB3aXRoIGFwcGxpY2F0aW9uLlwiKTtcbiAgICB9XG5cbiAgICBpZiAocmVqZWN0aW9uLnN0YXR1cyA9PT0gNDAwICYmIHJlamVjdGlvbi5kZXRhaWwpIHtcbiAgICAgIG1lc3NhZ2UgPSByZWplY3Rpb24uZGV0YWlsO1xuICAgIH1cblxuICAgIGlmIChyZWplY3Rpb24uc3RhdHVzID09PSA0MDMpIHtcbiAgICAgIG1lc3NhZ2UgPSByZWplY3Rpb24uZGV0YWlsO1xuICAgICAgaWYgKG1lc3NhZ2UgPT09IFwiUGVybWlzc2lvbiBkZW5pZWRcIikge1xuICAgICAgICBtZXNzYWdlID0gZ2V0dGV4dChcbiAgICAgICAgICBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb24gdG8gcGVyZm9ybSB0aGlzIGFjdGlvbi5cIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlamVjdGlvbi5zdGF0dXMgPT09IDQwNCkge1xuICAgICAgbWVzc2FnZSA9IGdldHRleHQoXCJBY3Rpb24gbGluayBpcyBpbnZhbGlkLlwiKTtcbiAgICB9XG5cbiAgICB0aGlzLmVycm9yKG1lc3NhZ2UpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBTbmFja2JhcigpO1xuIiwiaW1wb3J0IHsgY29tYmluZVJlZHVjZXJzLCBjcmVhdGVTdG9yZSB9IGZyb20gJ3JlZHV4JztcblxuZXhwb3J0IGNsYXNzIFN0b3JlV3JhcHBlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX3N0b3JlID0gbnVsbDtcbiAgICB0aGlzLl9yZWR1Y2VycyA9IHt9O1xuICAgIHRoaXMuX2luaXRpYWxTdGF0ZSA9IHt9O1xuICB9XG5cbiAgYWRkUmVkdWNlcihuYW1lLCByZWR1Y2VyLCBpbml0aWFsU3RhdGUpIHtcbiAgICB0aGlzLl9yZWR1Y2Vyc1tuYW1lXSA9IHJlZHVjZXI7XG4gICAgdGhpcy5faW5pdGlhbFN0YXRlW25hbWVdID0gaW5pdGlhbFN0YXRlO1xuICB9XG5cbiAgaW5pdCgpIHtcbiAgICB0aGlzLl9zdG9yZSA9IGNyZWF0ZVN0b3JlKFxuICAgICAgY29tYmluZVJlZHVjZXJzKHRoaXMuX3JlZHVjZXJzKSwgdGhpcy5faW5pdGlhbFN0YXRlKTtcbiAgfVxuXG4gIGdldFN0b3JlKCkge1xuICAgIHJldHVybiB0aGlzLl9zdG9yZTtcbiAgfVxuXG4gIC8vIFN0b3JlIEFQSVxuXG4gIGdldFN0YXRlKCkge1xuICAgIHJldHVybiB0aGlzLl9zdG9yZS5nZXRTdGF0ZSgpO1xuICB9XG5cbiAgZGlzcGF0Y2goYWN0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JlLmRpc3BhdGNoKGFjdGlvbik7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IFN0b3JlV3JhcHBlcigpO1xuIiwiaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuaW1wb3J0IFJlYWN0RE9NIGZyb20gJ3JlYWN0LWRvbSc7XG5pbXBvcnQgeyBQcm92aWRlciwgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JzsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG5pbXBvcnQgQmFubmVkUGFnZSBmcm9tICdtaXNhZ28vY29tcG9uZW50cy9iYW5uZWQtcGFnZSc7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuaW1wb3J0IG1pc2FnbyBmcm9tICdtaXNhZ28vaW5kZXgnO1xuaW1wb3J0IHN0b3JlIGZyb20gJ21pc2Fnby9zZXJ2aWNlcy9zdG9yZSc7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuXG4vKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG5sZXQgc2VsZWN0ID0gZnVuY3Rpb24oc3RhdGUpIHtcbiAgcmV0dXJuIHN0YXRlLnRpY2s7XG59O1xuXG5sZXQgUmVkcmF3ZWRCYW5uZWRQYWdlID0gY29ubmVjdChzZWxlY3QpKEJhbm5lZFBhZ2UpO1xuLyoganNoaW50IGlnbm9yZTplbmQgKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oYmFuLCBjaGFuZ2VTdGF0ZSkge1xuICBSZWFjdERPTS5yZW5kZXIoXG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIDxQcm92aWRlciBzdG9yZT17c3RvcmUuZ2V0U3RvcmUoKX0+XG4gICAgICA8UmVkcmF3ZWRCYW5uZWRQYWdlIG1lc3NhZ2U9e2Jhbi5tZXNzYWdlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICBleHBpcmVzPXtiYW4uZXhwaXJlc19vbiA/IG1vbWVudChiYW4uZXhwaXJlc19vbikgOiBudWxsfSAvPlxuICAgIDwvUHJvdmlkZXI+LFxuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BhZ2UtbW91bnQnKVxuICApO1xuXG4gIGlmICh0eXBlb2YgY2hhbmdlU3RhdGUgPT09ICd1bmRlZmluZWQnIHx8ICFjaGFuZ2VTdGF0ZSkge1xuICAgIGxldCBmb3J1bU5hbWUgPSBtaXNhZ28uZ2V0KCdTRVRUSU5HUycpLmZvcnVtX25hbWU7XG4gICAgZG9jdW1lbnQudGl0bGUgPSBnZXR0ZXh0KFwiWW91IGFyZSBiYW5uZWRcIikgKyAnIHwgJyArIGZvcnVtTmFtZTtcbiAgICB3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUoe30sIFwiXCIsIG1pc2Fnby5nZXQoJ0JBTk5FRF9VUkwnKSk7XG4gIH1cbn0iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdyZWFjdC1yZWR1eCc7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuaW1wb3J0IHN0b3JlIGZyb20gJ21pc2Fnby9zZXJ2aWNlcy9zdG9yZSc7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtb3VudChDb21wb25lbnQsIHJvb3RFbGVtZW50SWQsIGNvbm5lY3RlZD10cnVlKSB7XG4gIGxldCByb290RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJvb3RFbGVtZW50SWQpO1xuXG4gIGlmIChyb290RWxlbWVudCkge1xuICAgIGlmIChjb25uZWN0ZWQpIHtcbiAgICAgIFJlYWN0RE9NLnJlbmRlcihcbiAgICAgICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgICAgICA8UHJvdmlkZXIgc3RvcmU9e3N0b3JlLmdldFN0b3JlKCl9PlxuICAgICAgICAgIDxDb21wb25lbnQgLz5cbiAgICAgICAgPC9Qcm92aWRlcj4sXG4gICAgICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgICAgIHJvb3RFbGVtZW50XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBSZWFjdERPTS5yZW5kZXIoXG4gICAgICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICAgICAgPENvbXBvbmVudCAvPixcbiAgICAgICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgICAgICAgcm9vdEVsZW1lbnRcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG4iLCJjbGFzcyBPcmRlcmVkTGlzdCB7XG4gICAgY29uc3RydWN0b3IoaXRlbXMpIHtcbiAgICAgIHRoaXMuaXNPcmRlcmVkID0gZmFsc2U7XG4gICAgICB0aGlzLl9pdGVtcyA9IGl0ZW1zIHx8IFtdO1xuICAgIH1cblxuICAgIGFkZChrZXksIGl0ZW0sIG9yZGVyKSB7XG4gICAgICB0aGlzLl9pdGVtcy5wdXNoKHtcbiAgICAgICAga2V5OiBrZXksXG4gICAgICAgIGl0ZW06IGl0ZW0sXG5cbiAgICAgICAgYWZ0ZXI6IG9yZGVyID8gb3JkZXIuYWZ0ZXIgfHwgbnVsbCA6IG51bGwsXG4gICAgICAgIGJlZm9yZTogb3JkZXIgPyBvcmRlci5iZWZvcmUgfHwgbnVsbCA6IG51bGxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldChrZXksIHZhbHVlKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2l0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLl9pdGVtc1tpXS5rZXkgPT09IGtleSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLl9pdGVtc1tpXS5pdGVtO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBoYXMoa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXQoa2V5KSAhPT0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHZhbHVlcygpIHtcbiAgICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5faXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFsdWVzLnB1c2godGhpcy5faXRlbXNbaV0uaXRlbSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH1cblxuICAgIG9yZGVyKHZhbHVlc19vbmx5KSB7XG4gICAgICBpZiAoIXRoaXMuaXNPcmRlcmVkKSB7XG4gICAgICAgIHRoaXMuX2l0ZW1zID0gdGhpcy5fb3JkZXIodGhpcy5faXRlbXMpO1xuICAgICAgICB0aGlzLmlzT3JkZXJlZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWx1ZXNfb25seSB8fCB0eXBlb2YgdmFsdWVzX29ubHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlcygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZW1zO1xuICAgICAgfVxuICAgIH1cblxuICAgIG9yZGVyZWRWYWx1ZXMoKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcmRlcih0cnVlKTtcbiAgICB9XG5cbiAgICBfb3JkZXIodW5vcmRlcmVkKSB7XG4gICAgICAvLyBJbmRleCBvZiB1bm9yZGVyZWQgaXRlbXNcbiAgICAgIHZhciBpbmRleCA9IFtdO1xuICAgICAgdW5vcmRlcmVkLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgaW5kZXgucHVzaChpdGVtLmtleSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gT3JkZXJlZCBpdGVtc1xuICAgICAgdmFyIG9yZGVyZWQgPSBbXTtcbiAgICAgIHZhciBvcmRlcmluZyA9IFtdO1xuXG4gICAgICAvLyBGaXJzdCBwYXNzOiByZWdpc3RlciBpdGVtcyB0aGF0XG4gICAgICAvLyBkb24ndCBzcGVjaWZ5IHRoZWlyIG9yZGVyXG4gICAgICB1bm9yZGVyZWQuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICBpZiAoIWl0ZW0uYWZ0ZXIgJiYgIWl0ZW0uYmVmb3JlKSB7XG4gICAgICAgICAgb3JkZXJlZC5wdXNoKGl0ZW0pO1xuICAgICAgICAgIG9yZGVyaW5nLnB1c2goaXRlbS5rZXkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gU2Vjb25kIHBhc3M6IHJlZ2lzdGVyIGl0ZW1zIHRoYXRcbiAgICAgIC8vIHNwZWNpZnkgdGhlaXIgYmVmb3JlIHRvIFwiX2VuZFwiXG4gICAgICB1bm9yZGVyZWQuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICBpZiAoaXRlbS5iZWZvcmUgPT09IFwiX2VuZFwiKSB7XG4gICAgICAgICAgb3JkZXJlZC5wdXNoKGl0ZW0pO1xuICAgICAgICAgIG9yZGVyaW5nLnB1c2goaXRlbS5rZXkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gVGhpcmQgcGFzczoga2VlcCBpdGVyYXRpbmcgaXRlbXNcbiAgICAgIC8vIHVudGlsIHdlIGhpdCBpdGVyYXRpb25zIGxpbWl0IG9yIGZpbmlzaFxuICAgICAgLy8gb3JkZXJpbmcgbGlzdFxuICAgICAgZnVuY3Rpb24gaW5zZXJ0SXRlbShpdGVtKSB7XG4gICAgICAgIHZhciBpbnNlcnRBdCA9IC0xO1xuICAgICAgICBpZiAob3JkZXJpbmcuaW5kZXhPZihpdGVtLmtleSkgPT09IC0xKSB7XG4gICAgICAgICAgaWYgKGl0ZW0uYWZ0ZXIpIHtcbiAgICAgICAgICAgIGluc2VydEF0ID0gb3JkZXJpbmcuaW5kZXhPZihpdGVtLmFmdGVyKTtcbiAgICAgICAgICAgIGlmIChpbnNlcnRBdCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgaW5zZXJ0QXQgKz0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGl0ZW0uYmVmb3JlKSB7XG4gICAgICAgICAgICBpbnNlcnRBdCA9IG9yZGVyaW5nLmluZGV4T2YoaXRlbS5iZWZvcmUpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpbnNlcnRBdCAhPT0gLTEpIHtcbiAgICAgICAgICAgIG9yZGVyZWQuc3BsaWNlKGluc2VydEF0LCAwLCBpdGVtKTtcbiAgICAgICAgICAgIG9yZGVyaW5nLnNwbGljZShpbnNlcnRBdCwgMCwgaXRlbS5rZXkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDIwMDtcbiAgICAgIHdoaWxlIChpdGVyYXRpb25zID4gMCAmJiBpbmRleC5sZW5ndGggIT09IG9yZGVyaW5nLmxlbmd0aCkge1xuICAgICAgICBpdGVyYXRpb25zIC09IDE7XG4gICAgICAgIHVub3JkZXJlZC5mb3JFYWNoKGluc2VydEl0ZW0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gb3JkZXJlZDtcbiAgICB9XG4gIH1cblxuICBleHBvcnQgZGVmYXVsdCBPcmRlcmVkTGlzdDtcbiIsImNvbnN0IEVNQUlMID0gL14oKFtePD4oKVtcXF1cXC4sOzpcXHNAXFxcIl0rKFxcLltePD4oKVtcXF1cXC4sOzpcXHNAXFxcIl0rKSopfChcXFwiLitcXFwiKSlAKChbXjw+KClbXFxdXFwuLDs6XFxzQFxcXCJdK1xcLikrW148PigpW1xcXVxcLiw7Olxcc0BcXFwiXXsyLH0pJC9pO1xuY29uc3QgVVNFUk5BTUUgPSBuZXcgUmVnRXhwKCdeWzAtOWEtel0rJCcsICdpJyk7XG5cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlZCgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKCQudHJpbSh2YWx1ZSkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gZ2V0dGV4dChcIlRoaXMgZmllbGQgaXMgcmVxdWlyZWQuXCIpO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVtYWlsKG1lc3NhZ2UpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKCFFTUFJTC50ZXN0KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UgfHwgZ2V0dGV4dChcIkVudGVyIGEgdmFsaWQgZW1haWwgYWRkcmVzcy5cIik7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWluTGVuZ3RoKGxpbWl0VmFsdWUsIG1lc3NhZ2UpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIHJldHVybk1lc3NhZ2UgPSAnJztcbiAgICB2YXIgbGVuZ3RoID0gJC50cmltKHZhbHVlKS5sZW5ndGg7XG5cbiAgICBpZiAobGVuZ3RoIDwgbGltaXRWYWx1ZSkge1xuICAgICAgaWYgKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuTWVzc2FnZSA9IG1lc3NhZ2UobGltaXRWYWx1ZSwgbGVuZ3RoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybk1lc3NhZ2UgPSBuZ2V0dGV4dChcbiAgICAgICAgICBcIkVuc3VyZSB0aGlzIHZhbHVlIGhhcyBhdCBsZWFzdCAlKGxpbWl0X3ZhbHVlKXMgY2hhcmFjdGVyIChpdCBoYXMgJShzaG93X3ZhbHVlKXMpLlwiLFxuICAgICAgICAgIFwiRW5zdXJlIHRoaXMgdmFsdWUgaGFzIGF0IGxlYXN0ICUobGltaXRfdmFsdWUpcyBjaGFyYWN0ZXJzIChpdCBoYXMgJShzaG93X3ZhbHVlKXMpLlwiLFxuICAgICAgICAgIGxpbWl0VmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGludGVycG9sYXRlKHJldHVybk1lc3NhZ2UsIHtcbiAgICAgICAgbGltaXRfdmFsdWU6IGxpbWl0VmFsdWUsXG4gICAgICAgIHNob3dfdmFsdWU6IGxlbmd0aFxuICAgICAgfSwgdHJ1ZSk7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWF4TGVuZ3RoKGxpbWl0VmFsdWUsIG1lc3NhZ2UpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIHJldHVybk1lc3NhZ2UgPSAnJztcbiAgICB2YXIgbGVuZ3RoID0gJC50cmltKHZhbHVlKS5sZW5ndGg7XG5cbiAgICBpZiAobGVuZ3RoID4gbGltaXRWYWx1ZSkge1xuICAgICAgaWYgKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuTWVzc2FnZSA9IG1lc3NhZ2UobGltaXRWYWx1ZSwgbGVuZ3RoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybk1lc3NhZ2UgPSBuZ2V0dGV4dChcbiAgICAgICAgICBcIkVuc3VyZSB0aGlzIHZhbHVlIGhhcyBhdCBtb3N0ICUobGltaXRfdmFsdWUpcyBjaGFyYWN0ZXIgKGl0IGhhcyAlKHNob3dfdmFsdWUpcykuXCIsXG4gICAgICAgICAgXCJFbnN1cmUgdGhpcyB2YWx1ZSBoYXMgYXQgbW9zdCAlKGxpbWl0X3ZhbHVlKXMgY2hhcmFjdGVycyAoaXQgaGFzICUoc2hvd192YWx1ZSlzKS5cIixcbiAgICAgICAgICBsaW1pdFZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpbnRlcnBvbGF0ZShyZXR1cm5NZXNzYWdlLCB7XG4gICAgICAgIGxpbWl0X3ZhbHVlOiBsaW1pdFZhbHVlLFxuICAgICAgICBzaG93X3ZhbHVlOiBsZW5ndGhcbiAgICAgIH0sIHRydWUpO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVzZXJuYW1lTWluTGVuZ3RoKHNldHRpbmdzKSB7XG4gIHZhciBtZXNzYWdlID0gZnVuY3Rpb24obGltaXRWYWx1ZSkge1xuICAgIHJldHVybiBuZ2V0dGV4dChcbiAgICAgIFwiVXNlcm5hbWUgbXVzdCBiZSBhdCBsZWFzdCAlKGxpbWl0X3ZhbHVlKXMgY2hhcmFjdGVyIGxvbmcuXCIsXG4gICAgICBcIlVzZXJuYW1lIG11c3QgYmUgYXQgbGVhc3QgJShsaW1pdF92YWx1ZSlzIGNoYXJhY3RlcnMgbG9uZy5cIixcbiAgICAgIGxpbWl0VmFsdWUpO1xuICB9O1xuICByZXR1cm4gdGhpcy5taW5MZW5ndGgoc2V0dGluZ3MudXNlcm5hbWVfbGVuZ3RoX21pbiwgbWVzc2FnZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1c2VybmFtZU1heExlbmd0aChzZXR0aW5ncykge1xuICB2YXIgbWVzc2FnZSA9IGZ1bmN0aW9uKGxpbWl0VmFsdWUpIHtcbiAgICByZXR1cm4gbmdldHRleHQoXG4gICAgICBcIlVzZXJuYW1lIGNhbm5vdCBiZSBsb25nZXIgdGhhbiAlKGxpbWl0X3ZhbHVlKXMgY2hhcmFjdGVyLlwiLFxuICAgICAgXCJVc2VybmFtZSBjYW5ub3QgYmUgbG9uZ2VyIHRoYW4gJShsaW1pdF92YWx1ZSlzIGNoYXJhY3RlcnMuXCIsXG4gICAgICBsaW1pdFZhbHVlKTtcbiAgfTtcbiAgcmV0dXJuIHRoaXMubWF4TGVuZ3RoKHNldHRpbmdzLnVzZXJuYW1lX2xlbmd0aF9tYXgsIG1lc3NhZ2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXNlcm5hbWVDb250ZW50KCkge1xuICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICBpZiAoIVVTRVJOQU1FLnRlc3QoJC50cmltKHZhbHVlKSkpIHtcbiAgICAgIHJldHVybiBnZXR0ZXh0KFwiVXNlcm5hbWUgY2FuIG9ubHkgY29udGFpbiBsYXRpbiBhbHBoYWJldCBsZXR0ZXJzIGFuZCBkaWdpdHMuXCIpO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhc3N3b3JkTWluTGVuZ3RoKHNldHRpbmdzKSB7XG4gIHZhciBtZXNzYWdlID0gZnVuY3Rpb24obGltaXRWYWx1ZSkge1xuICAgIHJldHVybiBuZ2V0dGV4dChcbiAgICAgIFwiVmFsaWQgcGFzc3dvcmQgbXVzdCBiZSBhdCBsZWFzdCAlKGxpbWl0X3ZhbHVlKXMgY2hhcmFjdGVyIGxvbmcuXCIsXG4gICAgICBcIlZhbGlkIHBhc3N3b3JkIG11c3QgYmUgYXQgbGVhc3QgJShsaW1pdF92YWx1ZSlzIGNoYXJhY3RlcnMgbG9uZy5cIixcbiAgICAgIGxpbWl0VmFsdWUpO1xuICB9O1xuICByZXR1cm4gdGhpcy5taW5MZW5ndGgoc2V0dGluZ3MucGFzc3dvcmRfbGVuZ3RoX21pbiwgbWVzc2FnZSk7XG59Il19

File diff suppressed because it is too large
+ 33312 - 10
misago/static/misago/js/vendor.js


+ 1 - 1
misago/templates/misago/navbar.html

@@ -64,4 +64,4 @@
   </ul>
   <!-- /compact navbar -->
 </nav>
-<div id="navbar-dropdown-mount" class="mobile-dropdown"></div>
+<div id="mobile-navbar-dropdown-mount" class="mobile-dropdown"></div>

+ 3 - 1
misago/users/models/ban.py

@@ -61,7 +61,9 @@ class BansManager(models.Manager):
             queryset = queryset.filter(check_type__in=checks)
 
         for ban in queryset.order_by('-id').iterator():
-            if (ban.check_type == BAN_USERNAME and username and
+            if ban.is_expired:
+                continue
+            elif (ban.check_type == BAN_USERNAME and username and
                     ban.check_value(username)):
                 return ban
             elif (ban.check_type == BAN_EMAIL and email and

Some files were not shown because too many files changed in this diff