Browse Source

wip account activation flow

Rafał Pitoń 9 years ago
parent
commit
d7b8a0cb25
37 changed files with 647 additions and 140 deletions
  1. 10 1
      misago/frontend/misago/app.js
  2. 34 0
      misago/frontend/misago/components/forms/request-link-form.js
  3. 12 2
      misago/frontend/misago/components/modals/signin.js
  4. 65 0
      misago/frontend/misago/forms/request-link-form.js
  5. 115 0
      misago/frontend/misago/routes/activate-by-token.js
  6. 6 6
      misago/frontend/misago/routes/error-pages.js
  7. 9 43
      misago/frontend/misago/routes/index.js
  8. 109 0
      misago/frontend/misago/routes/request-activation.js
  9. 13 15
      misago/frontend/misago/services/api.js
  10. 15 0
      misago/frontend/misago/services/auth.js
  11. 3 1
      misago/frontend/misago/services/components.js
  12. 6 1
      misago/frontend/misago/services/router.js
  13. 11 3
      misago/frontend/misago/services/routes.js
  14. 1 1
      misago/frontend/misago/services/validation.js
  15. 2 1
      misago/frontend/misago/style/misago.less
  16. 12 0
      misago/frontend/misago/style/misago/loaders.less
  17. 10 10
      misago/frontend/misago/style/misago/message-pages.less
  18. 3 3
      misago/frontend/misago/style/misago/modals.less
  19. 3 1
      misago/frontend/misago/style/misago/variables.less
  20. 8 7
      misago/frontend/misago/urls.js
  21. 15 12
      misago/frontend/misago/utils/lifecycle-hooks.js
  22. 1 0
      misago/frontend/package.json
  23. 43 0
      misago/frontend/test/tests/acceptance/auth-exceptions.js
  24. 12 1
      misago/frontend/test/utils/misago-factories.js
  25. 96 0
      misago/frontend/test/utils/mock-user.js
  26. 3 1
      misago/frontend/test/utils/qunit-boilerplate.js
  27. 1 1
      misago/static/misago/css/misago.css
  28. 2 2
      misago/static/misago/js/misago.js
  29. 1 1
      misago/static/misago/js/misago.js.map
  30. 1 1
      misago/templates/misago/emails/activation/by_user.txt
  31. 4 4
      misago/templates/misago/errorpages/403.html
  32. 4 4
      misago/templates/misago/errorpages/404.html
  33. 4 4
      misago/templates/misago/errorpages/405.html
  34. 4 4
      misago/templates/misago/errorpages/csrf_failure.html
  35. 4 4
      misago/templates/misago/errorpages/csrf_failure_authenticated.html
  36. 3 3
      misago/templates/misago/noscript.html
  37. 2 3
      misago/users/api/auth.py

+ 10 - 1
misago/frontend/misago/app.js

@@ -62,7 +62,6 @@
     };
     };
   };
   };
 
 
-
   // Services
   // Services
   var proto = window.Misago.prototype;
   var proto = window.Misago.prototype;
 
 
@@ -75,4 +74,14 @@
       before: proto.get(order, 'before')
       before: proto.get(order, 'before')
     });
     });
   };
   };
+
+  // Exceptions
+  proto.PermissionDenied = function(message) {
+    this.detail = message;
+    this.status = 403;
+
+    this.toString = function() {
+      return this.detail || 'Permission denied';
+    };
+  };
 }());
 }());

+ 34 - 0
misago/frontend/misago/components/forms/request-link-form.js

@@ -0,0 +1,34 @@
+(function (Misago) {
+  'use strict';
+
+  var form = {
+    view: function(ctrl, form, _) {
+      return m('.well.well-form',
+        m('form', {onsubmit: form.submit}, [
+          m('.form-group',
+            m('.control-input',
+              Misago.input({
+                disabled: form.isBusy,
+                value: form.email,
+                placeholder: gettext("Your e-mail address")
+              })
+            )
+          ),
+          _.component('button', {
+            class: '.btn-primary.btn-block',
+            submit: true,
+            loading: form.isBusy,
+            label: gettext("Send link")
+          })
+        ])
+      );
+    }
+  };
+
+  Misago.addService('component:request-link-form', function(_) {
+    _.component('request-link-form', form);
+  },
+  {
+    after: 'components'
+  });
+}(Misago.prototype));

+ 12 - 2
misago/frontend/misago/components/modals/signin.js

@@ -12,6 +12,15 @@
       };
       };
     },
     },
     view: function(ctrl, _) {
     view: function(ctrl, _) {
+      var activateButton = null;
+
+      if (ctrl.form.showActivation) {
+        activateButton = m('a.btn.btn-block.btn-success',
+          {href: _.router.url('request_activation')},
+          gettext('Activate account')
+        );
+      }
+
       return m('.modal-dialog.modal-sm.modal-signin[role="document"]',
       return m('.modal-dialog.modal-sm.modal-signin[role="document"]',
         {config: persistent},
         {config: persistent},
         m('.modal-content', [
         m('.modal-content', [
@@ -38,14 +47,15 @@
                 )
                 )
               )
               )
             ]),
             ]),
-            m('.modal-footer',
+            m('.modal-footer', [
+              activateButton,
               _.component('button', {
               _.component('button', {
                 class: '.btn-primary.btn-block',
                 class: '.btn-primary.btn-block',
                 submit: true,
                 submit: true,
                 loading: ctrl.form.isBusy,
                 loading: ctrl.form.isBusy,
                 label: gettext("Sign in")
                 label: gettext("Sign in")
               })
               })
-            )
+            ])
           ])
           ])
         ])
         ])
       );
       );

+ 65 - 0
misago/frontend/misago/forms/request-link-form.js

@@ -0,0 +1,65 @@
+(function (Misago) {
+  'use strict';
+
+  var RequestLink = function(options, _) {
+    var self = this;
+
+    this.email = m.prop('');
+
+    this.validation = {
+      'email': [
+        Misago.validators.email()
+      ]
+    };
+
+    this.clean = function() {
+      if (!_.validate(this)) {
+        _.alert.error(gettext("Enter a valid email address."));
+        return false;
+      } else {
+        return true;
+      }
+    };
+
+    this.submit = function() {
+      _.api.endpoint('auth').endpoint(options.endpoint).post({
+        email: self.email()
+      }).then(function(user) {
+        self.success(user);
+      }, function(error) {
+        self.error(error);
+      });
+    };
+
+    this.success = function(user) {
+      options.success(user);
+    };
+
+    this.error = function(rejection) {
+      if (rejection.status === 400) {
+        if (rejection.code === 'banned') {
+          _.router.error403({
+            message: '',
+            ban: rejection.detail
+          });
+        } else {
+          options.error(rejection, _);
+        }
+      } else {
+        _.api.alert(rejection);
+      }
+    };
+
+    this.reset = function() {
+      this.email('');
+      options.reset();
+    };
+  };
+
+  Misago.addService('form:request-link', function(_) {
+    _.form('request-link', RequestLink);
+  },
+  {
+    after: 'forms'
+  });
+} (Misago.prototype));

+ 115 - 0
misago/frontend/misago/routes/activate-by-token.js

@@ -0,0 +1,115 @@
+(function (Misago) {
+  'use strict';
+
+  var viewModel = {
+    error: null,
+    username: null,
+    isReady: false,
+    init: function(_) {
+      this.error = null;
+      this.user = null;
+      this.isReady = false;
+
+      var endpoint = _.api.endpoint('auth').endpoint('activate-account');
+      endpoint = endpoint.endpoint(m.route.param('user_id'));
+      endpoint = endpoint.endpoint(m.route.param('token'));
+
+      return endpoint.post();
+    },
+    ondata: function(data, _) {
+      m.startComputation();
+
+      _.title.set(gettext("Account activated"));
+
+      this.username = data.username;
+      this.isReady = true;
+
+      m.endComputation();
+    },
+    onerror: function(error, _) {
+      if (error.status === 400) {
+        m.startComputation();
+
+        this.error = error;
+        this.isReady = true;
+
+        m.endComputation();
+      } else {
+        _.router.errorPage(error);
+      }
+    }
+  };
+
+  var activateByToken = {
+    controller: function(_) {
+      _.auth.denyAuthenticated(
+        gettext("You have to be signed out to activate account."));
+
+      _.title.set(gettext("Account activation"));
+      this.vm.init(_);
+    },
+    vm: viewModel,
+    view: function(ctrl, _) {
+      if (this.vm.error) {
+        return this.rejected(this.vm.error, _);
+      } else {
+        return this.success(this.vm.username, _);
+      }
+    },
+    success: function(username) {
+      var message = gettext('%(username)s, your account has been successfully activated!');
+
+      return m('.page.page-message.page-message-success',
+        m('.container',
+          m('.message-panel', [
+            m('.message-icon',
+              m('span.material-icon', 'check')
+            ),
+            m('.message-body', [
+              m('p.lead',
+                interpolate(message, {
+                  username: username
+                }, true)
+              ),
+              m('p',
+                gettext('You can now sign in to finish setting up your account and to participate in or start new discussions.')
+              )
+            ])
+          ])
+        )
+      );
+    },
+    rejected: function(error) {
+      return m('.page.page-message.page-message-info',
+        m('.container',
+          m('.message-panel', [
+            m('.message-icon',
+              m('span.material-icon', 'info_outline')
+            ),
+            m('.message-body', [
+              m('p.lead',
+                gettext("Your account can't be activated at this time.")
+              ),
+              m('p',
+                error.detail
+              )
+            ])
+          ])
+        )
+      );
+    },
+    loading: function(ctrl, _) {
+      return m('.page.page-loading', [
+        _.component('loader'),
+        m('p.lead', gettext("Activating account..."))
+      ]);
+    }
+  };
+
+  Misago.addService('route:activate-by-token', function(_) {
+    _.route('activate-by-token', activateByToken);
+  },
+  {
+    after: 'routes'
+  });
+}(Misago.prototype));

+ 6 - 6
misago/frontend/misago/routes/error-pages.js

@@ -12,11 +12,11 @@
 
 
     return m('.page.page-error.page-error-' + error.code,
     return m('.page.page-error.page-error-' + error.code,
       m('.container',
       m('.container',
-        m('.error-panel', [
-          m('.error-icon',
+        m('.message-panel', [
+          m('.message-icon',
             m('span.material-icon', error.icon)
             m('span.material-icon', error.icon)
           ),
           ),
-          m('.error-message', error_message)
+          m('.message-body', error_message)
         ])
         ])
       )
       )
     );
     );
@@ -54,11 +54,11 @@
 
 
       return m('.page.page-error.page-error-banned',
       return m('.page.page-error.page-error-banned',
         m('.container',
         m('.container',
-          m('.error-panel', [
-            m('.error-icon',
+          m('.message-panel', [
+            m('.message-icon',
               m('span.material-icon', 'highlight_off')
               m('span.material-icon', 'highlight_off')
             ),
             ),
-            m('.error-message', error_message)
+            m('.message-body', error_message)
           ])
           ])
         )
         )
       );
       );

+ 9 - 43
misago/frontend/misago/routes/index.js

@@ -6,54 +6,20 @@
       document.title = _.settings.forum_index_title || _.settings.forum_name;
       document.title = _.settings.forum_index_title || _.settings.forum_name;
 
 
       return {
       return {
-        active: function() {
-          _.modal('register-complete', {
-            'activation': 'active',
-            'username': 'BobBoberson',
-            'email': 'bob-boberson@somewhere.com'
-          });
-        },
-        user: function() {
-          _.modal('register-complete', {
-            'activation': 'by_user',
-            'username': 'BobBoberson',
-            'email': 'bob-boberson@somewhere.com'
-          });
-        },
-        admin: function() {
-          _.modal('register-complete', {
-            'activation': 'by_admin',
-            'username': 'BobBoberson',
-            'email': 'bob-boberson@somewhere.com'
-          });
+        activation: function() {
+          _.router.url('request_activation');
         }
         }
       };
       };
     },
     },
     view: function(ctrl, _) {
     view: function(ctrl, _) {
       return m('.container', [
       return m('.container', [
-        m('h1', 'Buttons'),
-        m('p', 'Test registration successful modal!'),
-        m('',
-          _.component('button', {
-            class: '.btn-success',
-            label: 'Registration done, account active',
-            onclick: ctrl.active
-          })
-        ),
-        m('',
-          _.component('button', {
-            class: '.btn-warning',
-            label: 'Registration done, account inactive (user)',
-            onclick: ctrl.user
-          })
-        ),
-        m('',
-          _.component('button', {
-            class: '.btn-danger',
-            label: 'Registration done, account inactive (admin)',
-            onclick: ctrl.admin
-          })
-        ),
+        m('h1', 'Activation'),
+        m('p', 'Test auth blocks'),
+        m('p',
+          m('a', {href: _.router.url('request_activation')},
+            'Request activation.'
+          )
+        )
       ]);
       ]);
     }
     }
   };
   };

+ 109 - 0
misago/frontend/misago/routes/request-activation.js

@@ -0,0 +1,109 @@
+(function (Misago) {
+  'use strict';
+
+  var formOptions = {
+    endpoint: 'send-activation',
+    user: null,
+
+    success: function(user) {
+      this.user = user;
+    },
+    error: function(rejection, _) {
+      if (rejection.code === 'already_active') {
+        _.alert.info(rejection.detail);
+        _.modal('sign-in');
+      } else if (rejection.code === 'inactive_admin') {
+        _.alert.info(rejection.detail);
+      } else {
+        _.alert.error(rejection.detail);
+      }
+    },
+    reset: function() {
+      this.user = null;
+    }
+  };
+
+  var requestActivation = {
+    controller: function(_) {
+      _.auth.denyAuthenticated(
+        gettext("You have to be signed out to activate account."));
+
+      _.title.set(gettext("Activate your account"));
+
+      return {
+        form: _.form('request-link', formOptions)
+      };
+    },
+    view: function(ctrl, _) {
+      if (formOptions.user) {
+        return this.completed(ctrl.form, formOptions, _);
+      } else {
+        return this.form(ctrl.form, _);
+      }
+    },
+    completed: function(form, formOptions, _) {
+      var message = gettext("%(username)s, we have sent your activation link to %(email)s.");
+
+      return m('.page.page-message.page-message-success',
+        m('.container',
+          m('.message-panel', [
+            m('.message-icon',
+              m('span.material-icon', 'check')
+            ),
+            m('.message-body', [
+              m('p.lead',
+                gettext("Activation link has been sent.")
+              ),
+              m('p',
+                interpolate(message, {
+                  username: formOptions.user.username,
+                  email: formOptions.user.email
+                }, true)
+              ),
+              m('p',
+                _.component('button', {
+                  class: '.btn-default',
+                  submit: false,
+                  label: gettext("Request another link"),
+                  onclick: form.reset.bind(form)
+                })
+              )
+            ])
+          ])
+        )
+      );
+    },
+    form: function(form, _) {
+      return m('.page.page-request-activation', [
+        _.component('header', {
+          title: gettext("Request activation link")
+        }),
+        m('.container',
+          m('.row', [
+            m('.col-md-8', [
+              m('p',
+                gettext("Site administrator may impose requirement on newly regitered accounts to be activated before users will be able to sign in.")
+              ),
+              m('p',
+                gettext("Depending on time of registration, you will be able activate your account by clicking special activation link. This link will be valid only for your browser, for seven days or until your account is activated.")
+              ),
+              m('p',
+                gettext("To receive this link, enter your account's e-mail addres in form and press \"Send link\" button.")
+              )
+            ]),
+            m('.col-md-4',
+              _.component('request-link-form', form)
+            )
+          ])
+        )
+      ]);
+    }
+  };
+
+  Misago.addService('route:request-activation', function(_) {
+    _.route('request-activation', requestActivation);
+  },
+  {
+    after: 'routes'
+  });
+}(Misago.prototype));

+ 13 - 15
misago/frontend/misago/services/api.js

@@ -32,27 +32,25 @@
       this.url += filtersUrl(call.filters);
       this.url += filtersUrl(call.filters);
     }
     }
 
 
-    if (!call.url && call.filters) {
-      if (call.model) {
-        this.related = function(model, filters) {
-          return new Query(_, {
-            url: this.url,
-            relation: call.model,
-            related: model,
-            filters: filters,
-          });
-        };
-      }
-
-      this.endpoint = function(path, filters) {
+    if (call.model) {
+      this.related = function(model, filters) {
         return new Query(_, {
         return new Query(_, {
           url: this.url,
           url: this.url,
-          path: path,
-          filters: filters
+          relation: call.model,
+          related: model,
+          filters: filters,
         });
         });
       };
       };
     }
     }
 
 
+    this.endpoint = function(path, filters) {
+      return new Query(_, {
+        url: this.url,
+        path: path,
+        filters: filters
+      });
+    };
+
     this.get = function() {
     this.get = function() {
       var model = null;
       var model = null;
       if (call.related) {
       if (call.related) {

+ 15 - 0
misago/frontend/misago/services/auth.js

@@ -3,6 +3,21 @@
 
 
   var Auth = function(_) {
   var Auth = function(_) {
     _.user = _.models.deserialize('user', _.context.user);
     _.user = _.models.deserialize('user', _.context.user);
+
+    // Access controls
+    this.denyAuthenticated = function(message) {
+      if (_.user.isAuthenticated) {
+        throw new Misago.PermissionDenied(
+          message || gettext("This page is not available to signed in users."));
+      }
+    };
+
+    this.denyAnonymous = function(message) {
+      if (_.user.isAnonymous) {
+        throw new Misago.PermissionDenied(
+          message || gettext("This page is not available to guests."));
+      }
+    };
   };
   };
 
 
   Misago.addService('auth', function(_) {
   Misago.addService('auth', function(_) {

+ 3 - 1
misago/frontend/misago/services/components.js

@@ -13,8 +13,10 @@
       } else {
       } else {
         return m.component(this._components[name], this);
         return m.component(this._components[name], this);
       }
       }
-    } else {
+    } else if (component) {
       this._components[name] = component;
       this._components[name] = component;
+    } else {
+      throw '"' + name + '" component is not registered and can\'t be created';
     }
     }
   };
   };
 
 

+ 6 - 1
misago/frontend/misago/services/router.js

@@ -31,6 +31,7 @@
       } else {
       } else {
         m.route.mode = 'pathname';
         m.route.mode = 'pathname';
       }
       }
+
       m.route(fixture, '/', this.urls);
       m.route(fixture, '/', this.urls);
     };
     };
 
 
@@ -38,6 +39,10 @@
       return this.reverses[name];
       return this.reverses[name];
     };
     };
 
 
+    this.route = function(url) {
+      m.route(url);
+    };
+
     // Delegate clicks
     // Delegate clicks
     this.delegateElement = null;
     this.delegateElement = null;
 
 
@@ -87,7 +92,7 @@
         var cleanUrl = self.cleanUrl(e.target.href);
         var cleanUrl = self.cleanUrl(e.target.href);
         if (cleanUrl) {
         if (cleanUrl) {
           if (cleanUrl != m.route()) {
           if (cleanUrl != m.route()) {
-            m.route(cleanUrl);
+            self.route(cleanUrl);
           }
           }
           e.preventDefault();
           e.preventDefault();
         }
         }

+ 11 - 3
misago/frontend/misago/services/routes.js

@@ -17,8 +17,14 @@
     };
     };
 
 
     var errorHandler = function(error) {
     var errorHandler = function(error) {
-      if (this.isActive) {
-        this.container.router.errorPage(error);
+      if (this.isActive && error.status) {
+        if (this.vm && this.vm.onerror) {
+          this.vm.onerror(error, this.container);
+        } else {
+          this.container.router.errorPage(error);
+        }
+      } else {
+        throw error;
       }
       }
     };
     };
 
 
@@ -39,9 +45,11 @@
         } else {
         } else {
           return m.component(this._routes[name], this);
           return m.component(this._routes[name], this);
         }
         }
-      } else {
+      } else if (component) {
         component.container = _;
         component.container = _;
         this._routes[name] = boilerplate(component);
         this._routes[name] = boilerplate(component);
+      } else {
+        throw '"' + name + '" route is not registered and can\'t be created';
       }
       }
     };
     };
   });
   });

+ 1 - 1
misago/frontend/misago/services/validation.js

@@ -16,7 +16,7 @@
     email: function(message) {
     email: function(message) {
       return function(value) {
       return function(value) {
         if (!EMAIL.test(value)) {
         if (!EMAIL.test(value)) {
-          return message || gettext('Enter a valid email address.');
+          return message || gettext("Enter a valid email address.");
         }
         }
       };
       };
     },
     },

+ 2 - 1
misago/frontend/misago/style/misago.less

@@ -38,6 +38,7 @@
 @import "@{bs}close.less";
 @import "@{bs}close.less";
 @import "@{bs}alerts.less";
 @import "@{bs}alerts.less";
 @import "@{bs}progress-bars.less";
 @import "@{bs}progress-bars.less";
+@import "@{bs}wells.less";
 
 
 // Components w/ JavaScript
 // Components w/ JavaScript
 @import "@{bs}modals.less";
 @import "@{bs}modals.less";
@@ -61,7 +62,7 @@
 @import "misago/buttons.less";
 @import "misago/buttons.less";
 
 
 // Pages
 // Pages
-@import "misago/error-pages.less";
+@import "misago/message-pages.less";
 
 
 // --------------------------------------------------
 // --------------------------------------------------
 // Flavor
 // Flavor

+ 12 - 0
misago/frontend/misago/style/misago/loaders.less

@@ -144,3 +144,15 @@
     }
     }
   }
   }
 }
 }
+
+
+// Loading page extra styles
+.page-loading {
+  .lead {
+    margin-top: @loader-vertical-margin * -0.5;
+    margin-bottom: @loader-vertical-margin;
+
+    color: @loader-text;
+    text-align: center;
+  }
+}

+ 10 - 10
misago/frontend/misago/style/misago/error-pages.less → misago/frontend/misago/style/misago/message-pages.less

@@ -1,18 +1,18 @@
 //
 //
-// Error Pages
+// Message Pages
 // --------------------------------------------------
 // --------------------------------------------------
 
 
 
 
 // Small displays
 // Small displays
 @media screen and (max-width: @screen-sm-max) {
 @media screen and (max-width: @screen-sm-max) {
-  .page-error {
+  .page-message, .page-error {
     text-align: center;
     text-align: center;
 
 
-    .error-icon {
+    .message-icon {
       margin: @line-height-computed * 1.5;
       margin: @line-height-computed * 1.5;
 
 
       .material-icon {
       .material-icon {
-        font-size: @error-page-icon-size * 2;
+        font-size: @message-page-icon-size * 2;
       }
       }
     }
     }
   }
   }
@@ -21,23 +21,23 @@
 
 
 // Full displays
 // Full displays
 @media screen and (min-width: @screen-md-min) {
 @media screen and (min-width: @screen-md-min) {
-  .page-error {
-    .error-panel {
+  .page-message, .page-error {
+    .message-panel {
       margin: @line-height-computed * 3 auto;
       margin: @line-height-computed * 3 auto;
       max-width: @screen-md-max * .65;
       max-width: @screen-md-max * .65;
       overflow: auto;
       overflow: auto;
     }
     }
 
 
-    .error-icon {
+    .message-icon {
       float: left;
       float: left;
 
 
       .material-icon {
       .material-icon {
-        font-size: @error-page-icon-size;
+        font-size: @message-page-icon-size;
       }
       }
     }
     }
 
 
-    .error-message {
-      margin-left: @error-page-icon-size + @line-height-computed;
+    .message-body {
+      margin-left: @message-page-icon-size + @line-height-computed;
     }
     }
   }
   }
 }
 }

+ 3 - 3
misago/frontend/misago/style/misago/modals.less

@@ -16,7 +16,7 @@
       margin: @line-height-computed * 1.5;
       margin: @line-height-computed * 1.5;
 
 
       .material-icon {
       .material-icon {
-        font-size: @error-page-icon-size * 2;
+        font-size: @message-page-icon-size * 2;
       }
       }
     }
     }
   }
   }
@@ -30,12 +30,12 @@
       float: left;
       float: left;
 
 
       .material-icon {
       .material-icon {
-        font-size: @error-page-icon-size;
+        font-size: @message-page-icon-size;
       }
       }
     }
     }
 
 
     .message-body {
     .message-body {
-      margin-left: @error-page-icon-size + @line-height-computed;
+      margin-left: @message-page-icon-size + @line-height-computed;
     }
     }
   }
   }
 }
 }

+ 3 - 1
misago/frontend/misago/style/misago/variables.less

@@ -13,6 +13,8 @@
 @loader-size: 80px;
 @loader-size: 80px;
 //** Loader color
 //** Loader color
 @loader-color: @gray-light;
 @loader-color: @gray-light;
+//** Loader text color
+@loader-text: @gray-light;
 
 
 //** Compact loader dot height
 //** Compact loader dot height
 @loader-compact-height: 10px;
 @loader-compact-height: 10px;
@@ -20,6 +22,6 @@
 //== Error pages
 //== Error pages
 //
 //
 //## Desktop style
 //## Desktop style
-@error-page-icon-size: 80px;
+@message-page-icon-size: 80px;
 
 
 //## Mobile style
 //## Mobile style

+ 8 - 7
misago/frontend/misago/urls.js

@@ -2,16 +2,17 @@
   'use strict';
   'use strict';
 
 
   var urls = new UrlConf();
   var urls = new UrlConf();
+
+  // Board index
   urls.url('/', 'index');
   urls.url('/', 'index');
 
 
-  // Legal pages
-  urls.url(
-    '/terms-of-service/',
-    'terms_of_service');
+  // Account activation
+  urls.url('/activation/', 'request_activation');
+  urls.url('/activation/:user_id/:token/', 'activate_by_token');
 
 
-  urls.url(
-    '/privacy-policy/',
-    'privacy_policy');
+  // Legal pages
+  urls.url('/terms-of-service/', 'terms_of_service');
+  urls.url('/privacy-policy/', 'privacy_policy');
 
 
   // Catch-all 404 not found route
   // Catch-all 404 not found route
   urls.url('/:rest...', 'error:404', 'not_found');
   urls.url('/:rest...', 'error:404', 'not_found');

+ 15 - 12
misago/frontend/misago/utils/lifecycle-hooks.js

@@ -17,21 +17,26 @@
     // Component active state
     // Component active state
     component.isActive = true;
     component.isActive = true;
 
 
+    var errorHandler = errorState.bind(component);
+
     // Wrap controller to store lifecycle methods
     // Wrap controller to store lifecycle methods
     var _controller = component.controller || noop;
     var _controller = component.controller || noop;
     component.controller = function() {
     component.controller = function() {
-      component.isActive = true;
-
-      var controller = _controller.apply(component, arguments) || {};
+      try {
+        component.isActive = true;
+        var controller = _controller.apply(component, arguments) || {};
 
 
-      // wrap onunload for lifestate
-      var _onunload = controller.onunload || noop;
-      controller.onunload = function() {
-        _onunload.apply(component, arguments);
-        component.isActive = false;
-      };
+        // wrap onunload for lifestate
+        var _onunload = controller.onunload || noop;
+        controller.onunload = function() {
+          _onunload.apply(component, arguments);
+          component.isActive = false;
+        };
 
 
-      return controller;
+        return controller;
+      } catch (e) {
+        errorHandler(e);
+      }
     };
     };
 
 
     // Add state callbacks to View-Model
     // Add state callbacks to View-Model
@@ -51,8 +56,6 @@
         }
         }
       };
       };
 
 
-      var errorHandler = errorState.bind(component);
-
       // wrap vm.init in promise handler
       // wrap vm.init in promise handler
       var _init = component.vm.init;
       var _init = component.vm.init;
       component.vm.init = function() {
       component.vm.init = function() {

+ 1 - 0
misago/frontend/package.json

@@ -19,6 +19,7 @@
 
 
       "initTestMisago",
       "initTestMisago",
       "getMisagoService",
       "getMisagoService",
+      "mockUser",
       "then",
       "then",
       "onElement",
       "onElement",
       "waitForElement",
       "waitForElement",

+ 43 - 0
misago/frontend/test/tests/acceptance/auth-exceptions.js

@@ -0,0 +1,43 @@
+(function () {
+  'use strict';
+
+  var app = null;
+
+  QUnit.acceptance("Auth Exceptions", {
+    afterEach: function() {
+      app.destroy();
+    }
+  });
+
+  QUnit.test("denyAuthenticated denied authenticated", function(assert) {
+    app = initTestMisago({
+      user: mockUser()
+    });
+
+    var done = assert.async();
+
+    app.router.route('/activation/');
+
+    onElement('.page-error.page-error-403 .error-message', function() {
+      assert.ok(true, "Permission denied error page was displayed.");
+      assert.equal(
+        getElementText('.page .error-message p:last-child'),
+        "You have to be signed out to activate account.",
+        "Route access was denied with valid error.");
+      done();
+    });
+  });
+
+  QUnit.test("denyAuthenticated passed anonymous", function(assert) {
+    app = initTestMisago();
+
+    var done = assert.async();
+
+    app.router.route('/activation/');
+
+    onElement('.page-request-activation', function() {
+      assert.ok(true, "Access to route was granted for anonymous user.");
+      done();
+    });
+  });
+}());

+ 12 - 1
misago/frontend/test/utils/misago-factory.js → misago/frontend/test/utils/misago-factories.js

@@ -1,7 +1,7 @@
 (function () {
 (function () {
   'use strict';
   'use strict';
 
 
-  window.initTestMisago = function() {
+  window.initTestMisago = function(options) {
     var misago = new Misago();
     var misago = new Misago();
 
 
     var context = {
     var context = {
@@ -89,6 +89,17 @@
       }
       }
     };
     };
 
 
+    if (options) {
+      if (options.acl) {
+        context.user.acl = $.extend(context.user.acl, options.acl);
+      }
+
+      if (options.user) {
+        context.user = $.extend(context.user, options.user);
+        context.isAuthenticated = !!context.user.id;
+      }
+    }
+
     misago.init({
     misago.init({
       test: true,
       test: true,
       fixture: 'misago-fixture',
       fixture: 'misago-fixture',

+ 96 - 0
misago/frontend/test/utils/mock-user.js

@@ -0,0 +1,96 @@
+(function () {
+  'use strict';
+
+  window.mockUser = function(properties) {
+    var user = {
+      "id": 42,
+      "username": "BobBoberson",
+      "slug": "bobboberson",
+      "email": "bob@example.com",
+      "joined_on": "2015-05-04T20:16:41.084500Z",
+      "is_hiding_presence": false,
+      "title": null,
+      "full_title": "Forum team",
+      "short_title": "Team",
+      "rank": {
+          "id": 1,
+          "name": "Forum team",
+          "slug": "forum-team",
+          "description": null,
+          "title": "Team",
+          "css_class": "team",
+          "is_tab": true
+      },
+      "avatar_hash": 'a0b9c8d7',
+      "new_notifications": 0,
+      "limits_private_thread_invites_to": 0,
+      "unread_private_threads": 0,
+      "sync_unread_private_threads": false,
+      "subscribe_to_started_threads": 2,
+      "subscribe_to_replied_threads": 2,
+      "threads": 0,
+      "posts": 0,
+      "acl": {
+          "can_delete_users_newer_than": 3,
+          "can_see_users_name_history": 1,
+          "can_moderate_avatars": 1,
+          "can_be_warned": 0,
+          "can_see_reports": [
+              3,
+              4,
+              5
+          ],
+          "can_follow_users": 1,
+          "can_see_users_emails": 1,
+          "can_see_users_online_list": 1,
+          "can_moderate_signatures": 1,
+          "can_start_private_threads": 1,
+          "name_changes_allowed": 5,
+          "can_add_everyone_to_private_threads": 1,
+          "_acl_version": 0,
+          "can_rename_users": 0,
+          "can_browse_users_list": 1,
+          "allow_signature_links": 1,
+          "visible_forums": [
+              3,
+              4,
+              5
+          ],
+          "can_warn_users": 1,
+          "can_report_private_threads": 1,
+          "can_search_users": 1,
+          "can_use_private_threads": 1,
+          "can_be_blocked": 0,
+          "can_review_moderated_content": [
+              3,
+              4,
+              5,
+              1
+          ],
+          "can_delete_users_with_less_posts_than": 7,
+          "can_moderate_private_threads": 1,
+          "can_see_ban_details": 1,
+          "can_delete_warnings": 0,
+          "can_see_users_ips": 1,
+          "allow_signature_blocks": 0,
+          "can_ban_users": 0,
+          "max_ban_length": 2,
+          "can_have_signature": 1,
+          "allow_signature_images": 0,
+          "can_see_hidden_users": 1,
+          "max_private_thread_participants": 15,
+          "can_cancel_warnings": 1,
+          "name_changes_expire": 0,
+          "can_lift_bans": 0,
+          "max_lifted_ban_length": 2,
+          "can_see_other_users_warnings": 1
+      }
+    };
+
+    if (properties) {
+      return $.extend(user, properties);
+    } else {
+      return user;
+    }
+  };
+}());

+ 3 - 1
misago/frontend/test/utils/qunit-boilerplate.js

@@ -8,7 +8,9 @@
     var wrappedBeforeEach = conf.beforeEach;
     var wrappedBeforeEach = conf.beforeEach;
     conf.beforeEach = function() {
     conf.beforeEach = function() {
       m.deps(window.mock());
       m.deps(window.mock());
-      wrappedBeforeEach();
+      if (wrappedBeforeEach) {
+        wrappedBeforeEach();
+      }
     };
     };
 
 
     var wrappedAfterEach = conf.afterEach;
     var wrappedAfterEach = conf.afterEach;

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

@@ -1 +1 @@
-/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */hr,img{border:0}body,figure{margin:0}.img-thumbnail,.table,label{max-width:100%}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px}.alerts,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%;font-size:10px;-webkit-tap-highlight-color:transparent}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-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active,.btn.active,.btn:active,.form-control,.navbar-toggle,.open>.dropdown-toggle.btn-danger,.open>.dropdown-toggle.btn-default,.open>.dropdown-toggle.btn-info,.open>.dropdown-toggle.btn-success,.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}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}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border-top:1px solid #eee}.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,.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}ol,ul{margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-inline{margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-bottom:20px}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[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 ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;color:#777}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{margin-bottom:20px;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{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;word-break:break-all;word-wrap:break-word;color:#333;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:768px){.container{width:750px}}@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,.material-icon{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{display:block;width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px}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[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}.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}.btn,.nav{margin-bottom:0}@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}}.btn-block,input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.nav-justified>.dropdown .dropdown-menu,.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}.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 .control-label{text-align:right;margin-bottom:0;padding-top:7px}.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;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.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{outline:0;-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,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,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.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,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.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,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,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,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,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,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,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,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}.nav>li,.nav>li>a{display:block;position:relative}.collapsing{position:relative;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}.nav{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{color:#777}.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{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:#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}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.modal,.tab-content>.tab-pane{display:none}.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-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>.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}.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: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}.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}}@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}}@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-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}.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}.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)}.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}.btn.btn-loading,.btn.btn-loading:active,.btn.btn-loading:focus,.btn.btn-loading:hover,.btn.btn-loading:link,.btn.btn-loading:visited,.text-hide{color:transparent}.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)}.modal{position:fixed;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 .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;outline:0}.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;min-height:16.43px}.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}.affix,.alerts{position:fixed}@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,.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,.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;text-shadow:none;background-color:transparent;border:0}@-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}}@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}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 p,.loader-compact>div,.material-icon,.navbar .navbar-full .navbar-brand>*{display:inline-block}.alerts{top:-100%;width:100%;z-index:1060;text-align:center;font-size:18px;transition:top 300ms ease}.alerts.in{top:0;transition:top 200ms ease}.alerts 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%}.btn.btn-loading.btn-default .loader-compact>div,.loader-compact>div{background-color:#333}.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;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)}}.navbar .navbar-full .navbar-brand img{height:16px}.navbar .navbar-full .nav-guest,.navbar .navbar-full .nav-user{float:right}@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-weight:400;font-style:normal;width:1em;height:1em;line-height:1;text-align:center;text-transform:none;letter-spacing:normal;-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}}.material-icon.form-control-feedback{top:6px;right:24px;font-size:1.42857143;line-height:1.42857143}.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-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}@media screen and (max-width:991px){.page-error{text-align:center}.page-error .error-icon{margin:30px}.page-error .error-icon .material-icon{font-size:160px}}@media screen and (min-width:992px){.page-error .error-panel{margin:60px auto;max-width:779.35px;overflow:auto}.page-error .error-icon{float:left}.page-error .error-icon .material-icon{font-size:80px}.page-error .error-message{margin-left:100px}}
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */hr,img{border:0}body,figure{margin:0}.img-thumbnail,.table,label{max-width:100%}.alerts,a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-size:10px;-webkit-tap-highlight-color:transparent}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-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active,.btn.active,.btn:active,.form-control,.navbar-toggle,.open>.dropdown-toggle.btn-danger,.open>.dropdown-toggle.btn-default,.open>.dropdown-toggle.btn-info,.open>.dropdown-toggle.btn-success,.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}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}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border-top:1px solid #eee}.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,.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}ol,ul{margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-inline{margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-bottom:20px}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[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 ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;color:#777}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{margin-bottom:20px;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{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;word-break:break-all;word-wrap:break-word;color:#333;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:768px){.container{width:750px}}@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,.material-icon{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{display:block;width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px}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[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}.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}.btn,.nav{margin-bottom:0}@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}}.btn-block,input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.nav-justified>.dropdown .dropdown-menu,.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}.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 .control-label{text-align:right;margin-bottom:0;padding-top:7px}.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;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.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{outline:0;-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,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,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.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,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.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,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,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,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,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,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,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,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}.nav>li,.nav>li>a{display:block;position:relative}.collapsing{position:relative;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}.nav{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{color:#777}.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{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:#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{position:relative;min-height:50px;margin-bottom:20px;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: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}.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}}@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}}@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-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}.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}.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)}.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}.progress,.well{margin-bottom:20px}.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;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)}.well{min-height:20px;padding:19px;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}.modal{display:none;position:fixed;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 .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;outline:0}.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;min-height:16.43px}.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}.affix,.alerts{position:fixed}@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,.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,.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}@-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}}@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}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 p,.loader-compact>div,.material-icon,.navbar .navbar-full .navbar-brand>*{display:inline-block}.alerts{top:-100%;width:100%;z-index:1060;text-align:center;font-size:18px;transition:top 300ms ease}.alerts.in{top:0;transition:top 200ms ease}.alerts 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%}.btn.btn-loading.btn-default .loader-compact>div,.loader-compact>div{background-color:#333}.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;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 .navbar-full .navbar-brand img{height:16px}.navbar .navbar-full .nav-guest,.navbar .navbar-full .nav-user{float:right}@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-weight:400;font-style:normal;width:1em;height:1em;line-height:1;text-align:center;text-transform:none;letter-spacing:normal;-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}}.material-icon.form-control-feedback{top:6px;right:24px;font-size:1.42857143;line-height:1.42857143}.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-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}@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}}

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

@@ -1,3 +1,3 @@
-!function(){"use strict";window.Misago=function(){var t=Object.getPrototypeOf(this),e=this;this._initServices=function(n){var o=new t.OrderedList(n).order(!1);o.forEach(function(t){var n=null;n=void 0!==t.item.factory?t.item.factory:t.item;var o=n(e);o&&(e[t.key]=o)})},this._destroyServices=function(n){var o=new t.OrderedList(n).order();o.reverse(),o.forEach(function(t){void 0!==t.destroy&&t.destroy(e)})},this.context={SETTINGS:{}},this.setup=!1,this.init=function(e,n){this.setup={fixture:t.get(e,"fixture",null),test:t.get(e,"test",!1),api:t.get(e,"api","/api/")},n&&(this.context=n),this._initServices(t._services)},this.destroy=function(){this._destroyServices(t._services)}};var t=window.Misago.prototype;t._services=[],t.addService=function(e,n,o){t._services.push({key:e,item:n,after:t.get(o,"after"),before:t.get(o,"before")})}}(),function(t){"use strict";t.has=function(t,e){return t?t.hasOwnProperty(e):!1},t.get=function(e,n,o){return t.has(e,n)?e[n]:void 0!==o?o:void 0},t.pop=function(e,n,o){var r=t.get(e,n,o);return t.has(e,n)&&(e[n]=null),r}}(Misago.prototype),function(t){"use strict";function e(t,e,n){n.retain=!0}t.input=function(t){var n={disabled:t.disabled||!1,config:t.config||e};t.placeholder&&(n.placeholder=t.placeholder),t.autocomplete===!1&&(n.autocomplete="off");var o="input";return t.id&&(o+="#"+t.id,n.key="field-"+t.id),o+=".form-control"+(t["class"]||""),o+='[type="'+(t.type||"text")+'"]',t.value&&(n.value=t.value(),n.oninput=m.withAttr("value",t.value)),m(o,n)}}(Misago.prototype),function(t){"use strict";var e=function(){};t.stateHooks=function(t,n,o){if(t._hasLifecycleHooks)return t;t._hasLifecycleHooks=!0,t.isActive=!0;var r=t.controller||e;if(t.controller=function(){t.isActive=!0;var n=r.apply(t,arguments)||{},o=n.onunload||e;return n.onunload=function(){o.apply(t,arguments),t.isActive=!1},n},t.vm&&t.vm.init){if(!t.loading){var i=n.bind(t);t.loading=i}var s=t.view;t.view=function(){return t.vm.isReady?s.apply(t,arguments):t.loading.apply(t,arguments)};var a=o.bind(t),u=t.vm.init;t.vm.init=function(){var e=arguments,n=u.apply(t.vm,e);n&&n.then(function(){if(t.isActive&&t.vm.ondata){for(var n=[],o=0;o<arguments.length;o++)n.push(arguments[o]);for(var r=0;r<e.length;r++)n.push(e[r]);t.vm.ondata.apply(t.vm,n)}},function(e){t.isActive&&a(e)})}}return t}}(Misago.prototype),function(t){"use strict";t.OrderedList=function(e){this.isOrdered=!1,this._items=e||[],this.add=function(e,n,o){this._items.push({key:e,item:n,after:t.get(o,"after"),before:t.get(o,"before")})},this.get=function(t,e){for(var n=0;n<this._items.length;n++)if(this._items[n].key===t)return this._items[n].item;return e},this.has=function(t){return void 0!==this.get(t)},this.values=function(){for(var t=[],e=0;e<this._items.length;e++)t.push(this._items[e].item);return t},this.order=function(t){return this.isOrdered||(this._items=this._order(this._items),this.isOrdered=!0),t||"undefined"==typeof t?this.values():this._items},this._order=function(t){function e(t){var e=-1;-1===r.indexOf(t.key)&&(t.after?(e=r.indexOf(t.after),-1!==e&&(e+=1)):t.before&&(e=r.indexOf(t.before)),-1!==e&&(o.splice(e,0,t),r.splice(e,0,t.key)))}var n=[];t.forEach(function(t){n.push(t.key)});var o=[],r=[];t.forEach(function(t){t.after||t.before||(o.push(t),r.push(t.key))}),t.forEach(function(t){"_end"===t.before&&(o.push(t),r.push(t.key))});for(var i=200;i>0&&n.length!==r.length;)i-=1,t.forEach(e);return o}}}(Misago.prototype),function(t){t.serializeDatetime=function(t){return t?t.format():null},t.deserializeDatetime=function(t){return t?moment(t):null}}(Misago.prototype),function(t){"use strict";t.startsWith=function(t,e){return 0===t.indexOf(e)},t.endsWith=function(t,e){return-1!==t.indexOf(e,t.length-e.length)}}(Misago.prototype),function(t){"use strict";t.UrlConf=function(){var e=this;this._patterns=[],this.patterns=function(){return this._patterns};var n=function(t,e){return(t+e).replace("//","/")},o=function(t,o){for(var r=0;r<o.length;r++)e.url(n(t,o[r].pattern),o[r].component,o[r].name)};this.url=function(e,n,r){""===e&&(e="/"),n instanceof t.UrlConf?o(e,n.patterns()):this._patterns.push({pattern:e,component:n.replace(/_/g,"-"),name:r||n})}}}(Misago.prototype),function(t){"use strict";t.loadingPage=function(t){return m(".page.page-loading",t.component("loader"))}}(Misago.prototype),function(t){"use strict";var e=function(e){if(-1!==document.cookie.indexOf(e)){var n=new RegExp(e+"=([^;]*)"),o=t.get(document.cookie.match(n),0);return o.split("=")[1]}return null},n=function(n){this.refreshCsrfToken=function(){this.csrfToken=e(n.context.CSRF_COOKIE_NAME)},this.refreshCsrfToken();var o={};this.ajax=function(e,n,r,i){var s=m.deferred(),a={url:n,method:e,headers:{"X-CSRFToken":this.csrfToken},data:r||{},dataType:"json",success:function(r){"GET"===e&&t.pop(o,n),s.resolve(r)},error:function(r){"GET"===e&&t.pop(o,n);var i=r.responseJSON||{};i.status=r.status,i.statusText=r.statusText,s.reject(i)}};return i?void 0:($.ajax(a),s.promise)},this.get=function(e){var r=t.pop(n.context,e);if(r){var i=m.deferred();return i.resolve(r),i.promise}return void 0!==o[e]?o[e]:(o[e]=this.ajax("GET",e),o[e])},this.post=function(t,e){return this.ajax("POST",t,e)},this.patch=function(t,e){return this.ajax("PATCH",t,e)},this.put=function(t,e){return this.ajax("PUT",t,e)},this["delete"]=function(t){return this.ajax("DELETE",t)}};t.addService("ajax",function(t){return new n(t)})}(Misago.prototype),function(t){"use strict";var e=5e3,n=70,o=9e3,r=300,i=function(t){var i=this;this.type="info",this.message=null,this.isVisible=!1;var s=function(r,s){i.type=r,i.message=s,i.isVisible=!0;var a=e;a+=s.length*n,a>o&&(a=o),t.runloop.runOnce(function(){m.startComputation(),i.isVisible=!1,m.endComputation()},"flash-message-hide",a)},a=function(e,n){t.runloop.stop("flash-message-hide"),t.runloop.stop("flash-message-show"),i.isVisible?(i.isVisible=!1,t.runloop.runOnce(function(){m.startComputation(),s(e,n),m.endComputation()},"flash-message-show",r)):s(e,n)};this.info=function(t){a("info",t)},this.success=function(t){a("success",t)},this.warning=function(t){a("warning",t)},this.error=function(t){a("error",t)}};t.addService("alert",{factory:function(t){return new i(t)}})}(Misago.prototype),function(t){"use strict";var e=function(t){if("object"==typeof t){var e=[];for(var n in t)if(t.hasOwnProperty(n)){var o=encodeURIComponent(n),r=encodeURIComponent(t[n]);e.push(o+"="+r)}return"?"+e.join("&")}return t+"/"},n=function(t,o){this.url=o.url||t.setup.api,this.url+=o.path?o.path+"/":o.related?o.related+"/":o.model+"s/",o.filters&&(this.url+=e(o.filters)),!o.url&&o.filters&&(o.model&&(this.related=function(e,r){return new n(t,{url:this.url,relation:o.model,related:e,filters:r})}),this.endpoint=function(e,o){return new n(t,{url:this.url,path:e,filters:o})}),this.get=function(){var e=null;return o.related?e=o.relation+":"+o.related:o.model&&(e=o.model),t.ajax.get(this.url).then(function(n){return e?n.results?(n.results.map(function(n){return t.models["new"](e,n)}),n):t.models["new"](e,n):n})},this.post=function(e){return t.ajax.post(this.url,e)},this.patch=function(e){return t.ajax.patch(this.url,e)},this.put=function(e){return t.ajax.put(this.url,e)},this["delete"]=function(){return t.ajax["delete"](this.url)},this.then=function(t,e){return this.get().then(t,e)}},o=function(t){this.model=function(e,o){return new n(t,{model:e,filters:o})},this.endpoint=function(e,o){return new n(t,{path:e,filters:o})},this.alert=function(e){var n=gettext("Unknown error has occured.");0===e.status&&(n=gettext("Lost connection with application.")),403===e.status&&(n=e.detail,"Permission denied"===n&&(n=gettext("You don't have permission to perform this action."))),404===e.status&&(n=gettext("Action link is invalid.")),t.alert.error(n)}};t.addService("api",function(t){return new o(t)})}(Misago.prototype),function(t){"use strict";var e=function(t){t.user=t.models.deserialize("user",t.context.user)};t.addService("auth",function(t){return new e(t)},{after:"model:user"})}(Misago.prototype),function(t){"use strict";var e=function(){var t=m.deferred();t.resolve(),this.load=function(){return t.promise},this.value=function(){return null}},n=function(t){var e=this;this.loading=!1,this.question=null,this.value=m.prop("");var n=m.deferred();this.load=function(){return this.value(""),this.question||this.loading||(this.loading=!0,t.api.endpoint("captcha-question").get().then(function(t){e.question=t,n.resolve()},function(){t.api.alert(gettext("Failed to load CAPTCHA.")),n.reject()}).then(function(){e.loading=!0})),n.promise},this.component=function(e){return t.component("form-group",{label:this.question.question,labelClass:e.labelClass||null,controlClass:e.controlClass||null,control:t.input({value:t.validate(e.form,"captcha"),id:"id_captcha",disabled:e.form.isBusy}),validation:e.form.errors,validationKey:"captcha",helpText:this.question.help_text})},this.validator=function(){return[]}},o=function(t){this.included=!1,this.question=null;var e=m.deferred(),n=function(e){"undefined"!=typeof grecaptcha?e.resolve():t.runloop.runOnce(function(){n(e)},"loading-grecaptcha",150)};this.load=function(){return"undefined"!=typeof grecaptcha&&grecaptcha.reset(),this.included||(t.include("https://www.google.com/recaptcha/api.js",!0),this.included=!0),n(e),e.promise};var o=function(e,n,o){o.retain=!0,n||grecaptcha.render("recaptcha",{sitekey:t.settings.recaptcha_site_key})};this.component=function(e){var n=m("#recaptcha",{config:o});return t.component("form-group",{label:gettext("Security test"),labelClass:e.labelClass||null,controlClass:e.controlClass||null,control:n,validation:e.form.errors,validationKey:"captcha"})},this.value=function(){return"undefined"!=typeof grecaptcha?grecaptcha.getResponse():""},this.clean=function(t){t.errors.captcha=this.value()?!0:[gettext("This field is required.")]},this.validator=function(){return[]}},r=function(t){var r={no:e,qa:n,re:o},i=new r[t.settings.captcha_type](t);this.value=i.value,this.load=function(){return i.load()},this.component=function(t){return i.component?i.component(t):null},this.validator=function(){return i.validator?i.validator():null},this.clean=function(t){i.clean?i.clean(t):t.errors.captcha=!0}};t.addService("captcha",function(t){return new r(t)},{after:"include"})}(Misago.prototype),function(t){"use strict";var e=function(t,e){if(this._components[t]){if(arguments.length>1){for(var n=[this._components[t]],o=1;o<arguments.length;o+=1)n.push(arguments[o]);return n.push(this),m.component.apply(void 0,n)}return m.component(this._components[t],this)}this._components[t]=e};t.addService("components",function(t){t._components={},t.component=e})}(Misago.prototype),function(t){"use strict";t.addService("conf",function(e){e.settings=t.get(e.context,"SETTINGS",{})})}(Misago.prototype),function(t){"use strict";var e=function(t){var e=t.submit,n=t.success,o=t.error;return t.isBusy=!1,t.errors=null,t.submit=function(){return t.isBusy?!1:(t.clean?t.clean()&&(t.isBusy=!0,e.apply(t)):t.isBusy=!0,!1)},t.success=function(){m.startComputation(),n.apply(t,arguments),t.isBusy=!1,m.endComputation()},t.error=function(){m.startComputation(),o.apply(t,arguments),t.isBusy=!1,m.endComputation()},t.hasErrors=function(){if(null===t.errors)return!1;for(var e in t.validation)if(t.validation.hasOwnProperty(e)&&t.errors[e]!==!0)return!0;return!1},t},n=function(t,n){return this._forms[t]?e(n?new this._forms[t](n,this):new this._forms[t](this)):void(this._forms[t]=n)};t.addService("forms",function(t){t._forms={},t.form=n})}(Misago.prototype),function(t){"use strict";t.addService("forum-layout",{factory:function(t){t.setup.fixture&&m.mount(document.getElementById(t.setup.fixture),t.component("forum-layout"))},destroy:function(t){t.setup.fixture&&m.mount(document.getElementById(t.setup.fixture),null)}},{before:"start-routing"})}(Misago.prototype),function(t){"use strict";var e=function(t,e){e||(t=this.context.STATIC_URL+t),$.ajax({url:t,cache:!0,dataType:"script"})};t.addService("include",function(t){t.include=e},{after:"conf"})}(Misago.prototype),function(t){"use strict";var e=function(){var t=this,e=document.getElementById("misago-modal"),n="click.misago-modal";$(e).on(n,"a",function(){t.hide()}),this.destroy=function(){$(e).off(),$("body").removeClass("modal-open"),$(".modal-backdrop").remove()};var o=$(e).modal({show:!1});this.open=!1,o.on("hidden.bs.modal",function(){t.open&&(m.mount(e,null),this.open=!1)}),this.show=function(t){this.open=!0,m.mount(e,t),o.modal("show")},this.hide=function(){o.modal("hide")}};t.addService("_modal",{factory:function(){return new e},destroy:function(t){t._modal.destroy()}},{after:"start-routing"})}(Misago.prototype),function(t){"use strict";var e=function(t,e){if(this._modals[t]){for(var n=[this._modals[t]],o=1;o<arguments.length;o+=1)n.push(arguments[o]);n.push(this),this._modal.show(m.component.apply(m,n))}else t?this._modals[t]=e:this._modal.hide()};t.addService("modals",function(t){t._modals={},t.modal=e},{after:"_modal"})}(Misago.prototype),function(t){"use strict";var e=function(){this.classes={},this.deserializers={},this.relations={},this.add=function(t,e){if(e["class"]&&(this.classes[t]=e["class"]),e.deserialize&&(this.deserializers[t]=e.deserialize),e.relations)for(var n in e.relations)e.relations.hasOwnProperty(n)&&(this.relations[t+":"+n]=e.relations[n])},this["new"]=function(t,e){return this.classes[t]?new this.classes[t](e):e},this.deserialize=function(t,e){return this.relations[t]&&(t=this.relations[t]),this.deserializers[t]?this["new"](t,this.deserializers[t](e,this)):this["new"](t,e)}};t.addService("models",function(){return new e})}(Misago.prototype),function(t){"use strict";t.addService("set-momentjs-locale",function(){moment.locale($("html").attr("lang"))})}(Misago.prototype),function(t){"use strict";var e=function(e){var n=this;this.baseUrl=$("base").attr("href");var o=t.get(e.context,"STATIC_URL","/"),r=t.get(e.context,"MEDIA_URL","/");this.urls={},this.reverses={};var i=function(t){t.patterns().forEach(function(t){var o=n.baseUrl+t.pattern;o=o.replace("//","/"),n.urls[o]=e.route(t.component),n.reverses[t.name]=o})};this.startRouting=function(t,n){i(t),this.fixture=n,m.route.mode=e.setup.test?"search":"pathname",m.route(n,"/",this.urls)},this.url=function(t){return this.reverses[t]},this.delegateElement=null,this.cleanUrl=function(t){if(t){var e="/"===t.substr(0,1)&&"//"!==t.substr(0,2);if(!e){var n=window.location;if("//"!==t.substr(0,2)){var i=t.substr(0,n.protocol.length+2);if(i!==n.protocol+"//")return;t=t.substr(n.protocol.length+2)}else t=t.substr(2);if(t.substr(0,n.host.length)!==n.host)return;t=t.substr(n.host.length)}if(t.substr(0,this.baseUrl.length)===this.baseUrl&&t.substr(0,o.length)!==o&&t.substr(0,r.length)!==r){var s="/user-avatar/";if(t.substr(0,s.length)!==s)return t}}};var s="click.misago-router";this.delegateClicks=function(t){this.delegateElement=t,$(this.delegateElement).on(s,"a",function(t){var e=n.cleanUrl(t.target.href);e&&(e!=m.route()&&m.route(e),t.preventDefault())})},this.destroy=function(){$(this.delegateElement).off(s)};var a=function(t){return function(e){return t+e}};this.staticUrl=a(o),this.mediaUrl=a(r),this.error403=function(t){var n=null;n=t.ban?e.route("error:banned",t.detail,e.models.deserialize("ban",t.ban)):e.route("error:403",t.detail),m.mount(this.fixture,n)},this.error404=function(){m.mount(this.fixture,e.route("error:404"))},this.error500=function(){m.mount(this.fixture,e.route("error:500"))},this.error0=function(){m.mount(this.fixture,e.route("error:0"))},this.errorPage=function(t){0===t.status&&this.error0(),500===t.status&&this.error500(),404===t.status&&this.error404(),403===t.status&&this.error403(t)}};t.addService("router",function(t){return new e(t)}),t.addService("start-routing",function(e){e.router.startRouting(t.urls,document.getElementById("router-fixture")),e.router.delegateClicks(document.getElementById(e.setup.fixture))},{before:"_end"})}(Misago.prototype),function(t){"use strict";var e=function(e){if(e._hasRouteBoilerplate)return e;e._hasRouteBoilerplate=!0;var n=function(){var t=this.container;return m(".page.page-loading",t.component("loader"))},o=function(t){this.isActive&&this.container.router.errorPage(t)};return t.stateHooks(e,n,o)};t.addService("routes",function(t){t._routes={},t.route=function(n,o){if(this._routes[n]){if(arguments.length>1){for(var r=[this._routes[n]],i=1;i<arguments.length;i+=1)r.push(arguments[i]);return r.push(this),m.component.apply(void 0,r)}return m.component(this._routes[n],this)}o.container=t,this._routes[n]=e(o)}})}(Misago.prototype),function(t){"use strict";var e=function(t){var e=this;this._intervals={};var n=function(t){e._intervals[t]&&(window.clearTimeout(e._intervals[t]),e._intervals[t]=null)};this.run=function(o,r,i){this._intervals[r]=window.setTimeout(function(){n(r);var s=o(t);s!==!1&&e.run(o,r,i)},i)},this.runOnce=function(e,o,r){this._intervals[o]=window.setTimeout(function(){n(o),e(t)},r)},this.stop=function(t){for(var e in this._intervals)t&&t!==e||n(e)}};t.addService("runloop",{factory:function(t){return new e(t)},destroy:function(t){t.runloop.stop()}})}(Misago.prototype),function(t){"use strict";t.addService("start-tick",function(t){var e=m.prop();t.runloop.run(function(){m.startComputation(),e(e()+1),m.endComputation()},"tick",6e4)})}(Misago.prototype),function(t){"use strict";var e=function(t){this.set=function(e){e?this._set_complex(e):document.title=t},this._set_complex=function(e){"string"==typeof e&&(e={title:e});var n=e.title;if("undefined"!=typeof e.page&&e.page>1){var o=interpolate(gettext("page %(page)s"),{page:e.page},!0);n+=" ("+o+")"}"undefined"!=typeof e.parent&&(n+=" | "+e.parent),document.title=n+" | "+t}};t.addService("page-title",function(t){t.title=new e(t.settings.forum_name)})}(Misago.prototype),function(t){"use strict";var e=/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i,n=new RegExp("^[0-9a-z]+$","i");t.validators={required:function(){return function(t){return 0===$.trim(t).length?gettext("This field is required."):void 0}},email:function(t){return function(n){return e.test(n)?void 0:t||gettext("Enter a valid email address.")}},minLength:function(t,e){return function(n){var o="",r=$.trim(n).length;return t>r?(o=e?e(t,r):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).",t),interpolate(o,{limit_value:t,show_value:r},!0)):void 0}},maxLength:function(t,e){return function(n){var o="",r=$.trim(n).length;return r>t?(o=e?e(t,r):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).",t),interpolate(o,{limit_value:t,show_value:r},!0)):void 0}},usernameMinLength:function(t){var e=function(t){return ngettext("Username must be at least %(limit_value)s character long.","Username must be at least %(limit_value)s characters long.",t)};return this.minLength(t.username_length_min,e)},usernameMaxLength:function(t){var e=function(t){return ngettext("Username cannot be longer than %(limit_value)s character.","Username cannot be longer than %(limit_value)s characters.",t)};return this.maxLength(t.username_length_max,e)},usernameContent:function(){return function(t){return n.test($.trim(t))?void 0:gettext("Username can only contain latin alphabet letters and digits.")}},passwordMinLength:function(t){var e=function(t){return ngettext("Valid password must be at least %(limit_value)s character long.","Valid password must be at least %(limit_value)s characters long.",t)};return this.minLength(t.password_length_min,e)}};var o=function(e,n){var o=t.validators.required()(e),r=[];if(o)return[o];for(var i in n)o=n[i](e),o&&r.push(o);return r.length?r:!0},r=function(t){var e={},n=null,r=!0;for(var i in t.validation)t.validation.hasOwnProperty(i)&&(n=t[i](),e[i]=o(t[i](),t.validation[i]),e[i]!==!0&&(r=!1));return t.errors=e,r},i=function(t,e){return e?function(n){var r=null;return"undefined"!=typeof n?(r=o(n,t.validation[e]),r&&(t.errors||(t.errors={}),t.errors[e]=r),t[e](n),t[e](n)):t[e]()}:r(t)};t.addService("validate",{factory:function(){return i}})}(Misago.prototype),function(t){"use strict";var e=function(t){this.included=!1,this.scorePassword=function(t,e){return zxcvbn(t,e).score},this.include=function(){t.include("misago/js/zxcvbn.js"),this.included=!0};var e=function(n){"undefined"!=typeof zxcvbn?n.resolve():t.runloop.runOnce(function(){e(n)},"loading-zxcvbn",150)},n=m.deferred();this.load=function(){return this.included||this.include(),e(n),n.promise}};t.addService("zxcvbn",function(t){return new e(t)},{after:"include"})}(Misago.prototype),function(t){"use strict";var e=function(t){this.message={html:t.message.html,plain:t.message.plain},this.expires_on=t.expires_on},n=function(e){return e.expires_on=t.deserializeDatetime(e.expires_on),e};t.addService("model:ban",function(t){t.models.add("ban",{"class":e,deserialize:n})},{after:"models"})}(Misago.prototype),function(t){"use strict";var e=function(t){this.title=t.title,this.body=t.body,this.link=t.link};t.addService("model:legal-page",function(t){t.models.add("legal-page",{"class":e})},{after:"models"})}(Misago.prototype),function(t){"use strict";var e=function(t){this.id=t.id,this.isAuthenticated=!!this.id,this.isAnonymous=!this.isAuthenticated,this.slug=t.slug,this.username=t.username,this.acl=t.acl,this.rank=t.rank},n=function(e){return e.joined_on&&(e.joined_on=t.deserializeDatetime(e.joined_on)),e};t.addService("model:user",function(t){t.models.add("user",{"class":e,deserialize:n})},{after:"models"})}(Misago.prototype),function(t){"use strict";var e=function(t){var e=[m("p.lead",t.message)];return t.help&&e.push(m("p.help",t.help)),m(".page.page-error.page-error-"+t.code,m(".container",m(".error-panel",[m(".error-icon",m("span.material-icon",t.icon)),m(".error-message",e)])))},n={controller:function(){this.container.title.set(gettext("You are banned"))},view:function(t,e,n){var o=[];o.push(n.message.html?m(".lead",m.trust(n.message.html)):e?m("p.lead",e):m("p.lead",gettext("You are banned.")));var r=null;return r=n.expires_on?n.expires_on.isAfter(moment())?interpolate(gettext("This ban expires %(expires_on)s."),{expires_on:n.expires_on.fromNow()},!0):gettext("This ban has expired."):gettext("This ban is permanent."),o.push(m("p",r)),m(".page.page-error.page-error-banned",m(".container",m(".error-panel",[m(".error-icon",m("span.material-icon","highlight_off")),m(".error-message",o)])))}},o={controller:function(){this.container.title.set(gettext("Page not available"))},view:function(t,n){return"Permission denied"===n&&(n=gettext("You don't have permission to access this page.")),e({code:403,icon:"remove_circle_outline",message:gettext("This page is not available."),help:n})}},r={controller:function(){this.container.title.set(gettext("Page not found"))},view:function(){return e({code:404,icon:"info_outline",message:gettext("Requested page could not be found."),help:gettext("The link you followed was incorrect or the page has been moved or deleted.")})}},i={controller:function(){this.container.title.set(gettext("Application error occured"))},view:function(){return e({code:500,icon:"error_outline",message:gettext("Requested page could not be displayed due to an error."),help:gettext("Please try again later or contact site staff if error persists.")})}},s={controller:function(){this.container.title.set(gettext("Lost connection with application"))},view:function(){return e({code:0,icon:"sync_problem",message:gettext("Could not connect to application."),help:gettext("This may be caused by problems with your connection or application server. Please check your internet connection and refresh page if problem persists.")})}};t.addService("route:error-pages",function(t){t.route("error:banned",n),t.route("error:403",o),t.route("error:404",r),t.route("error:500",i),t.route("error:0",s)},{after:"routes"})}(Misago.prototype),function(t){"use strict";var e={controller:function(t){return document.title=t.settings.forum_index_title||t.settings.forum_name,{active:function(){t.modal("register-complete",{activation:"active",username:"BobBoberson",email:"bob-boberson@somewhere.com"})},user:function(){t.modal("register-complete",{activation:"by_user",username:"BobBoberson",email:"bob-boberson@somewhere.com"})},admin:function(){t.modal("register-complete",{activation:"by_admin",username:"BobBoberson",email:"bob-boberson@somewhere.com"})}}},view:function(t,e){return m(".container",[m("h1","Buttons"),m("p","Test registration successful modal!"),m("",e.component("button",{"class":".btn-success",label:"Registration done, account active",onclick:t.active})),m("",e.component("button",{"class":".btn-warning",label:"Registration done, account inactive (user)",onclick:t.user})),m("",e.component("button",{"class":".btn-danger",label:"Registration done, account inactive (admin)",onclick:t.admin}))])}};t.addService("route:index",function(t){t.route("index",e)},{after:"routes"})}(Misago.prototype),function(t){"use strict";var e=function(e,n){var o=e.replace(/_/g,"-");return{controller:function(n){t.get(n.settings,e+"_link")?window.location=t.get(n.settings,e+"_link"):this.vm.init(this,n)},vm:{page:null,isReady:!1,init:function(t,e){return this.isReady?void e.title.set(this.title):(e.title.set(),e.api.model("legal-page",o))},ondata:function(t,e,o){m.startComputation(),t.link?window.location=t.link:(t.title=t.title||n,this.page=t,this.isReady=!0,m.endComputation(),e.isActive&&o.title.set(this.page.title))}},view:function(t,e){return m(".page.page-legal.page-legal-"+o,[e.component("header",{title:this.vm.page.title}),m(".container",e.component("markup",this.vm.page.body))])}}};t.addService("route:legal-pages",function(t){t.route("terms-of-service",e("terms_of_service",gettext("Terms of service"))),t.route("privacy-policy",e("privacy_policy",gettext("Privacy policy")))},{after:"routes"})}(Misago.prototype),function(t){"use strict";var e=function(t){return-1!==[!!t.forum_footnote,!!t.terms_of_service,!!t.terms_of_service_link,!!t.privacy_policy,!!t.privacy_policy_link].indexOf(!0)},n={view:function(t,n){var o=null;return e(n.settings)&&(o=n.component("footer:menu")),m("footer.forum-footer",[m(".container",m(".footer-content",[o,n.component("footer:branding")]))])}};t.addService("component:footer",function(t){t.component("footer",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(e,n,o){var r=t.get(e.settings,n+"_link");return!r&&t.get(e.settings,n)&&(r=e.router.url(n)),r?m("li",m("a",{href:r},t.get(e.settings,n+"_title",o))):null},n={isVisible:function(t){return-1!==[!!t.forum_footnote,!!t.terms_of_service,!!t.terms_of_service_link,!!t.privacy_policy,!!t.privacy_policy_link].indexOf(!0)},view:function(t,n){var o=[];return n.settings.forum_footnote&&o.push(m("li.forum-footnote",m.trust(n.settings.forum_footnote))),o.push(e(n,"terms_of_service",gettext("Terms of service"))),o.push(e(n,"privacy_policy",gettext("Privacy policy"))),m("ul.list-inline.footer-nav",o)}};t.addService("component:footer:menu",function(t){t.component("footer:menu",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(){return m("a.misago-branding[href=http://misago-project.org]",["powered by ",m("strong","misago")])}};t.addService("component:footer:branding",function(t){t.component("footer:branding",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){return m(".modal-header",[m('button.close[type="button"]',{"data-dismiss":"modal","aria-label":gettext("Close")},m("span",{"aria-hidden":"true"},m.trust("&times;"))),m("h4#misago-modal-label.modal-title",e)])}};t.addService("component:modal:header",function(t){t.component("modal:header",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n=function(){document.location.reload()},o={controller:function(t,e){"active"===t.activation&&e.runloop.runOnce(n,"refresh-after-registration",1e4)},view:function(t,n,o){var r=null;return r="active"===n.activation?this.active(n):this.inactive(n),m('.modal-dialog.modal-message.modal-register[role="document"]',{config:e},m(".modal-content",[o.component("modal:header",gettext("Registration complete")),m(".modal-body",r)]))},active:function(t){var e=gettext("%(username)s, your account has been created and you were signed in.");return[m(".message-icon",m("span.material-icon","check")),m(".message-body",[m("p.lead",interpolate(e,{username:t.username},!0)),m("p",gettext("The page will refresh automatically in 10 seconds.")),m("p",m('button[type="button"].btn.btn-default',{onclick:n},gettext("Refresh page")))])]},inactive:function(t){var e=null,n=null;return"user"===t.activation?(e=gettext("%(username)s, your account has been created but you need to activate it before you will be able to sign in."),n=gettext("We have sent an e-mail to %(email)s with link that you have to click to activate your account.")):"admin"===t.activation&&(e=gettext("%(username)s, your account has been created but board administrator will have to activate it before you will be able to sign in."),n=gettext("We will send an e-mail to %(email)s when this takes place.")),[m(".message-icon",m("span.material-icon","info_outline")),m(".message-body",[m("p.lead",interpolate(e,{username:t.username},!0)),m("p",interpolate(n,{email:t.email},!0))])]}};t.addService("modal:register-complete",function(t){t.modal("register-complete",o)},{after:"modals"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n={controller:function(t){return{form:t.form("register")}},view:function(t,n){var o=n.captcha.component({form:t.form,labelClass:".col-md-4",controlClass:".col-md-8"}),r=null,i=n.settings.terms_of_service_link;return!i&&n.settings.terms_of_service&&(i=n.router.url("terms_of_service")),i&&(r=m("a",{href:i},m.trust(interpolate(gettext("By registering you agree to site's %(terms)s."),{terms:"<strong>"+gettext("terms and conditions")+"</strong>"},!0)))),m('.modal-dialog.modal-form.modal-register[role="document"]',{config:e},m(".modal-content",[n.component("modal:header",gettext("Register")),m("form.form-horizontal",{onsubmit:t.form.submit},[m('input[type="text"]',{name:"_username",style:"display: none"}),m('input[type="password"]',{name:"_password",style:"display: none"}),m(".modal-body",[n.component("form-group",{label:gettext("Username"),labelClass:".col-md-4",controlClass:".col-md-8",control:n.input({value:n.validate(t.form,"username"),id:"id_username",disabled:t.form.isBusy}),validation:t.form.errors,validationKey:"username"}),n.component("form-group",{label:gettext("E-mail"),labelClass:".col-md-4",controlClass:".col-md-8",control:n.input({value:n.validate(t.form,"email"),id:"id_email",disabled:t.form.isBusy}),validation:t.form.errors,validationKey:"email"}),n.component("form-group",{label:gettext("Password"),labelClass:".col-md-4",controlClass:".col-md-8",control:n.input({value:n.validate(t.form,"password"),type:"password",id:"id_password",disabled:t.form.isBusy}),validation:t.form.errors,validationKey:"password",helpText:n.component("password-strength",{inputs:[t.form.username(),t.form.email()],password:t.form.password()})}),o]),m(".modal-footer",[r,n.component("button",{"class":".btn-primary",submit:!0,loading:t.form.isBusy,label:gettext("Register account")})])])]))}};t.addService("modal:register",function(t){t.modal("register",n)},{after:"modals"})}(Misago.prototype),function(t){"use strict";function e(t,e,n){n.retain=!0}var n={controller:function(t){return{form:t.form("sign-in")}},view:function(n,o){return m('.modal-dialog.modal-sm.modal-signin[role="document"]',{config:e},m(".modal-content",[o.component("modal:header",gettext("Sign in")),m("form",{onsubmit:n.form.submit},[m(".modal-body",[m(".form-group",m(".control-input",t.input({
-disabled:n.form.isBusy,value:n.form.username,placeholder:gettext("Username or e-mail")}))),m(".form-group",m(".control-input",t.input({type:"password",disabled:n.form.isBusy,value:n.form.password,placeholder:gettext("Password")})))]),m(".modal-footer",o.component("button",{"class":".btn-primary.btn-block",submit:!0,loading:n.form.isBusy,label:gettext("Sign in")}))])]))}};t.addService("modal:sign-in",function(t){t.modal("sign-in",n)},{after:"modals"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){var n=".navbar.navbar-default.navbar-static-top";return m("nav"+n+'[role="navigation"]',[e.component("navbar:desktop")])}};t.addService("component:navbar",function(t){t.component("navbar",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e,n){var o=[m("img",{src:n.router.staticUrl("misago/img/site-logo.png"),alt:n.settings.forum_name})];return e&&o.push(e),m("a.navbar-brand",{href:n.router.url("index")},o)}};t.addService("component:navbar:desktop:brand",function(t){t.component("navbar:desktop:brand",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={controller:function(t){return{showSignIn:function(){t.modal("sign-in")},isBusy:!1,showRegister:function(){if("closed"===t.settings.account_activation)t.alert.info(gettext("New registrations are currently disabled."));else{m.startComputation(),this.isBusy=!0,m.endComputation();var e=this;m.sync([t.zxcvbn.load(),t.captcha.load()]).then(function(){t.modal("register")},function(){t.alert.error(gettext("Registation is not available now due to an error."))}).then(function(){m.startComputation(),e.isBusy=!1,m.endComputation()})}}}},view:function(t,e){return m("div.nav.nav-guest",[e.component("button",{"class":".navbar-btn.btn-default",onclick:t.showSignIn,disabled:t.isBusy,label:gettext("Sign in")}),e.component("button",{"class":".navbar-btn.btn-primary",onclick:t.showRegister.bind(t),loading:t.isBusy,label:gettext("Register")})])}};t.addService("component:navbar:desktop:guest-menu",function(t){t.component("navbar:desktop:guest-menu",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){var n=[];return e.settings.forum_branding_display&&n.push(e.component("navbar:desktop:brand",e.settings.forum_branding_text)),n.push(m("ul.nav.navbar-nav",[m("li",m("a",{config:m.route,href:e.router.url("index")},"Index"))])),n.push(e.user.isAuthenticated?e.component("navbar:desktop:user-menu"):e.component("navbar:desktop:guest-menu")),m(".container.navbar-full.hidden-xs.hidden-sm",n)}};t.addService("component:navbar:desktop",function(t){t.component("navbar:desktop",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={controller:function(){return{logout:function(){$("#hidden-logout-form").submit()}}},view:function(t,e){return m("div.nav.nav-user",[m("p.navbar-text",e.user.username),m("button.navbar-btn.btn.btn-default.navbar-right",{onclick:t.logout.bind(t)},gettext("Logout"))])}};t.addService("component:navbar:desktop:user-menu",function(t){t.component("navbar:desktop:user-menu",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";function e(t,e,n){n.retain=!0}var n={classes:{info:"alert-info",success:"alert-success",warning:"alert-warning",error:"alert-danger"},view:function(t,n){return m(".alerts",{config:e,"class":n.alert.isVisible?"in":"out"},m("p.alert",{"class":this.classes[n.alert.type]},n.alert.message))}};t.addService("component:alert",function(t){t.component("alert",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){var n={disabled:e.disabled||e.loading||!1,config:e.config||null,loading:e.loading||!1,type:e.submit?"submit":"button",onclick:e.onclick||null},o='button[type="'+n.type+'"].btn';n.loading&&(o+=".btn-loading"),e.id&&(o+="#"+e.id),o+=e["class"]||"";var r=e.label;return n.loading&&(r=[r,m(".loader-compact",[m(".bounce1"),m(".bounce2"),m(".bounce3")])]),m(o,n,r)}};t.addService("component:button",function(t){t.component("button",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=["text","password","email"],n={view:function(t,n){var o=".form-group",r=null,i=null,s=n.control.attrs.type,a=n.control.attrs.id,u=a+"_feedback",c=null,l=null,d=n.validationKey&&null!==n.validation;return n.control.attrs["aria-describedby"]="",d&&n.validation[n.validationKey]&&(l=e.indexOf(s)>=0,n.control.attrs["aria-describedby"]=u,n.validation[n.validationKey]===!0?(o+=".has-success",c=[m("span.material-icon.form-control-feedback",{"aria-hidden":"true"},"check"),m("span.sr-only#"+u,gettext("(success)"))]):(o+=".has-error",r=n.validation[n.validationKey],c=[m("span.material-icon.form-control-feedback",{"aria-hidden":"true"},"clear"),m("span.sr-only#"+u,gettext("(error)"))])),n.helpText&&(i="string"==typeof n.helpText||n.helpText instanceof String?m("p.help-block",n.helpText):n.helpText),m(o,[m("label.control-label"+(n.labelClass||""),{"for":n.labelFor||a},n.label+":"),m(n.controlClass||"",[n.control,l?c:null,r?m(".help-block.errors",r.map(function(t){return m("p",t)})):null,i])])}};t.addService("component:form-group",function(t){t.component("form-group",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n={view:function(t,n){return[n.component("alert"),n.component("navbar"),m("#router-fixture",{config:e}),n.component("footer"),n.component("modal")]}};t.addService("component:layout",function(t){t.component("forum-layout",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(){return m(".loader.sk-folding-cube",[m(".sk-cube1.sk-cube"),m(".sk-cube2.sk-cube"),m(".sk-cube4.sk-cube"),m(".sk-cube3.sk-cube")])}};t.addService("component:loader",function(t){t.component("loader",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n={view:function(t,n){return m("article.misago-markup",{config:e},m.trust(n))}};t.addService("component:markup",function(t){t.component("markup",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n={view:function(){return m('#misago-modal.modal.fade[role="dialog"]',{config:e,tabindex:"-1","aria-labelledby":"misago-modal-label"})}};t.addService("component:modal",function(t){t.component("modal",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){return m(".page-header",m(".container",[m("h1",e.title)]))}};t.addService("component:header",function(t){t.component("header",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n=["progress-bar-danger","progress-bar-warning","progress-bar-warning","progress-bar-primary","progress-bar-success"],o=[gettext("Entered password is very weak."),gettext("Entered password is weak."),gettext("Entered password is average."),gettext("Entered password is strong."),gettext("Entered password is very strong.")],r={view:function(t,r,i){var s=i.zxcvbn.scorePassword(r.password,r.inputs),a={config:e,"class":n[s],style:"width: "+(20+20*s)+"%",role:"progressbar","aria-valuenow":s,"aria-valuemin":"0","aria-valuemax":"4"};return m(".help-block.password-strength",{key:"password-strength"},[m(".progress",m(".progress-bar",a,m("span.sr-only",o[s]))),m("p.text-small",o[s])])}};t.addService("component:password-strength",function(t){t.component("password-strength",r)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(e){var n=this;this.showActivation=!1,this.username=m.prop(""),this.email=m.prop(""),this.password=m.prop(""),this.captcha=e.captcha.value,this.errors=null,this.validation={username:[t.validators.usernameContent(),t.validators.usernameMinLength(e.settings),t.validators.usernameMaxLength(e.settings)],email:[t.validators.email()],password:[t.validators.passwordMinLength(e.settings)],captcha:e.captcha.validator()},this.clean=function(){return null===this.errors&&e.validate(this),e.captcha.clean(this),this.hasErrors()?(e.alert.error(gettext("Form contains errors.")),!1):!0},this.submit=function(){e.api.model("user").post({username:this.username(),email:this.email(),password:this.password(),captcha:this.captcha()}).then(this.success,this.error)},this.success=function(t){e.modal("register-complete",t)},this.error=function(t){400===t.status?(e.alert.error(gettext("Form contains errors.")),$.extend(n.errors,t)):e.api.alert(t)}};t.addService("form:register",function(t){t.form("register",e)},{after:"forms"})}(Misago.prototype),function(t){"use strict";var e=function(t){var e=this;this.showActivation=!1,this.username=m.prop(""),this.password=m.prop(""),this.validation={username:[],password:[]},this.clean=function(){return t.validate(this)?!0:(t.alert.error(gettext("Fill out both fields.")),!1)},this.submit=function(){t.api.endpoint("auth").post({username:e.username(),password:e.password()}).then(function(){e.success()},function(t){e.error(t)})},this.success=function(){t.modal();var e=$("#hidden-login-form");t.ajax.refreshCsrfToken(),e.find('input[type="hidden"]').val(t.ajax.csrfToken),e.find('input[name="redirect_to"]').val(m.route()),e.find('input[name="username"]').val(this.username()),e.find('input[name="password"]').val(this.password()),e.submit()},this.error=function(n){400===n.status?"inactive_admin"===n.code?t.alert.info(n.detail):"inactive_user"===n.code?(t.alert.info(n.detail),e.showActivation=!0):"banned"===n.code?(t.modal(),t.router.error403({message:"",ban:n.detail})):t.alert.error(n.detail):t.api.alert(n)}};t.addService("form:sign-in",function(t){t.form("sign-in",e)},{after:"forms"})}(Misago.prototype),function(t,e){"use strict";var n=new e;n.url("/","index"),n.url("/terms-of-service/","terms_of_service"),n.url("/privacy-policy/","privacy_policy"),n.url("/:rest...","error:404","not_found"),t.urls=n}(Misago.prototype,Misago.prototype.UrlConf);
+!function(){"use strict";window.Misago=function(){var t=Object.getPrototypeOf(this),e=this;this._initServices=function(n){var o=new t.OrderedList(n).order(!1);o.forEach(function(t){var n=null;n=void 0!==t.item.factory?t.item.factory:t.item;var o=n(e);o&&(e[t.key]=o)})},this._destroyServices=function(n){var o=new t.OrderedList(n).order();o.reverse(),o.forEach(function(t){void 0!==t.destroy&&t.destroy(e)})},this.context={SETTINGS:{}},this.setup=!1,this.init=function(e,n){this.setup={fixture:t.get(e,"fixture",null),test:t.get(e,"test",!1),api:t.get(e,"api","/api/")},n&&(this.context=n),this._initServices(t._services)},this.destroy=function(){this._destroyServices(t._services)}};var t=window.Misago.prototype;t._services=[],t.addService=function(e,n,o){t._services.push({key:e,item:n,after:t.get(o,"after"),before:t.get(o,"before")})},t.PermissionDenied=function(t){this.detail=t,this.status=403,this.toString=function(){return this.detail||"Permission denied"}}}(),function(t){"use strict";t.has=function(t,e){return t?t.hasOwnProperty(e):!1},t.get=function(e,n,o){return t.has(e,n)?e[n]:void 0!==o?o:void 0},t.pop=function(e,n,o){var r=t.get(e,n,o);return t.has(e,n)&&(e[n]=null),r}}(Misago.prototype),function(t){"use strict";function e(t,e,n){n.retain=!0}t.input=function(t){var n={disabled:t.disabled||!1,config:t.config||e};t.placeholder&&(n.placeholder=t.placeholder),t.autocomplete===!1&&(n.autocomplete="off");var o="input";return t.id&&(o+="#"+t.id,n.key="field-"+t.id),o+=".form-control"+(t["class"]||""),o+='[type="'+(t.type||"text")+'"]',t.value&&(n.value=t.value(),n.oninput=m.withAttr("value",t.value)),m(o,n)}}(Misago.prototype),function(t){"use strict";var e=function(){};t.stateHooks=function(t,n,o){if(t._hasLifecycleHooks)return t;t._hasLifecycleHooks=!0,t.isActive=!0;var r=o.bind(t),i=t.controller||e;if(t.controller=function(){try{t.isActive=!0;var n=i.apply(t,arguments)||{},o=n.onunload||e;return n.onunload=function(){o.apply(t,arguments),t.isActive=!1},n}catch(s){r(s)}},t.vm&&t.vm.init){if(!t.loading){var s=n.bind(t);t.loading=s}var a=t.view;t.view=function(){return t.vm.isReady?a.apply(t,arguments):t.loading.apply(t,arguments)};var u=t.vm.init;t.vm.init=function(){var e=arguments,n=u.apply(t.vm,e);n&&n.then(function(){if(t.isActive&&t.vm.ondata){for(var n=[],o=0;o<arguments.length;o++)n.push(arguments[o]);for(var r=0;r<e.length;r++)n.push(e[r]);t.vm.ondata.apply(t.vm,n)}},function(e){t.isActive&&r(e)})}}return t}}(Misago.prototype),function(t){"use strict";t.OrderedList=function(e){this.isOrdered=!1,this._items=e||[],this.add=function(e,n,o){this._items.push({key:e,item:n,after:t.get(o,"after"),before:t.get(o,"before")})},this.get=function(t,e){for(var n=0;n<this._items.length;n++)if(this._items[n].key===t)return this._items[n].item;return e},this.has=function(t){return void 0!==this.get(t)},this.values=function(){for(var t=[],e=0;e<this._items.length;e++)t.push(this._items[e].item);return t},this.order=function(t){return this.isOrdered||(this._items=this._order(this._items),this.isOrdered=!0),t||"undefined"==typeof t?this.values():this._items},this._order=function(t){function e(t){var e=-1;-1===r.indexOf(t.key)&&(t.after?(e=r.indexOf(t.after),-1!==e&&(e+=1)):t.before&&(e=r.indexOf(t.before)),-1!==e&&(o.splice(e,0,t),r.splice(e,0,t.key)))}var n=[];t.forEach(function(t){n.push(t.key)});var o=[],r=[];t.forEach(function(t){t.after||t.before||(o.push(t),r.push(t.key))}),t.forEach(function(t){"_end"===t.before&&(o.push(t),r.push(t.key))});for(var i=200;i>0&&n.length!==r.length;)i-=1,t.forEach(e);return o}}}(Misago.prototype),function(t){t.serializeDatetime=function(t){return t?t.format():null},t.deserializeDatetime=function(t){return t?moment(t):null}}(Misago.prototype),function(t){"use strict";t.startsWith=function(t,e){return 0===t.indexOf(e)},t.endsWith=function(t,e){return-1!==t.indexOf(e,t.length-e.length)}}(Misago.prototype),function(t){"use strict";t.UrlConf=function(){var e=this;this._patterns=[],this.patterns=function(){return this._patterns};var n=function(t,e){return(t+e).replace("//","/")},o=function(t,o){for(var r=0;r<o.length;r++)e.url(n(t,o[r].pattern),o[r].component,o[r].name)};this.url=function(e,n,r){""===e&&(e="/"),n instanceof t.UrlConf?o(e,n.patterns()):this._patterns.push({pattern:e,component:n.replace(/_/g,"-"),name:r||n})}}}(Misago.prototype),function(t){"use strict";t.loadingPage=function(t){return m(".page.page-loading",t.component("loader"))}}(Misago.prototype),function(t){"use strict";var e=function(e){if(-1!==document.cookie.indexOf(e)){var n=new RegExp(e+"=([^;]*)"),o=t.get(document.cookie.match(n),0);return o.split("=")[1]}return null},n=function(n){this.refreshCsrfToken=function(){this.csrfToken=e(n.context.CSRF_COOKIE_NAME)},this.refreshCsrfToken();var o={};this.ajax=function(e,n,r,i){var s=m.deferred(),a={url:n,method:e,headers:{"X-CSRFToken":this.csrfToken},data:r||{},dataType:"json",success:function(r){"GET"===e&&t.pop(o,n),s.resolve(r)},error:function(r){"GET"===e&&t.pop(o,n);var i=r.responseJSON||{};i.status=r.status,i.statusText=r.statusText,s.reject(i)}};return i?void 0:($.ajax(a),s.promise)},this.get=function(e){var r=t.pop(n.context,e);if(r){var i=m.deferred();return i.resolve(r),i.promise}return void 0!==o[e]?o[e]:(o[e]=this.ajax("GET",e),o[e])},this.post=function(t,e){return this.ajax("POST",t,e)},this.patch=function(t,e){return this.ajax("PATCH",t,e)},this.put=function(t,e){return this.ajax("PUT",t,e)},this["delete"]=function(t){return this.ajax("DELETE",t)}};t.addService("ajax",function(t){return new n(t)})}(Misago.prototype),function(t){"use strict";var e=5e3,n=70,o=9e3,r=300,i=function(t){var i=this;this.type="info",this.message=null,this.isVisible=!1;var s=function(r,s){i.type=r,i.message=s,i.isVisible=!0;var a=e;a+=s.length*n,a>o&&(a=o),t.runloop.runOnce(function(){m.startComputation(),i.isVisible=!1,m.endComputation()},"flash-message-hide",a)},a=function(e,n){t.runloop.stop("flash-message-hide"),t.runloop.stop("flash-message-show"),i.isVisible?(i.isVisible=!1,t.runloop.runOnce(function(){m.startComputation(),s(e,n),m.endComputation()},"flash-message-show",r)):s(e,n)};this.info=function(t){a("info",t)},this.success=function(t){a("success",t)},this.warning=function(t){a("warning",t)},this.error=function(t){a("error",t)}};t.addService("alert",{factory:function(t){return new i(t)}})}(Misago.prototype),function(t){"use strict";var e=function(t){if("object"==typeof t){var e=[];for(var n in t)if(t.hasOwnProperty(n)){var o=encodeURIComponent(n),r=encodeURIComponent(t[n]);e.push(o+"="+r)}return"?"+e.join("&")}return t+"/"},n=function(t,o){this.url=o.url||t.setup.api,this.url+=o.path?o.path+"/":o.related?o.related+"/":o.model+"s/",o.filters&&(this.url+=e(o.filters)),o.model&&(this.related=function(e,r){return new n(t,{url:this.url,relation:o.model,related:e,filters:r})}),this.endpoint=function(e,o){return new n(t,{url:this.url,path:e,filters:o})},this.get=function(){var e=null;return o.related?e=o.relation+":"+o.related:o.model&&(e=o.model),t.ajax.get(this.url).then(function(n){return e?n.results?(n.results.map(function(n){return t.models["new"](e,n)}),n):t.models["new"](e,n):n})},this.post=function(e){return t.ajax.post(this.url,e)},this.patch=function(e){return t.ajax.patch(this.url,e)},this.put=function(e){return t.ajax.put(this.url,e)},this["delete"]=function(){return t.ajax["delete"](this.url)},this.then=function(t,e){return this.get().then(t,e)}},o=function(t){this.model=function(e,o){return new n(t,{model:e,filters:o})},this.endpoint=function(e,o){return new n(t,{path:e,filters:o})},this.alert=function(e){var n=gettext("Unknown error has occured.");0===e.status&&(n=gettext("Lost connection with application.")),403===e.status&&(n=e.detail,"Permission denied"===n&&(n=gettext("You don't have permission to perform this action."))),404===e.status&&(n=gettext("Action link is invalid.")),t.alert.error(n)}};t.addService("api",function(t){return new o(t)})}(Misago.prototype),function(t){"use strict";var e=function(e){e.user=e.models.deserialize("user",e.context.user),this.denyAuthenticated=function(n){if(e.user.isAuthenticated)throw new t.PermissionDenied(n||gettext("This page is not available to signed in users."))},this.denyAnonymous=function(n){if(e.user.isAnonymous)throw new t.PermissionDenied(n||gettext("This page is not available to guests."))}};t.addService("auth",function(t){return new e(t)},{after:"model:user"})}(Misago.prototype),function(t){"use strict";var e=function(){var t=m.deferred();t.resolve(),this.load=function(){return t.promise},this.value=function(){return null}},n=function(t){var e=this;this.loading=!1,this.question=null,this.value=m.prop("");var n=m.deferred();this.load=function(){return this.value(""),this.question||this.loading||(this.loading=!0,t.api.endpoint("captcha-question").get().then(function(t){e.question=t,n.resolve()},function(){t.api.alert(gettext("Failed to load CAPTCHA.")),n.reject()}).then(function(){e.loading=!0})),n.promise},this.component=function(e){return t.component("form-group",{label:this.question.question,labelClass:e.labelClass||null,controlClass:e.controlClass||null,control:t.input({value:t.validate(e.form,"captcha"),id:"id_captcha",disabled:e.form.isBusy}),validation:e.form.errors,validationKey:"captcha",helpText:this.question.help_text})},this.validator=function(){return[]}},o=function(t){this.included=!1,this.question=null;var e=m.deferred(),n=function(e){"undefined"!=typeof grecaptcha?e.resolve():t.runloop.runOnce(function(){n(e)},"loading-grecaptcha",150)};this.load=function(){return"undefined"!=typeof grecaptcha&&grecaptcha.reset(),this.included||(t.include("https://www.google.com/recaptcha/api.js",!0),this.included=!0),n(e),e.promise};var o=function(e,n,o){o.retain=!0,n||grecaptcha.render("recaptcha",{sitekey:t.settings.recaptcha_site_key})};this.component=function(e){var n=m("#recaptcha",{config:o});return t.component("form-group",{label:gettext("Security test"),labelClass:e.labelClass||null,controlClass:e.controlClass||null,control:n,validation:e.form.errors,validationKey:"captcha"})},this.value=function(){return"undefined"!=typeof grecaptcha?grecaptcha.getResponse():""},this.clean=function(t){t.errors.captcha=this.value()?!0:[gettext("This field is required.")]},this.validator=function(){return[]}},r=function(t){var r={no:e,qa:n,re:o},i=new r[t.settings.captcha_type](t);this.value=i.value,this.load=function(){return i.load()},this.component=function(t){return i.component?i.component(t):null},this.validator=function(){return i.validator?i.validator():null},this.clean=function(t){i.clean?i.clean(t):t.errors.captcha=!0}};t.addService("captcha",function(t){return new r(t)},{after:"include"})}(Misago.prototype),function(t){"use strict";var e=function(t,e){if(this._components[t]){if(arguments.length>1){for(var n=[this._components[t]],o=1;o<arguments.length;o+=1)n.push(arguments[o]);return n.push(this),m.component.apply(void 0,n)}return m.component(this._components[t],this)}if(!e)throw'"'+t+"\" component is not registered and can't be created";this._components[t]=e};t.addService("components",function(t){t._components={},t.component=e})}(Misago.prototype),function(t){"use strict";t.addService("conf",function(e){e.settings=t.get(e.context,"SETTINGS",{})})}(Misago.prototype),function(t){"use strict";var e=function(t){var e=t.submit,n=t.success,o=t.error;return t.isBusy=!1,t.errors=null,t.submit=function(){return t.isBusy?!1:(t.clean?t.clean()&&(t.isBusy=!0,e.apply(t)):t.isBusy=!0,!1)},t.success=function(){m.startComputation(),n.apply(t,arguments),t.isBusy=!1,m.endComputation()},t.error=function(){m.startComputation(),o.apply(t,arguments),t.isBusy=!1,m.endComputation()},t.hasErrors=function(){if(null===t.errors)return!1;for(var e in t.validation)if(t.validation.hasOwnProperty(e)&&t.errors[e]!==!0)return!0;return!1},t},n=function(t,n){return this._forms[t]?e(n?new this._forms[t](n,this):new this._forms[t](this)):void(this._forms[t]=n)};t.addService("forms",function(t){t._forms={},t.form=n})}(Misago.prototype),function(t){"use strict";t.addService("forum-layout",{factory:function(t){t.setup.fixture&&m.mount(document.getElementById(t.setup.fixture),t.component("forum-layout"))},destroy:function(t){t.setup.fixture&&m.mount(document.getElementById(t.setup.fixture),null)}},{before:"start-routing"})}(Misago.prototype),function(t){"use strict";var e=function(t,e){e||(t=this.context.STATIC_URL+t),$.ajax({url:t,cache:!0,dataType:"script"})};t.addService("include",function(t){t.include=e},{after:"conf"})}(Misago.prototype),function(t){"use strict";var e=function(){var t=this,e=document.getElementById("misago-modal"),n="click.misago-modal";$(e).on(n,"a",function(){t.hide()}),this.destroy=function(){$(e).off(),$("body").removeClass("modal-open"),$(".modal-backdrop").remove()};var o=$(e).modal({show:!1});this.open=!1,o.on("hidden.bs.modal",function(){t.open&&(m.mount(e,null),this.open=!1)}),this.show=function(t){this.open=!0,m.mount(e,t),o.modal("show")},this.hide=function(){o.modal("hide")}};t.addService("_modal",{factory:function(){return new e},destroy:function(t){t._modal.destroy()}},{after:"start-routing"})}(Misago.prototype),function(t){"use strict";var e=function(t,e){if(this._modals[t]){for(var n=[this._modals[t]],o=1;o<arguments.length;o+=1)n.push(arguments[o]);n.push(this),this._modal.show(m.component.apply(m,n))}else t?this._modals[t]=e:this._modal.hide()};t.addService("modals",function(t){t._modals={},t.modal=e},{after:"_modal"})}(Misago.prototype),function(t){"use strict";var e=function(){this.classes={},this.deserializers={},this.relations={},this.add=function(t,e){if(e["class"]&&(this.classes[t]=e["class"]),e.deserialize&&(this.deserializers[t]=e.deserialize),e.relations)for(var n in e.relations)e.relations.hasOwnProperty(n)&&(this.relations[t+":"+n]=e.relations[n])},this["new"]=function(t,e){return this.classes[t]?new this.classes[t](e):e},this.deserialize=function(t,e){return this.relations[t]&&(t=this.relations[t]),this.deserializers[t]?this["new"](t,this.deserializers[t](e,this)):this["new"](t,e)}};t.addService("models",function(){return new e})}(Misago.prototype),function(t){"use strict";t.addService("set-momentjs-locale",function(){moment.locale($("html").attr("lang"))})}(Misago.prototype),function(t){"use strict";var e=function(e){var n=this;this.baseUrl=$("base").attr("href");var o=t.get(e.context,"STATIC_URL","/"),r=t.get(e.context,"MEDIA_URL","/");this.urls={},this.reverses={};var i=function(t){t.patterns().forEach(function(t){var o=n.baseUrl+t.pattern;o=o.replace("//","/"),n.urls[o]=e.route(t.component),n.reverses[t.name]=o})};this.startRouting=function(t,n){i(t),this.fixture=n,m.route.mode=e.setup.test?"search":"pathname",m.route(n,"/",this.urls)},this.url=function(t){return this.reverses[t]},this.route=function(t){m.route(t)},this.delegateElement=null,this.cleanUrl=function(t){if(t){var e="/"===t.substr(0,1)&&"//"!==t.substr(0,2);if(!e){var n=window.location;if("//"!==t.substr(0,2)){var i=t.substr(0,n.protocol.length+2);if(i!==n.protocol+"//")return;t=t.substr(n.protocol.length+2)}else t=t.substr(2);if(t.substr(0,n.host.length)!==n.host)return;t=t.substr(n.host.length)}if(t.substr(0,this.baseUrl.length)===this.baseUrl&&t.substr(0,o.length)!==o&&t.substr(0,r.length)!==r){var s="/user-avatar/";if(t.substr(0,s.length)!==s)return t}}};var s="click.misago-router";this.delegateClicks=function(t){this.delegateElement=t,$(this.delegateElement).on(s,"a",function(t){var e=n.cleanUrl(t.target.href);e&&(e!=m.route()&&n.route(e),t.preventDefault())})},this.destroy=function(){$(this.delegateElement).off(s)};var a=function(t){return function(e){return t+e}};this.staticUrl=a(o),this.mediaUrl=a(r),this.error403=function(t){var n=null;n=t.ban?e.route("error:banned",t.detail,e.models.deserialize("ban",t.ban)):e.route("error:403",t.detail),m.mount(this.fixture,n)},this.error404=function(){m.mount(this.fixture,e.route("error:404"))},this.error500=function(){m.mount(this.fixture,e.route("error:500"))},this.error0=function(){m.mount(this.fixture,e.route("error:0"))},this.errorPage=function(t){0===t.status&&this.error0(),500===t.status&&this.error500(),404===t.status&&this.error404(),403===t.status&&this.error403(t)}};t.addService("router",function(t){return new e(t)}),t.addService("start-routing",function(e){e.router.startRouting(t.urls,document.getElementById("router-fixture")),e.router.delegateClicks(document.getElementById(e.setup.fixture))},{before:"_end"})}(Misago.prototype),function(t){"use strict";var e=function(e){if(e._hasRouteBoilerplate)return e;e._hasRouteBoilerplate=!0;var n=function(){var t=this.container;return m(".page.page-loading",t.component("loader"))},o=function(t){if(!this.isActive||!t.status)throw t;this.vm&&this.vm.onerror?this.vm.onerror(t,this.container):this.container.router.errorPage(t)};return t.stateHooks(e,n,o)};t.addService("routes",function(t){t._routes={},t.route=function(n,o){if(this._routes[n]){if(arguments.length>1){for(var r=[this._routes[n]],i=1;i<arguments.length;i+=1)r.push(arguments[i]);return r.push(this),m.component.apply(void 0,r)}return m.component(this._routes[n],this)}if(!o)throw'"'+n+"\" route is not registered and can't be created";o.container=t,this._routes[n]=e(o)}})}(Misago.prototype),function(t){"use strict";var e=function(t){var e=this;this._intervals={};var n=function(t){e._intervals[t]&&(window.clearTimeout(e._intervals[t]),e._intervals[t]=null)};this.run=function(o,r,i){this._intervals[r]=window.setTimeout(function(){n(r);var s=o(t);s!==!1&&e.run(o,r,i)},i)},this.runOnce=function(e,o,r){this._intervals[o]=window.setTimeout(function(){n(o),e(t)},r)},this.stop=function(t){for(var e in this._intervals)t&&t!==e||n(e)}};t.addService("runloop",{factory:function(t){return new e(t)},destroy:function(t){t.runloop.stop()}})}(Misago.prototype),function(t){"use strict";t.addService("start-tick",function(t){var e=m.prop();t.runloop.run(function(){m.startComputation(),e(e()+1),m.endComputation()},"tick",6e4)})}(Misago.prototype),function(t){"use strict";var e=function(t){this.set=function(e){e?this._set_complex(e):document.title=t},this._set_complex=function(e){"string"==typeof e&&(e={title:e});var n=e.title;if("undefined"!=typeof e.page&&e.page>1){var o=interpolate(gettext("page %(page)s"),{page:e.page},!0);n+=" ("+o+")"}"undefined"!=typeof e.parent&&(n+=" | "+e.parent),document.title=n+" | "+t}};t.addService("page-title",function(t){t.title=new e(t.settings.forum_name)})}(Misago.prototype),function(t){"use strict";var e=/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i,n=new RegExp("^[0-9a-z]+$","i");t.validators={required:function(){return function(t){return 0===$.trim(t).length?gettext("This field is required."):void 0}},email:function(t){return function(n){return e.test(n)?void 0:t||gettext("Enter a valid email address.")}},minLength:function(t,e){return function(n){var o="",r=$.trim(n).length;return t>r?(o=e?e(t,r):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).",t),interpolate(o,{limit_value:t,show_value:r},!0)):void 0}},maxLength:function(t,e){return function(n){var o="",r=$.trim(n).length;return r>t?(o=e?e(t,r):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).",t),interpolate(o,{limit_value:t,show_value:r},!0)):void 0}},usernameMinLength:function(t){var e=function(t){return ngettext("Username must be at least %(limit_value)s character long.","Username must be at least %(limit_value)s characters long.",t)};return this.minLength(t.username_length_min,e)},usernameMaxLength:function(t){var e=function(t){return ngettext("Username cannot be longer than %(limit_value)s character.","Username cannot be longer than %(limit_value)s characters.",t)};return this.maxLength(t.username_length_max,e)},usernameContent:function(){return function(t){return n.test($.trim(t))?void 0:gettext("Username can only contain latin alphabet letters and digits.")}},passwordMinLength:function(t){var e=function(t){return ngettext("Valid password must be at least %(limit_value)s character long.","Valid password must be at least %(limit_value)s characters long.",t)};return this.minLength(t.password_length_min,e)}};var o=function(e,n){var o=t.validators.required()(e),r=[];if(o)return[o];for(var i in n)o=n[i](e),o&&r.push(o);return r.length?r:!0},r=function(t){var e={},n=null,r=!0;for(var i in t.validation)t.validation.hasOwnProperty(i)&&(n=t[i](),e[i]=o(t[i](),t.validation[i]),e[i]!==!0&&(r=!1));return t.errors=e,r},i=function(t,e){return e?function(n){var r=null;return"undefined"!=typeof n?(r=o(n,t.validation[e]),r&&(t.errors||(t.errors={}),t.errors[e]=r),t[e](n),t[e](n)):t[e]()}:r(t)};t.addService("validate",{factory:function(){return i}})}(Misago.prototype),function(t){"use strict";var e=function(t){this.included=!1,this.scorePassword=function(t,e){return zxcvbn(t,e).score},this.include=function(){t.include("misago/js/zxcvbn.js"),this.included=!0};var e=function(n){"undefined"!=typeof zxcvbn?n.resolve():t.runloop.runOnce(function(){e(n)},"loading-zxcvbn",150)},n=m.deferred();this.load=function(){return this.included||this.include(),e(n),n.promise}};t.addService("zxcvbn",function(t){return new e(t)},{after:"include"})}(Misago.prototype),function(t){"use strict";var e=function(t){this.message={html:t.message.html,plain:t.message.plain},this.expires_on=t.expires_on},n=function(e){return e.expires_on=t.deserializeDatetime(e.expires_on),e};t.addService("model:ban",function(t){t.models.add("ban",{"class":e,deserialize:n})},{after:"models"})}(Misago.prototype),function(t){"use strict";var e=function(t){this.title=t.title,this.body=t.body,this.link=t.link};t.addService("model:legal-page",function(t){t.models.add("legal-page",{"class":e})},{after:"models"})}(Misago.prototype),function(t){"use strict";var e=function(t){this.id=t.id,this.isAuthenticated=!!this.id,this.isAnonymous=!this.isAuthenticated,this.slug=t.slug,this.username=t.username,this.acl=t.acl,this.rank=t.rank},n=function(e){return e.joined_on&&(e.joined_on=t.deserializeDatetime(e.joined_on)),e};t.addService("model:user",function(t){t.models.add("user",{"class":e,deserialize:n})},{after:"models"})}(Misago.prototype),function(t){"use strict";var e={error:null,username:null,isReady:!1,init:function(t){this.error=null,this.user=null,this.isReady=!1;var e=t.api.endpoint("auth").endpoint("activate-account");return e=e.endpoint(m.route.param("user_id")),e=e.endpoint(m.route.param("token")),e.post()},ondata:function(t,e){m.startComputation(),e.title.set(gettext("Account activated")),this.username=t.username,this.isReady=!0,m.endComputation()},onerror:function(t,e){400===t.status?(m.startComputation(),this.error=t,this.isReady=!0,m.endComputation()):e.router.errorPage(t)}},n={controller:function(t){t.auth.denyAuthenticated(gettext("You have to be signed out to activate account.")),t.title.set(gettext("Account activation")),this.vm.init(t)},vm:e,view:function(t,e){return this.vm.error?this.rejected(this.vm.error,e):this.success(this.vm.username,e)},success:function(t){var e=gettext("%(username)s, your account has been successfully activated!");return m(".page.page-message.page-message-success",m(".container",m(".message-panel",[m(".message-icon",m("span.material-icon","check")),m(".message-body",[m("p.lead",interpolate(e,{username:t},!0)),m("p",gettext("You can now sign in to finish setting up your account and to participate in or start new discussions."))])])))},rejected:function(t){return m(".page.page-message.page-message-info",m(".container",m(".message-panel",[m(".message-icon",m("span.material-icon","info_outline")),m(".message-body",[m("p.lead",gettext("Your account can't be activated at this time.")),m("p",t.detail)])])))},loading:function(t,e){return m(".page.page-loading",[e.component("loader"),m("p.lead",gettext("Activating account..."))])}};t.addService("route:activate-by-token",function(t){t.route("activate-by-token",n)},{after:"routes"})}(Misago.prototype),function(t){"use strict";var e=function(t){var e=[m("p.lead",t.message)];return t.help&&e.push(m("p.help",t.help)),m(".page.page-error.page-error-"+t.code,m(".container",m(".message-panel",[m(".message-icon",m("span.material-icon",t.icon)),m(".message-body",e)])))},n={controller:function(){this.container.title.set(gettext("You are banned"))},view:function(t,e,n){var o=[];o.push(n.message.html?m(".lead",m.trust(n.message.html)):e?m("p.lead",e):m("p.lead",gettext("You are banned.")));var r=null;return r=n.expires_on?n.expires_on.isAfter(moment())?interpolate(gettext("This ban expires %(expires_on)s."),{expires_on:n.expires_on.fromNow()},!0):gettext("This ban has expired."):gettext("This ban is permanent."),o.push(m("p",r)),m(".page.page-error.page-error-banned",m(".container",m(".message-panel",[m(".message-icon",m("span.material-icon","highlight_off")),m(".message-body",o)])))}},o={controller:function(){this.container.title.set(gettext("Page not available"))},view:function(t,n){return"Permission denied"===n&&(n=gettext("You don't have permission to access this page.")),e({code:403,icon:"remove_circle_outline",message:gettext("This page is not available."),help:n})}},r={controller:function(){this.container.title.set(gettext("Page not found"))},view:function(){return e({code:404,icon:"info_outline",message:gettext("Requested page could not be found."),help:gettext("The link you followed was incorrect or the page has been moved or deleted.")})}},i={controller:function(){this.container.title.set(gettext("Application error occured"))},view:function(){return e({code:500,icon:"error_outline",message:gettext("Requested page could not be displayed due to an error."),help:gettext("Please try again later or contact site staff if error persists.")})}},s={controller:function(){this.container.title.set(gettext("Lost connection with application"))},view:function(){return e({code:0,icon:"sync_problem",message:gettext("Could not connect to application."),help:gettext("This may be caused by problems with your connection or application server. Please check your internet connection and refresh page if problem persists.")})}};t.addService("route:error-pages",function(t){t.route("error:banned",n),t.route("error:403",o),t.route("error:404",r),t.route("error:500",i),t.route("error:0",s)},{after:"routes"})}(Misago.prototype),function(t){"use strict";var e={controller:function(t){return document.title=t.settings.forum_index_title||t.settings.forum_name,{activation:function(){t.router.url("request_activation")}}},view:function(t,e){return m(".container",[m("h1","Activation"),m("p","Test auth blocks"),m("p",m("a",{href:e.router.url("request_activation")},"Request activation."))])}};t.addService("route:index",function(t){t.route("index",e)},{after:"routes"})}(Misago.prototype),function(t){"use strict";var e=function(e,n){var o=e.replace(/_/g,"-");return{controller:function(n){t.get(n.settings,e+"_link")?window.location=t.get(n.settings,e+"_link"):this.vm.init(this,n)},vm:{page:null,isReady:!1,init:function(t,e){return this.isReady?void e.title.set(this.title):(e.title.set(),e.api.model("legal-page",o))},ondata:function(t,e,o){m.startComputation(),t.link?window.location=t.link:(t.title=t.title||n,this.page=t,this.isReady=!0,m.endComputation(),e.isActive&&o.title.set(this.page.title))}},view:function(t,e){return m(".page.page-legal.page-legal-"+o,[e.component("header",{title:this.vm.page.title}),m(".container",e.component("markup",this.vm.page.body))])}}};t.addService("route:legal-pages",function(t){t.route("terms-of-service",e("terms_of_service",gettext("Terms of service"))),t.route("privacy-policy",e("privacy_policy",gettext("Privacy policy")))},{after:"routes"})}(Misago.prototype),function(t){"use strict";var e={endpoint:"send-activation",user:null,success:function(t){this.user=t},error:function(t,e){"already_active"===t.code?(e.alert.info(t.detail),e.modal("sign-in")):"inactive_admin"===t.code?e.alert.info(t.detail):e.alert.error(t.detail)},reset:function(){this.user=null}},n={controller:function(t){return t.auth.denyAuthenticated(gettext("You have to be signed out to activate account.")),t.title.set(gettext("Activate your account")),{form:t.form("request-link",e)}},view:function(t,n){return e.user?this.completed(t.form,e,n):this.form(t.form,n)},completed:function(t,e,n){var o=gettext("%(username)s, we have sent your activation link to %(email)s.");return m(".page.page-message.page-message-success",m(".container",m(".message-panel",[m(".message-icon",m("span.material-icon","check")),m(".message-body",[m("p.lead",gettext("Activation link has been sent.")),m("p",interpolate(o,{username:e.user.username,email:e.user.email},!0)),m("p",n.component("button",{"class":".btn-default",submit:!1,label:gettext("Request another link"),onclick:t.reset.bind(t)}))])])))},form:function(t,e){return m(".page.page-request-activation",[e.component("header",{title:gettext("Request activation link")}),m(".container",m(".row",[m(".col-md-8",[m("p",gettext("Site administrator may impose requirement on newly regitered accounts to be activated before users will be able to sign in.")),m("p",gettext("Depending on time of registration, you will be able activate your account by clicking special activation link. This link will be valid only for your browser, for seven days or until your account is activated.")),m("p",gettext('To receive this link, enter your account\'s e-mail addres in form and press "Send link" button.'))]),m(".col-md-4",e.component("request-link-form",t))]))])}};t.addService("route:request-activation",function(t){t.route("request-activation",n)},{after:"routes"})}(Misago.prototype),function(t){"use strict";var e=function(t){return-1!==[!!t.forum_footnote,!!t.terms_of_service,!!t.terms_of_service_link,!!t.privacy_policy,!!t.privacy_policy_link].indexOf(!0)},n={view:function(t,n){var o=null;return e(n.settings)&&(o=n.component("footer:menu")),m("footer.forum-footer",[m(".container",m(".footer-content",[o,n.component("footer:branding")]))])}};t.addService("component:footer",function(t){t.component("footer",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(e,n,o){var r=t.get(e.settings,n+"_link");return!r&&t.get(e.settings,n)&&(r=e.router.url(n)),r?m("li",m("a",{href:r},t.get(e.settings,n+"_title",o))):null},n={isVisible:function(t){return-1!==[!!t.forum_footnote,!!t.terms_of_service,!!t.terms_of_service_link,!!t.privacy_policy,!!t.privacy_policy_link].indexOf(!0)},view:function(t,n){var o=[];return n.settings.forum_footnote&&o.push(m("li.forum-footnote",m.trust(n.settings.forum_footnote))),o.push(e(n,"terms_of_service",gettext("Terms of service"))),o.push(e(n,"privacy_policy",gettext("Privacy policy"))),m("ul.list-inline.footer-nav",o)}};t.addService("component:footer:menu",function(t){t.component("footer:menu",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(){return m("a.misago-branding[href=http://misago-project.org]",["powered by ",m("strong","misago")])}};t.addService("component:footer:branding",function(t){t.component("footer:branding",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(e,n,o){return m(".well.well-form",m("form",{onsubmit:n.submit},[m(".form-group",m(".control-input",t.input({disabled:n.isBusy,value:n.email,placeholder:gettext("Your e-mail address")}))),o.component("button",{"class":".btn-primary.btn-block",submit:!0,loading:n.isBusy,label:gettext("Send link")})]))}};t.addService("component:request-link-form",function(t){t.component("request-link-form",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){return m(".modal-header",[m('button.close[type="button"]',{"data-dismiss":"modal","aria-label":gettext("Close")},m("span",{"aria-hidden":"true"
+},m.trust("&times;"))),m("h4#misago-modal-label.modal-title",e)])}};t.addService("component:modal:header",function(t){t.component("modal:header",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n=function(){document.location.reload()},o={controller:function(t,e){"active"===t.activation&&e.runloop.runOnce(n,"refresh-after-registration",1e4)},view:function(t,n,o){var r=null;return r="active"===n.activation?this.active(n):this.inactive(n),m('.modal-dialog.modal-message.modal-register[role="document"]',{config:e},m(".modal-content",[o.component("modal:header",gettext("Registration complete")),m(".modal-body",r)]))},active:function(t){var e=gettext("%(username)s, your account has been created and you were signed in.");return[m(".message-icon",m("span.material-icon","check")),m(".message-body",[m("p.lead",interpolate(e,{username:t.username},!0)),m("p",gettext("The page will refresh automatically in 10 seconds.")),m("p",m('button[type="button"].btn.btn-default',{onclick:n},gettext("Refresh page")))])]},inactive:function(t){var e=null,n=null;return"user"===t.activation?(e=gettext("%(username)s, your account has been created but you need to activate it before you will be able to sign in."),n=gettext("We have sent an e-mail to %(email)s with link that you have to click to activate your account.")):"admin"===t.activation&&(e=gettext("%(username)s, your account has been created but board administrator will have to activate it before you will be able to sign in."),n=gettext("We will send an e-mail to %(email)s when this takes place.")),[m(".message-icon",m("span.material-icon","info_outline")),m(".message-body",[m("p.lead",interpolate(e,{username:t.username},!0)),m("p",interpolate(n,{email:t.email},!0))])]}};t.addService("modal:register-complete",function(t){t.modal("register-complete",o)},{after:"modals"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n={controller:function(t){return{form:t.form("register")}},view:function(t,n){var o=n.captcha.component({form:t.form,labelClass:".col-md-4",controlClass:".col-md-8"}),r=null,i=n.settings.terms_of_service_link;return!i&&n.settings.terms_of_service&&(i=n.router.url("terms_of_service")),i&&(r=m("a",{href:i},m.trust(interpolate(gettext("By registering you agree to site's %(terms)s."),{terms:"<strong>"+gettext("terms and conditions")+"</strong>"},!0)))),m('.modal-dialog.modal-form.modal-register[role="document"]',{config:e},m(".modal-content",[n.component("modal:header",gettext("Register")),m("form.form-horizontal",{onsubmit:t.form.submit},[m('input[type="text"]',{name:"_username",style:"display: none"}),m('input[type="password"]',{name:"_password",style:"display: none"}),m(".modal-body",[n.component("form-group",{label:gettext("Username"),labelClass:".col-md-4",controlClass:".col-md-8",control:n.input({value:n.validate(t.form,"username"),id:"id_username",disabled:t.form.isBusy}),validation:t.form.errors,validationKey:"username"}),n.component("form-group",{label:gettext("E-mail"),labelClass:".col-md-4",controlClass:".col-md-8",control:n.input({value:n.validate(t.form,"email"),id:"id_email",disabled:t.form.isBusy}),validation:t.form.errors,validationKey:"email"}),n.component("form-group",{label:gettext("Password"),labelClass:".col-md-4",controlClass:".col-md-8",control:n.input({value:n.validate(t.form,"password"),type:"password",id:"id_password",disabled:t.form.isBusy}),validation:t.form.errors,validationKey:"password",helpText:n.component("password-strength",{inputs:[t.form.username(),t.form.email()],password:t.form.password()})}),o]),m(".modal-footer",[r,n.component("button",{"class":".btn-primary",submit:!0,loading:t.form.isBusy,label:gettext("Register account")})])])]))}};t.addService("modal:register",function(t){t.modal("register",n)},{after:"modals"})}(Misago.prototype),function(t){"use strict";function e(t,e,n){n.retain=!0}var n={controller:function(t){return{form:t.form("sign-in")}},view:function(n,o){var r=null;return n.form.showActivation&&(r=m("a.btn.btn-block.btn-success",{href:o.router.url("request_activation")},gettext("Activate account"))),m('.modal-dialog.modal-sm.modal-signin[role="document"]',{config:e},m(".modal-content",[o.component("modal:header",gettext("Sign in")),m("form",{onsubmit:n.form.submit},[m(".modal-body",[m(".form-group",m(".control-input",t.input({disabled:n.form.isBusy,value:n.form.username,placeholder:gettext("Username or e-mail")}))),m(".form-group",m(".control-input",t.input({type:"password",disabled:n.form.isBusy,value:n.form.password,placeholder:gettext("Password")})))]),m(".modal-footer",[r,o.component("button",{"class":".btn-primary.btn-block",submit:!0,loading:n.form.isBusy,label:gettext("Sign in")})])])]))}};t.addService("modal:sign-in",function(t){t.modal("sign-in",n)},{after:"modals"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){var n=".navbar.navbar-default.navbar-static-top";return m("nav"+n+'[role="navigation"]',[e.component("navbar:desktop")])}};t.addService("component:navbar",function(t){t.component("navbar",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e,n){var o=[m("img",{src:n.router.staticUrl("misago/img/site-logo.png"),alt:n.settings.forum_name})];return e&&o.push(e),m("a.navbar-brand",{href:n.router.url("index")},o)}};t.addService("component:navbar:desktop:brand",function(t){t.component("navbar:desktop:brand",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={controller:function(t){return{showSignIn:function(){t.modal("sign-in")},isBusy:!1,showRegister:function(){if("closed"===t.settings.account_activation)t.alert.info(gettext("New registrations are currently disabled."));else{m.startComputation(),this.isBusy=!0,m.endComputation();var e=this;m.sync([t.zxcvbn.load(),t.captcha.load()]).then(function(){t.modal("register")},function(){t.alert.error(gettext("Registation is not available now due to an error."))}).then(function(){m.startComputation(),e.isBusy=!1,m.endComputation()})}}}},view:function(t,e){return m("div.nav.nav-guest",[e.component("button",{"class":".navbar-btn.btn-default",onclick:t.showSignIn,disabled:t.isBusy,label:gettext("Sign in")}),e.component("button",{"class":".navbar-btn.btn-primary",onclick:t.showRegister.bind(t),loading:t.isBusy,label:gettext("Register")})])}};t.addService("component:navbar:desktop:guest-menu",function(t){t.component("navbar:desktop:guest-menu",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){var n=[];return e.settings.forum_branding_display&&n.push(e.component("navbar:desktop:brand",e.settings.forum_branding_text)),n.push(m("ul.nav.navbar-nav",[m("li",m("a",{config:m.route,href:e.router.url("index")},"Index"))])),n.push(e.user.isAuthenticated?e.component("navbar:desktop:user-menu"):e.component("navbar:desktop:guest-menu")),m(".container.navbar-full.hidden-xs.hidden-sm",n)}};t.addService("component:navbar:desktop",function(t){t.component("navbar:desktop",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={controller:function(){return{logout:function(){$("#hidden-logout-form").submit()}}},view:function(t,e){return m("div.nav.nav-user",[m("p.navbar-text",e.user.username),m("button.navbar-btn.btn.btn-default.navbar-right",{onclick:t.logout.bind(t)},gettext("Logout"))])}};t.addService("component:navbar:desktop:user-menu",function(t){t.component("navbar:desktop:user-menu",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";function e(t,e,n){n.retain=!0}var n={classes:{info:"alert-info",success:"alert-success",warning:"alert-warning",error:"alert-danger"},view:function(t,n){return m(".alerts",{config:e,"class":n.alert.isVisible?"in":"out"},m("p.alert",{"class":this.classes[n.alert.type]},n.alert.message))}};t.addService("component:alert",function(t){t.component("alert",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){var n={disabled:e.disabled||e.loading||!1,config:e.config||null,loading:e.loading||!1,type:e.submit?"submit":"button",onclick:e.onclick||null},o='button[type="'+n.type+'"].btn';n.loading&&(o+=".btn-loading"),e.id&&(o+="#"+e.id),o+=e["class"]||"";var r=e.label;return n.loading&&(r=[r,m(".loader-compact",[m(".bounce1"),m(".bounce2"),m(".bounce3")])]),m(o,n,r)}};t.addService("component:button",function(t){t.component("button",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=["text","password","email"],n={view:function(t,n){var o=".form-group",r=null,i=null,s=n.control.attrs.type,a=n.control.attrs.id,u=a+"_feedback",c=null,l=null,d=n.validationKey&&null!==n.validation;return n.control.attrs["aria-describedby"]="",d&&n.validation[n.validationKey]&&(l=e.indexOf(s)>=0,n.control.attrs["aria-describedby"]=u,n.validation[n.validationKey]===!0?(o+=".has-success",c=[m("span.material-icon.form-control-feedback",{"aria-hidden":"true"},"check"),m("span.sr-only#"+u,gettext("(success)"))]):(o+=".has-error",r=n.validation[n.validationKey],c=[m("span.material-icon.form-control-feedback",{"aria-hidden":"true"},"clear"),m("span.sr-only#"+u,gettext("(error)"))])),n.helpText&&(i="string"==typeof n.helpText||n.helpText instanceof String?m("p.help-block",n.helpText):n.helpText),m(o,[m("label.control-label"+(n.labelClass||""),{"for":n.labelFor||a},n.label+":"),m(n.controlClass||"",[n.control,l?c:null,r?m(".help-block.errors",r.map(function(t){return m("p",t)})):null,i])])}};t.addService("component:form-group",function(t){t.component("form-group",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n={view:function(t,n){return[n.component("alert"),n.component("navbar"),m("#router-fixture",{config:e}),n.component("footer"),n.component("modal")]}};t.addService("component:layout",function(t){t.component("forum-layout",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(){return m(".loader.sk-folding-cube",[m(".sk-cube1.sk-cube"),m(".sk-cube2.sk-cube"),m(".sk-cube4.sk-cube"),m(".sk-cube3.sk-cube")])}};t.addService("component:loader",function(t){t.component("loader",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n={view:function(t,n){return m("article.misago-markup",{config:e},m.trust(n))}};t.addService("component:markup",function(t){t.component("markup",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n={view:function(){return m('#misago-modal.modal.fade[role="dialog"]',{config:e,tabindex:"-1","aria-labelledby":"misago-modal-label"})}};t.addService("component:modal",function(t){t.component("modal",n)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e={view:function(t,e){return m(".page-header",m(".container",[m("h1",e.title)]))}};t.addService("component:header",function(t){t.component("header",e)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(t,e,n){n.retain=!0},n=["progress-bar-danger","progress-bar-warning","progress-bar-warning","progress-bar-primary","progress-bar-success"],o=[gettext("Entered password is very weak."),gettext("Entered password is weak."),gettext("Entered password is average."),gettext("Entered password is strong."),gettext("Entered password is very strong.")],r={view:function(t,r,i){var s=i.zxcvbn.scorePassword(r.password,r.inputs),a={config:e,"class":n[s],style:"width: "+(20+20*s)+"%",role:"progressbar","aria-valuenow":s,"aria-valuemin":"0","aria-valuemax":"4"};return m(".help-block.password-strength",{key:"password-strength"},[m(".progress",m(".progress-bar",a,m("span.sr-only",o[s]))),m("p.text-small",o[s])])}};t.addService("component:password-strength",function(t){t.component("password-strength",r)},{after:"components"})}(Misago.prototype),function(t){"use strict";var e=function(e){var n=this;this.showActivation=!1,this.username=m.prop(""),this.email=m.prop(""),this.password=m.prop(""),this.captcha=e.captcha.value,this.errors=null,this.validation={username:[t.validators.usernameContent(),t.validators.usernameMinLength(e.settings),t.validators.usernameMaxLength(e.settings)],email:[t.validators.email()],password:[t.validators.passwordMinLength(e.settings)],captcha:e.captcha.validator()},this.clean=function(){return null===this.errors&&e.validate(this),e.captcha.clean(this),this.hasErrors()?(e.alert.error(gettext("Form contains errors.")),!1):!0},this.submit=function(){e.api.model("user").post({username:this.username(),email:this.email(),password:this.password(),captcha:this.captcha()}).then(this.success,this.error)},this.success=function(t){e.modal("register-complete",t)},this.error=function(t){400===t.status?(e.alert.error(gettext("Form contains errors.")),$.extend(n.errors,t)):e.api.alert(t)}};t.addService("form:register",function(t){t.form("register",e)},{after:"forms"})}(Misago.prototype),function(t){"use strict";var e=function(e,n){var o=this;this.email=m.prop(""),this.validation={email:[t.validators.email()]},this.clean=function(){return n.validate(this)?!0:(n.alert.error(gettext("Enter a valid email address.")),!1)},this.submit=function(){n.api.endpoint("auth").endpoint(e.endpoint).post({email:o.email()}).then(function(t){o.success(t)},function(t){o.error(t)})},this.success=function(t){e.success(t)},this.error=function(t){400===t.status?"banned"===t.code?n.router.error403({message:"",ban:t.detail}):e.error(t,n):n.api.alert(t)},this.reset=function(){this.email(""),e.reset()}};t.addService("form:request-link",function(t){t.form("request-link",e)},{after:"forms"})}(Misago.prototype),function(t){"use strict";var e=function(t){var e=this;this.showActivation=!1,this.username=m.prop(""),this.password=m.prop(""),this.validation={username:[],password:[]},this.clean=function(){return t.validate(this)?!0:(t.alert.error(gettext("Fill out both fields.")),!1)},this.submit=function(){t.api.endpoint("auth").post({username:e.username(),password:e.password()}).then(function(){e.success()},function(t){e.error(t)})},this.success=function(){t.modal();var e=$("#hidden-login-form");t.ajax.refreshCsrfToken(),e.find('input[type="hidden"]').val(t.ajax.csrfToken),e.find('input[name="redirect_to"]').val(m.route()),e.find('input[name="username"]').val(this.username()),e.find('input[name="password"]').val(this.password()),e.submit()},this.error=function(n){400===n.status?"inactive_admin"===n.code?t.alert.info(n.detail):"inactive_user"===n.code?(t.alert.info(n.detail),e.showActivation=!0):"banned"===n.code?(t.modal(),t.router.error403({message:"",ban:n.detail})):t.alert.error(n.detail):t.api.alert(n)}};t.addService("form:sign-in",function(t){t.form("sign-in",e)},{after:"forms"})}(Misago.prototype),function(t,e){"use strict";var n=new e;n.url("/","index"),n.url("/activation/","request_activation"),n.url("/activation/:user_id/:token/","activate_by_token"),n.url("/terms-of-service/","terms_of_service"),n.url("/privacy-policy/","privacy_policy"),n.url("/:rest...","error:404","not_found"),t.urls=n}(Misago.prototype,Misago.prototype.UrlConf);
 //# sourceMappingURL=/misago.js.map
 //# sourceMappingURL=/misago.js.map

+ 1 - 1
misago/static/misago/js/misago.js.map

@@ -1 +1 @@
-{"version":3,"sources":["misago.js"],"names":["window","Misago","ns","Object","getPrototypeOf","this","self","_initServices","services","orderedServices","OrderedList","order","forEach","item","factory","undefined","serviceInstance","key","_destroyServices","reverse","destroy","context","SETTINGS","setup","init","fixture","get","test","api","_services","proto","prototype","addService","name","push","after","before","has","obj","hasOwnProperty","value","pop","returnValue","persistent","el","isInit","retain","input","kwargs","options","disabled","config","placeholder","autocomplete","element","id","type","oninput","m","withAttr","noop","stateHooks","component","loadingState","errorState","_hasLifecycleHooks","isActive","_controller","controller","apply","arguments","_onunload","onunload","vm","loading","loadingHandler","bind","_view","view","isReady","errorHandler","_init","initArgs","promise","then","ondata","finalArgs","i","length","f","error","items","isOrdered","_items","add","values","values_only","_order","unordered","insertItem","insertAt","ordering","indexOf","ordered","splice","index","iterations","serializeDatetime","serialized","format","deserializeDatetime","deserialized","moment","startsWith","string","beginning","endsWith","tail","UrlConf","_patterns","patterns","prefixPattern","prefix","pattern","replace","include","url","loadingPage","_","getCsrfToken","cookie_name","document","cookie","cookieRegex","RegExp","match","split","Ajax","refreshCsrfToken","csrfToken","CSRF_COOKIE_NAME","runningGets","ajax","method","data","progress","deferred","ajax_settings","headers","X-CSRFToken","dataType","success","resolve","jqXHR","rejection","responseJSON","status","statusText","reject","$","preloaded","post","patch","put","ALERT_BASE_DISPLAY_TIME","ALERT_LENGTH_FACTOR","ALERT_MAX_DISPLAY_TIME","ALERT_HIDE_ANIMATION_LENGTH","Alert","message","isVisible","show","displayTime","runloop","runOnce","startComputation","endComputation","set","stop","info","warning","filtersUrl","filters","encodedKey","encodeURIComponent","encodedValue","join","Query","call","path","related","model","relation","endpoint","results","map","models","Api","alert","gettext","detail","Auth","user","deserialize","NoCaptcha","load","QACaptcha","question","prop","label","labelClass","controlClass","control","validate","form","isBusy","validation","errors","validationKey","helpText","help_text","validator","ReCaptcha","included","wait","grecaptcha","reset","controlConfig","render","sitekey","settings","recaptcha_site_key","getResponse","clean","captcha","Captcha","types","no","qa","re","captcha_type","_components","argumentsArray","boilerplate","_submit","submit","_success","_error","hasErrors","constructor","_forms","mount","getElementById","script","remote","STATIC_URL","cache","Modal","delegateName","on","hide","off","removeClass","remove","modal","open","_modal","_modals","Models","classes","deserializers","relations","json","locale","attr","Router","baseUrl","staticUrl","mediaUrl","urls","reverses","populatePatterns","urlconf","finalPattern","route","startRouting","mode","delegateElement","cleanUrl","isRelative","substr","location","protocol","host","avatarsUrl","delegateClicks","e","target","href","preventDefault","prefixUrl","error403","ban","error404","error500","error0","errorPage","router","_hasRouteBoilerplate","loadingView","container","_routes","RunLoop","_intervals","stopInterval","clearTimeout","run","callable","delay","setTimeout","result","loop","ticks","PageTitle","forum_name","title","_set_complex","completeTitle","page","page_label","interpolate","parent","EMAIL","USERNAME","validators","required","trim","email","minLength","limit_value","returnMessage","ngettext","show_value","maxLength","usernameMinLength","username_length_min","usernameMaxLength","username_length_max","usernameContent","passwordMinLength","password_length_min","validateField","validateForm","isValid","Zxcvbn","scorePassword","password","inputs","zxcvbn","score","Ban","html","plain","expires_on","deserializeBan","class","LegalPage","body","link","User","isAuthenticated","isAnonymous","slug","username","acl","rank","deserializeUser","joined_on","error_message","help","code","icon","errorBanned","ctrl","trust","expirationMessage","isAfter","fromNow","forum_index_title","active","activation","admin","onclick","legalPageFactory","typeName","defaultTitle","dashedTypeName","isMenuVisible","forum_footnote","terms_of_service","terms_of_service_link","privacy_policy","privacy_policy_link","footer","nav","legalLink","legalType","menu","branding","header","data-dismiss","aria-label","aria-hidden","refresh","reload","registerComplete","messageHtml","inactive","lead","register","footnote","termsUrl","terms","onsubmit","style","signin","navbar","brand","children","src","alt","showSignIn","showRegister","account_activation","sync","forum_branding_display","forum_branding_text","logout","button","textFields","formGroup","groupClass","controlType","attrs","controlId","feedbackId","feedbackIcon","showFeedbackIcon","isValidated","String","for","labelFor","forumLayout","loader","markup","content","tabindex","aria-labelledby","styles","labels","passwordStrength","role","aria-valuenow","aria-valuemin","aria-valuemax","Register","showActivation","extend","SignIn","$form","find","val"],"mappings":"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","file":"misago.js","sourcesContent":["/* global -Misago */\n/* exported Misago */\n(function () {\n  'use strict';\n\n  window.Misago = function() {\n    var ns = Object.getPrototypeOf(this);\n    var self = this;\n\n    // Services init/destroy\n    this._initServices = function(services) {\n      var orderedServices = new ns.OrderedList(services).order(false);\n      orderedServices.forEach(function (item) {\n        var factory = null;\n        if (item.item.factory !== undefined) {\n          factory = item.item.factory;\n        } else {\n          factory = item.item;\n        }\n\n        var serviceInstance = factory(self);\n        if (serviceInstance) {\n          self[item.key] = serviceInstance;\n        }\n      });\n    };\n\n    this._destroyServices = function(services) {\n      var orderedServices = new ns.OrderedList(services).order();\n      orderedServices.reverse();\n      orderedServices.forEach(function (item) {\n        if (item.destroy !== undefined) {\n          item.destroy(self);\n        }\n      });\n    };\n\n    // Context data\n    this.context = {\n      // Empty settings\n      SETTINGS: {}\n    };\n\n    // App init/destory\n    this.setup = false;\n    this.init = function(setup, context) {\n      this.setup = {\n        fixture: ns.get(setup, 'fixture', null),\n        test: ns.get(setup, 'test', false),\n        api: ns.get(setup, 'api', '/api/')\n      };\n\n      if (context) {\n        this.context = context;\n      }\n\n      this._initServices(ns._services);\n    };\n\n    this.destroy = function() {\n      this._destroyServices(ns._services);\n    };\n  };\n\n\n  // Services\n  var proto = window.Misago.prototype;\n\n  proto._services = [];\n  proto.addService = function(name, factory, order) {\n    proto._services.push({\n      key: name,\n      item: factory,\n      after: proto.get(order, 'after'),\n      before: proto.get(order, 'before')\n    });\n  };\n}());\n\n(function (Misago) {\n  'use strict';\n\n  Misago.has = function(obj, key) {\n    if (obj) {\n      return obj.hasOwnProperty(key);\n    } else {\n      return false;\n    }\n  };\n\n  Misago.get = function(obj, key, value) {\n    if (Misago.has(obj, key)) {\n      return obj[key];\n    } else if (value !== undefined) {\n      return value;\n    } else {\n      return undefined;\n    }\n  };\n\n  Misago.pop = function(obj, key, value) {\n    var returnValue = Misago.get(obj, key, value);\n    if (Misago.has(obj, key)) {\n      obj[key] = null;\n    }\n    return returnValue;\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  function persistent(el, isInit, context) {\n    context.retain = true;\n  }\n\n  Misago.input = function(kwargs) {\n    var options = {\n      disabled: kwargs.disabled || false,\n      config: kwargs.config || persistent\n    };\n\n    if (kwargs.placeholder) {\n      options.placeholder = kwargs.placeholder;\n    }\n\n    if (kwargs.autocomplete === false) {\n      options.autocomplete = 'off';\n    }\n\n    var element = 'input';\n\n    if (kwargs.id) {\n      element += '#' + kwargs.id;\n      options.key = 'field-' + kwargs.id;\n    }\n\n    element += '.form-control' + (kwargs.class || '');\n    element += '[type=\"' + (kwargs.type || 'text') + '\"]';\n\n    if (kwargs.value) {\n      options.value = kwargs.value();\n      options.oninput = m.withAttr('value', kwargs.value);\n    }\n\n    return m(element, options);\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var noop = function() {};\n\n  Misago.stateHooks = function(component, loadingState, errorState) {\n    /*\n      Boilerplate for Misago components with lifecycles\n    */\n\n    // Component boilerplated (this may happen in tests)\n    if (component._hasLifecycleHooks) {\n      return component;\n    }\n    component._hasLifecycleHooks = true;\n\n    // Component active state\n    component.isActive = true;\n\n    // Wrap controller to store lifecycle methods\n    var _controller = component.controller || noop;\n    component.controller = function() {\n      component.isActive = true;\n\n      var controller = _controller.apply(component, arguments) || {};\n\n      // wrap onunload for lifestate\n      var _onunload = controller.onunload || noop;\n      controller.onunload = function() {\n        _onunload.apply(component, arguments);\n        component.isActive = false;\n      };\n\n      return controller;\n    };\n\n    // Add state callbacks to View-Model\n    if (component.vm && component.vm.init) {\n      // setup default loading view\n      if (!component.loading) {\n        var loadingHandler = loadingState.bind(component);\n        component.loading = loadingHandler;\n      }\n\n      var _view = component.view;\n      component.view = function() {\n        if (component.vm.isReady) {\n          return _view.apply(component, arguments);\n        } else {\n          return component.loading.apply(component, arguments);\n        }\n      };\n\n      var errorHandler = errorState.bind(component);\n\n      // wrap vm.init in promise handler\n      var _init = component.vm.init;\n      component.vm.init = function() {\n        var initArgs = arguments;\n        var promise = _init.apply(component.vm, initArgs);\n\n        if (promise) {\n          promise.then(function() {\n            if (component.isActive && component.vm.ondata) {\n              var finalArgs = [];\n              for (var i = 0; i < arguments.length; i++) {\n                finalArgs.push(arguments[i]);\n              }\n              for (var f = 0; f < initArgs.length; f++) {\n                finalArgs.push(initArgs[f]);\n              }\n\n              component.vm.ondata.apply(component.vm, finalArgs);\n            }\n          }, function(error) {\n            if (component.isActive) {\n              errorHandler(error);\n            }\n          });\n        }\n      };\n    }\n\n    return component;\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.OrderedList = function(items) {\n    this.isOrdered = false;\n    this._items = items || [];\n\n    this.add = function(key, item, order) {\n      this._items.push({\n        key: key,\n        item: item,\n        after: Misago.get(order, 'after'),\n        before: Misago.get(order, 'before')\n      });\n    };\n\n    this.get = function(key, value) {\n      for (var i = 0; i < this._items.length; i++) {\n        if (this._items[i].key === key) {\n          return this._items[i].item;\n        }\n      }\n\n      return value;\n    };\n\n    this.has = function(key) {\n      return this.get(key) !== undefined;\n    };\n\n    this.values = function() {\n      var values = [];\n      for (var i = 0; i < this._items.length; i++) {\n        values.push(this._items[i].item);\n      }\n      return values;\n    };\n\n    this.order = function(values_only) {\n      if (!this.isOrdered) {\n        this._items = this._order(this._items);\n        this.isOrdered = true;\n      }\n\n      if (values_only || typeof values_only === 'undefined') {\n        return this.values();\n      } else {\n        return this._items;\n      }\n    };\n\n    this._order = function(unordered) {\n      // Index of unordered items\n      var index = [];\n      unordered.forEach(function (item) {\n        index.push(item.key);\n      });\n\n      // Ordered items\n      var ordered = [];\n      var ordering = [];\n\n      // First pass: register items that\n      // don't specify their order\n      unordered.forEach(function (item) {\n        if (!item.after && !item.before) {\n          ordered.push(item);\n          ordering.push(item.key);\n        }\n      });\n\n      // Second pass: register items that\n      // specify their before to \"_end\"\n      unordered.forEach(function (item) {\n        if (item.before === \"_end\") {\n          ordered.push(item);\n          ordering.push(item.key);\n        }\n      });\n\n      // Third pass: keep iterating items\n      // until we hit iterations limit or finish\n      // ordering list\n      function insertItem(item) {\n        var insertAt = -1;\n        if (ordering.indexOf(item.key) === -1) {\n          if (item.after) {\n            insertAt = ordering.indexOf(item.after);\n            if (insertAt !== -1) {\n              insertAt += 1;\n            }\n          } else if (item.before) {\n            insertAt = ordering.indexOf(item.before);\n          }\n\n          if (insertAt !== -1) {\n            ordered.splice(insertAt, 0, item);\n            ordering.splice(insertAt, 0, item.key);\n          }\n        }\n      }\n\n      var iterations = 200;\n      while (iterations > 0 && index.length !== ordering.length) {\n        iterations -= 1;\n        unordered.forEach(insertItem);\n      }\n\n      return ordered;\n    };\n  };\n} (Misago.prototype));\n\n(function (Misago) {\n  Misago.serializeDatetime = function(serialized) {\n    return serialized ? serialized.format() : null;\n  };\n\n  Misago.deserializeDatetime = function(deserialized) {\n    return deserialized ? moment(deserialized) : null;\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.startsWith = function(string, beginning) {\n    return string.indexOf(beginning) === 0;\n  };\n\n  Misago.endsWith = function(string, tail) {\n    return string.indexOf(tail, string.length - tail.length) !== -1;\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.UrlConf = function() {\n    var self = this;\n    this._patterns = [];\n\n    this.patterns = function() {\n      return this._patterns;\n    };\n\n    var prefixPattern = function(prefix, pattern) {\n      return (prefix + pattern).replace('//', '/');\n    };\n\n    var include = function(prefix, patterns) {\n      for (var i = 0; i < patterns.length; i ++) {\n        self.url(prefixPattern(prefix, patterns[i].pattern),\n                 patterns[i].component,\n                 patterns[i].name);\n      }\n    };\n\n    this.url = function(pattern, component, name) {\n      if (pattern === '') {\n        pattern = '/';\n      }\n\n      if (component instanceof Misago.UrlConf) {\n        include(pattern, component.patterns());\n      } else {\n        this._patterns.push({\n          pattern: pattern,\n          component: component.replace(/_/g, '-'),\n          name: name || component\n        });\n      }\n    };\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.loadingPage = function(_) {\n    return m('.page.page-loading',\n      _.component('loader')\n    );\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var getCsrfToken = function(cookie_name) {\n    if (document.cookie.indexOf(cookie_name) !== -1) {\n      var cookieRegex = new RegExp(cookie_name + '\\=([^;]*)');\n      var cookie = Misago.get(document.cookie.match(cookieRegex), 0);\n      return cookie.split('=')[1];\n    } else {\n      return null;\n    }\n  };\n\n  var Ajax = function(_) {\n    this.refreshCsrfToken = function() {\n      this.csrfToken = getCsrfToken(_.context.CSRF_COOKIE_NAME);\n    };\n    this.refreshCsrfToken();\n\n    /*\n      List of GETs underway\n      We are limiting number of GETs to API to 1 per url\n    */\n    var runningGets = {};\n\n    this.ajax = function(method, url, data, progress) {\n      var promise = m.deferred();\n\n      var ajax_settings = {\n        url: url,\n        method: method,\n        headers: {\n          'X-CSRFToken': this.csrfToken\n        },\n\n        data: data || {},\n        dataType: 'json',\n\n        success: function(data) {\n          if (method === 'GET') {\n            Misago.pop(runningGets, url);\n          }\n          promise.resolve(data);\n        },\n        error: function(jqXHR) {\n          if (method === 'GET') {\n            Misago.pop(runningGets, url);\n          }\n\n          var rejection = jqXHR.responseJSON || {};\n\n          rejection.status = jqXHR.status;\n          rejection.statusText = jqXHR.statusText;\n\n          promise.reject(rejection);\n        }\n      };\n\n      if (progress) {\n        return; // not implemented... yet!\n      }\n\n      $.ajax(ajax_settings);\n      return promise.promise;\n    };\n\n    this.get = function(url) {\n      var preloaded = Misago.pop(_.context, url);\n      if (preloaded) {\n        var deferred = m.deferred();\n        deferred.resolve(preloaded);\n        return deferred.promise;\n      } else if (runningGets[url] !== undefined) {\n        return runningGets[url];\n      } else {\n        runningGets[url] = this.ajax('GET', url);\n        return runningGets[url];\n      }\n    };\n\n    this.post = function(url, data) {\n      return this.ajax('POST', url, data);\n    };\n\n    this.patch = function(url, data) {\n      return this.ajax('PATCH', url, data);\n    };\n\n    this.put = function(url, data) {\n      return this.ajax('PUT', url, data);\n    };\n\n    this.delete = function(url) {\n      return this.ajax('DELETE', url);\n    };\n  };\n\n  Misago.addService('ajax', function(_) {\n    return new Ajax(_);\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var ALERT_BASE_DISPLAY_TIME = 5 * 1000;\n  var ALERT_LENGTH_FACTOR = 70;\n  var ALERT_MAX_DISPLAY_TIME = 9 * 1000;\n  var ALERT_HIDE_ANIMATION_LENGTH = 300;\n\n  var Alert = function(_) {\n    var self = this;\n\n    this.type = 'info';\n    this.message = null;\n    this.isVisible = false;\n\n    var show = function(type, message) {\n      self.type = type;\n      self.message = message;\n      self.isVisible = true;\n\n      var displayTime = ALERT_BASE_DISPLAY_TIME;\n      displayTime += message.length * ALERT_LENGTH_FACTOR;\n      if (displayTime > ALERT_MAX_DISPLAY_TIME) {\n        displayTime = ALERT_MAX_DISPLAY_TIME;\n      }\n\n      _.runloop.runOnce(function () {\n        m.startComputation();\n        self.isVisible = false;\n        m.endComputation();\n      }, 'flash-message-hide', displayTime);\n    };\n\n    var set = function(type, message) {\n      _.runloop.stop('flash-message-hide');\n      _.runloop.stop('flash-message-show');\n\n      if (self.isVisible) {\n        self.isVisible = false;\n        _.runloop.runOnce(function () {\n          m.startComputation();\n          show(type, message);\n          m.endComputation();\n        }, 'flash-message-show', ALERT_HIDE_ANIMATION_LENGTH);\n      } else {\n        show(type, message);\n      }\n    };\n\n    this.info = function(message) {\n      set('info', message);\n    };\n\n    this.success = function(message) {\n      set('success', message);\n    };\n\n    this.warning = function(message) {\n      set('warning', message);\n    };\n\n    this.error = function(message) {\n      set('error', message);\n    };\n  };\n\n  Misago.addService('alert', {\n    factory: function(_) {\n      return new Alert(_);\n    }\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var filtersUrl = function(filters) {\n    if (typeof filters === 'object') {\n      var values = [];\n      for (var key in filters) {\n        if (filters.hasOwnProperty(key)) {\n          var encodedKey = encodeURIComponent(key);\n          var encodedValue = encodeURIComponent(filters[key]);\n          values.push(encodedKey + '=' + encodedValue);\n        }\n      }\n      return '?' + values.join('&');\n    } else {\n      return filters + '/';\n    }\n  };\n\n  var Query = function(_, call) {\n    this.url = call.url || _.setup.api;\n\n    if (call.path) {\n      this.url += call.path + '/';\n    } else if (call.related) {\n      this.url += call.related + '/';\n    } else {\n      this.url += call.model + 's' + '/';\n    }\n\n    if (call.filters) {\n      this.url += filtersUrl(call.filters);\n    }\n\n    if (!call.url && call.filters) {\n      if (call.model) {\n        this.related = function(model, filters) {\n          return new Query(_, {\n            url: this.url,\n            relation: call.model,\n            related: model,\n            filters: filters,\n          });\n        };\n      }\n\n      this.endpoint = function(path, filters) {\n        return new Query(_, {\n          url: this.url,\n          path: path,\n          filters: filters\n        });\n      };\n    }\n\n    this.get = function() {\n      var model = null;\n      if (call.related) {\n        model = call.relation + ':' + call.related;\n      } else if (call.model) {\n        model = call.model;\n      }\n\n      return _.ajax.get(this.url).then(function(data) {\n        if (model) {\n          if (data.results) {\n            data.results.map(function(item) {\n              return _.models.new(model, item);\n            });\n            return data;\n          } else {\n            return _.models.new(model, data);\n          }\n        } else {\n          return data;\n        }\n      });\n    };\n\n    this.post = function(data) {\n      return _.ajax.post(this.url, data);\n    };\n\n    this.patch = function(data) {\n      return _.ajax.patch(this.url, data);\n    };\n\n    this.put = function(data) {\n      return _.ajax.put(this.url, data);\n    };\n\n    this.delete = function() {\n      return _.ajax.delete(this.url);\n    };\n\n    // shortcut for get()\n    this.then = function(resolve, reject) {\n      return this.get().then(resolve, reject);\n    };\n  };\n\n  var Api = function(_) {\n    this.model = function(model, filters) {\n      return new Query(_, {\n        model: model,\n        filters: filters,\n      });\n    };\n\n    this.endpoint = function(path, filters) {\n      return new Query(_, {\n        path: path,\n        filters: filters\n      });\n    };\n\n    this.alert = function(rejection) {\n      // Shorthand for API errors\n      var message = gettext(\"Unknown error has occured.\");\n\n      if (rejection.status === 0) {\n        message = gettext(\"Lost connection with application.\");\n      }\n\n      if (rejection.status === 403) {\n        message = rejection.detail;\n        if (message === \"Permission denied\") {\n          message = gettext(\n            \"You don't have permission to perform this action.\");\n        }\n      }\n\n      if (rejection.status === 404) {\n        message = gettext(\"Action link is invalid.\");\n      }\n\n      _.alert.error(message);\n    };\n  };\n\n  Misago.addService('api', function(_) {\n    return new Api(_);\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Auth = function(_) {\n    _.user = _.models.deserialize('user', _.context.user);\n  };\n\n  Misago.addService('auth', function(_) {\n    return new Auth(_);\n  },\n  {\n    after: 'model:user'\n  });\n}(Misago.prototype));\n\n/* global grecaptcha */\n(function (Misago) {\n  'use strict';\n\n  var NoCaptcha = function() {\n    var deferred = m.deferred();\n    deferred.resolve();\n\n    this.load = function() {\n      return deferred.promise;\n    };\n\n    this.value = function() {\n      return null;\n    };\n  };\n\n  var QACaptcha = function(_) {\n    var self = this;\n\n    this.loading = false;\n    this.question = null;\n    this.value = m.prop('');\n\n    var deferred = m.deferred();\n    this.load = function() {\n      this.value('');\n\n      if (!this.question && !this.loading) {\n        this.loading = true;\n\n        _.api.endpoint('captcha-question').get().then(function(question) {\n          self.question = question;\n          deferred.resolve();\n        }, function() {\n          _.api.alert(gettext('Failed to load CAPTCHA.'));\n          deferred.reject();\n        }).then(function() {\n          self.loading = true;\n        });\n      }\n\n      return deferred.promise;\n    };\n\n    this.component = function(kwargs) {\n      return _.component('form-group', {\n        label: this.question.question,\n        labelClass: kwargs.labelClass || null,\n        controlClass: kwargs.controlClass || null,\n        control: _.input({\n          value: _.validate(kwargs.form, 'captcha'),\n          id: 'id_captcha',\n          disabled: kwargs.form.isBusy\n        }),\n        validation: kwargs.form.errors,\n        validationKey: 'captcha',\n        helpText: this.question.help_text\n      });\n    };\n\n    this.validator = function() {\n      return [];\n    };\n  };\n\n  var ReCaptcha = function(_) {\n    this.included = false;\n    this.question = null;\n\n    var deferred = m.deferred();\n\n    var wait = function(promise) {\n      if (typeof grecaptcha !== \"undefined\") {\n        promise.resolve();\n      } else {\n        _.runloop.runOnce(function() {\n          wait(promise);\n        }, 'loading-grecaptcha', 150);\n      }\n    };\n\n    this.load = function() {\n      if (typeof grecaptcha !== \"undefined\") {\n        grecaptcha.reset();\n      }\n\n      if (!this.included) {\n        _.include('https://www.google.com/recaptcha/api.js', true);\n        this.included = true;\n      }\n\n      wait(deferred);\n\n      return deferred.promise;\n    };\n\n    var controlConfig = function(el, isInit, context) {\n      context.retain = true;\n\n      if (!isInit) {\n        grecaptcha.render('recaptcha', {\n          'sitekey': _.settings.recaptcha_site_key\n        });\n      }\n    };\n\n    this.component = function(kwargs) {\n      var control = m('#recaptcha', {\n        config: controlConfig\n      });\n\n      return _.component('form-group', {\n        label: gettext(\"Security test\"),\n        labelClass: kwargs.labelClass || null,\n        controlClass: kwargs.controlClass || null,\n        control: control,\n        validation: kwargs.form.errors,\n        validationKey: 'captcha'\n      });\n    };\n\n    this.value = function() {\n      if (typeof grecaptcha !== \"undefined\") {\n        return grecaptcha.getResponse();\n      } else {\n        return '';\n      }\n    };\n\n    this.clean = function(form) {\n      if (!this.value()) {\n        form.errors.captcha = [\n          gettext('This field is required.')\n        ];\n      } else {\n        form.errors.captcha = true;\n      }\n    };\n\n    this.validator = function() {\n      return [];\n    };\n  };\n\n  var Captcha = function(_) {\n    var types = {\n      'no': NoCaptcha,\n      'qa': QACaptcha,\n      're': ReCaptcha\n    };\n\n    var captcha = new types[_.settings.captcha_type](_);\n\n    this.value = captcha.value;\n\n    this.load = function() {\n      return captcha.load();\n    };\n\n    this.component = function(kwargs) {\n      if (captcha.component) {\n        return captcha.component(kwargs);\n      } else {\n        return null;\n      }\n    };\n\n    this.validator = function() {\n      if (captcha.validator) {\n        return captcha.validator();\n      } else {\n        return null;\n      }\n    };\n\n    this.clean = function(form) {\n      if (captcha.clean) {\n        captcha.clean(form);\n      } else {\n        form.errors.captcha = true;\n      }\n    };\n  };\n\n  Misago.addService('captcha', function(_) {\n    return new Captcha(_);\n  },\n  {\n    after: 'include'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var component = function(name, component) {\n    if (this._components[name]) {\n      if (arguments.length > 1) {\n        var argumentsArray = [this._components[name]];\n        for (var i = 1; i < arguments.length; i += 1) {\n          argumentsArray.push(arguments[i]);\n        }\n        argumentsArray.push(this);\n        return m.component.apply(undefined, argumentsArray);\n      } else {\n        return m.component(this._components[name], this);\n      }\n    } else {\n      this._components[name] = component;\n    }\n  };\n\n  Misago.addService('components', function(_) {\n    _._components = {};\n    _.component = component;\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.addService('conf', function(_) {\n    _.settings = Misago.get(_.context, 'SETTINGS', {});\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var boilerplate = function(form) {\n    var _submit = form.submit;\n    var _success = form.success;\n    var _error = form.error;\n\n    form.isBusy = false;\n\n    form.errors = null;\n\n    form.submit = function() {\n      if (form.isBusy) {\n        return false;\n      }\n\n      if (form.clean) {\n        if (form.clean()) {\n          form.isBusy = true;\n          _submit.apply(form);\n        }\n      } else {\n        form.isBusy = true;\n      }\n      return false;\n    };\n\n    form.success = function() {\n      m.startComputation();\n\n      _success.apply(form, arguments);\n      form.isBusy = false;\n\n      m.endComputation();\n    };\n\n    form.error = function() {\n      m.startComputation();\n\n      _error.apply(form, arguments);\n      form.isBusy = false;\n\n      m.endComputation();\n    };\n\n    form.hasErrors = function() {\n      if (form.errors === null) {\n        return false;\n      }\n\n      for (var key in form.validation) {\n        if (form.validation.hasOwnProperty(key)) {\n          if (form.errors[key] !== true) {\n            return true;\n          }\n        }\n      }\n\n      return false;\n    };\n\n    return form;\n  };\n\n  var form = function(name, constructor) {\n    if (this._forms[name]) {\n      if (constructor) {\n        return boilerplate(new this._forms[name](constructor, this));\n      } else {\n        return boilerplate(new this._forms[name](this));\n      }\n    } else {\n      this._forms[name] = constructor;\n    }\n  };\n\n  Misago.addService('forms', function(_) {\n    _._forms = {};\n    _.form = form;\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.addService('forum-layout', {\n    factory: function(_) {\n      if (_.setup.fixture) {\n        m.mount(document.getElementById(_.setup.fixture),\n                _.component('forum-layout'));\n      }\n    },\n\n    destroy: function(_) {\n      if (_.setup.fixture) {\n        m.mount(document.getElementById(_.setup.fixture), null);\n      }\n    }\n  },\n  {\n    before: 'start-routing'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var include = function(script, remote) {\n    if (!remote) {\n      script = this.context.STATIC_URL + script;\n    }\n\n    $.ajax({\n      url: script,\n      cache: true,\n      dataType: 'script'\n    });\n  };\n\n  Misago.addService('include', function(_) {\n    _.include = include;\n  },\n  {\n    after: 'conf'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Modal = function() {\n    var self = this;\n\n    var element = document.getElementById('misago-modal');\n\n    // href clicks within modal should close it\n    var delegateName = 'click.misago-modal';\n    $(element).on(delegateName, 'a', function() {\n      self.hide();\n    });\n\n    this.destroy = function() {\n      $(element).off();\n      $('body').removeClass('modal-open');\n      $('.modal-backdrop').remove();\n    };\n\n    // Open/close modal\n    var modal = $(element).modal({show: false});\n    this.open = false;\n\n    modal.on('hidden.bs.modal', function () {\n      if (self.open) {\n        m.mount(element, null);\n        this.open = false;\n      }\n    });\n\n    this.show = function(component) {\n      this.open = true;\n      m.mount(element, component);\n      modal.modal('show');\n    };\n\n    this.hide = function() {\n      modal.modal('hide');\n    };\n  };\n\n  Misago.addService('_modal', {\n    factory: function() {\n      return new Modal();\n    },\n    destroy: function(_) {\n      _._modal.destroy();\n    }\n  },\n  {\n    after: 'start-routing'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var modal = function(name, component) {\n    if (this._modals[name]) {\n      var argumentsArray = [this._modals[name]];\n      for (var i = 1; i < arguments.length; i += 1) {\n        argumentsArray.push(arguments[i]);\n      }\n      argumentsArray.push(this);\n      this._modal.show(m.component.apply(m, argumentsArray));\n    } else if (name) {\n      this._modals[name] = component;\n    } else {\n      this._modal.hide();\n    }\n  };\n\n  Misago.addService('modals', function(_) {\n    _._modals = {};\n    _.modal = modal;\n  },\n  {\n    after: '_modal'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Models = function() {\n    this.classes = {};\n    this.deserializers = {};\n    this.relations = {};\n\n    this.add = function(name, kwargs) {\n      if (kwargs.class) {\n        this.classes[name] = kwargs.class;\n      }\n\n      if (kwargs.deserialize) {\n        this.deserializers[name] = kwargs.deserialize;\n      }\n\n      if (kwargs.relations) {\n        for (var key in kwargs.relations) {\n          if (kwargs.relations.hasOwnProperty(key)) {\n            this.relations[name + ':' + key] = kwargs.relations[key];\n          }\n        }\n      }\n    };\n\n    this.new = function(name, data) {\n      if (this.classes[name]) {\n        return new this.classes[name](data);\n      } else {\n        return data;\n      }\n    };\n\n    this.deserialize = function(name, json) {\n      if (this.relations[name]) {\n        name = this.relations[name];\n      }\n\n      if (this.deserializers[name]) {\n        return this.new(name, this.deserializers[name](json, this));\n      } else {\n        return this.new(name, json);\n      }\n    };\n  };\n\n  Misago.addService('models', function() {\n    return new Models();\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.addService('set-momentjs-locale', function() {\n    moment.locale($('html').attr('lang'));\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Router = function(_) {\n    var self = this;\n    this.baseUrl = $('base').attr('href');\n\n    var staticUrl = Misago.get(_.context, 'STATIC_URL', '/');\n    var mediaUrl = Misago.get(_.context, 'MEDIA_URL', '/');\n\n    // Routing\n    this.urls = {};\n    this.reverses = {};\n\n    var populatePatterns = function(urlconf) {\n      urlconf.patterns().forEach(function(url) {\n        var finalPattern = self.baseUrl + url.pattern;\n        finalPattern = finalPattern.replace('//', '/');\n\n        self.urls[finalPattern] = _.route(url.component);\n        self.reverses[url.name] = finalPattern;\n      });\n    };\n\n    this.startRouting = function(urlconf, fixture) {\n      populatePatterns(urlconf);\n      this.fixture = fixture;\n\n      if (_.setup.test) {\n        m.route.mode = 'search';\n      } else {\n        m.route.mode = 'pathname';\n      }\n      m.route(fixture, '/', this.urls);\n    };\n\n    this.url = function(name) {\n      return this.reverses[name];\n    };\n\n    // Delegate clicks\n    this.delegateElement = null;\n\n    this.cleanUrl = function(url) {\n      if (!url) { return; }\n\n      // Is link relative?\n      var isRelative = url.substr(0, 1) === '/' && url.substr(0, 2) !== '//';\n\n      // If link contains host, validate to see if its outgoing\n      if (!isRelative) {\n        var location = window.location;\n\n        // If protocol matches current one, strip it from string\n        // otherwhise stop handler\n        if (url.substr(0, 2) !== '//') {\n          var protocol = url.substr(0, location.protocol.length + 2);\n          if (protocol !== location.protocol + '//') { return; }\n          url = url.substr(location.protocol.length + 2);\n        } else {\n          url = url.substr(2);\n        }\n\n        // Host checks out?\n        if (url.substr(0, location.host.length) !== location.host) { return; }\n        url = url.substr(location.host.length);\n      }\n\n      // Is link within Ember app?\n      if (url.substr(0, this.baseUrl.length) !== this.baseUrl) { return; }\n\n      // Is link to media/static/avatar server?\n      if (url.substr(0, staticUrl.length) === staticUrl) { return; }\n\n      if (url.substr(0, mediaUrl.length) === mediaUrl) { return; }\n\n      var avatarsUrl = '/user-avatar/';\n      if (url.substr(0, avatarsUrl.length) === avatarsUrl) { return; }\n\n      return url;\n    };\n\n    var delegateName = 'click.misago-router';\n    this.delegateClicks = function(element) {\n      this.delegateElement = element;\n      $(this.delegateElement).on(delegateName, 'a', function(e) {\n        var cleanUrl = self.cleanUrl(e.target.href);\n        if (cleanUrl) {\n          if (cleanUrl != m.route()) {\n            m.route(cleanUrl);\n          }\n          e.preventDefault();\n        }\n      });\n    };\n\n    this.destroy = function() {\n      $(this.delegateElement).off(delegateName);\n    };\n\n    // Media/Static url\n    var prefixUrl = function(prefix) {\n      return function(url) {\n        return prefix + url;\n      };\n    };\n\n    this.staticUrl = prefixUrl(staticUrl);\n    this.mediaUrl = prefixUrl(mediaUrl);\n\n    // Errors\n    this.error403 = function(error) {\n      var component = null;\n      if (error.ban) {\n        component = _.route('error:banned',\n          error.detail,\n          _.models.deserialize('ban', error.ban));\n      } else {\n        component = _.route('error:403', error.detail);\n      }\n      m.mount(this.fixture, component);\n    };\n\n    this.error404 = function() {\n      m.mount(this.fixture, _.route('error:404'));\n    };\n\n    this.error500 = function() {\n      m.mount(this.fixture, _.route('error:500'));\n    };\n\n    this.error0 = function() {\n      m.mount(this.fixture, _.route('error:0'));\n    };\n\n    this.errorPage = function(error) {\n      if (error.status === 0) {\n        this.error0();\n      }\n\n      if (error.status === 500) {\n        this.error500();\n      }\n\n      if (error.status === 404) {\n        this.error404();\n      }\n\n      if (error.status === 403) {\n        this.error403(error);\n      }\n    };\n  };\n\n  Misago.addService('router', function(_) {\n    return new Router(_);\n  });\n\n  Misago.addService('start-routing', function(_) {\n    _.router.startRouting(\n      Misago.urls, document.getElementById('router-fixture'));\n    _.router.delegateClicks(document.getElementById(_.setup.fixture));\n  },\n  {\n    before: '_end'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var boilerplate = function(component) {\n    // Component already boilerplated (this may happen in tests)\n    if (component._hasRouteBoilerplate) {\n      return component;\n    }\n    component._hasRouteBoilerplate = true;\n\n    // Add lifecycle hooks\n    var loadingView = function () {\n      var _ = this.container;\n      return m('.page.page-loading',\n        _.component('loader')\n      );\n    };\n\n    var errorHandler = function(error) {\n      if (this.isActive) {\n        this.container.router.errorPage(error);\n      }\n    };\n\n    return Misago.stateHooks(component, loadingView, errorHandler);\n  };\n\n  Misago.addService('routes', function(_) {\n    _._routes = {};\n    _.route = function(name, component) {\n      if (this._routes[name]) {\n        if (arguments.length > 1) {\n          var argumentsArray = [this._routes[name]];\n          for (var i = 1; i < arguments.length; i += 1) {\n            argumentsArray.push(arguments[i]);\n          }\n          argumentsArray.push(this);\n          return m.component.apply(undefined, argumentsArray);\n        } else {\n          return m.component(this._routes[name], this);\n        }\n      } else {\n        component.container = _;\n        this._routes[name] = boilerplate(component);\n      }\n    };\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var RunLoop = function(_) {\n    var self = this;\n\n    this._intervals = {};\n\n    var stopInterval = function(name) {\n      if (self._intervals[name]) {\n        window.clearTimeout(self._intervals[name]);\n        self._intervals[name] = null;\n      }\n    };\n\n    this.run = function(callable, name, delay) {\n      this._intervals[name] = window.setTimeout(function() {\n        stopInterval(name);\n        var result = callable(_);\n        if (result !== false) {\n          self.run(callable, name, delay);\n        }\n      }, delay);\n    };\n\n    this.runOnce = function(callable, name, delay) {\n      this._intervals[name] = window.setTimeout(function() {\n        stopInterval(name);\n        callable(_);\n      }, delay);\n    };\n\n    this.stop = function(name) {\n      for (var loop in this._intervals) {\n        if (!name || name === loop) {\n          stopInterval(loop);\n        }\n      }\n    };\n  };\n\n  Misago.addService('runloop', {\n    factory: function(_) {\n      return new RunLoop(_);\n    },\n\n    destroy: function(_) {\n      _.runloop.stop();\n    }\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.addService('start-tick', function(_) {\n    var ticks = m.prop();\n\n    _.runloop.run(function() {\n      m.startComputation();\n      // just tick once a minute so stuff gets rerendered\n      ticks(ticks() + 1);\n      // syncing dynamic timestamps, etc ect\n      m.endComputation();\n    }, 'tick', 60000);\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var PageTitle = function(forum_name) {\n    this.set = function(title) {\n      if (title) {\n        this._set_complex(title);\n      } else {\n        document.title = forum_name;\n      }\n    };\n\n    this._set_complex = function(title) {\n      if (typeof title === 'string') {\n        title = {title: title};\n      }\n\n      var completeTitle = title.title;\n\n      if (typeof title.page !== 'undefined' && title.page > 1) {\n        var page_label = interpolate(\n          gettext('page %(page)s'), { page:title.page }, true);\n        completeTitle += ' (' + page_label + ')';\n      }\n\n      if (typeof title.parent !== 'undefined') {\n        completeTitle += ' | ' + title.parent;\n      }\n\n      document.title = completeTitle + ' | ' + forum_name;\n    };\n  };\n\n  Misago.addService('page-title', function(_) {\n    _.title = new PageTitle(_.settings.forum_name);\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var EMAIL = /^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$/i;\n  var USERNAME = new RegExp('^[0-9a-z]+$', 'i');\n\n  // Validators namespace\n  Misago.validators = {\n    required: function() {\n      return function(value) {\n        if ($.trim(value).length === 0) {\n          return gettext(\"This field is required.\");\n        }\n      };\n    },\n    email: function(message) {\n      return function(value) {\n        if (!EMAIL.test(value)) {\n          return message || gettext('Enter a valid email address.');\n        }\n      };\n    },\n    minLength: function(limit_value, message) {\n      return function(value) {\n        var returnMessage = '';\n        var length = $.trim(value).length;\n\n        if (length < limit_value) {\n          if (message) {\n            returnMessage = message(limit_value, length);\n          } else {\n            returnMessage = ngettext(\n              \"Ensure this value has at least %(limit_value)s character (it has %(show_value)s).\",\n              \"Ensure this value has at least %(limit_value)s characters (it has %(show_value)s).\",\n              limit_value);\n          }\n          return interpolate(returnMessage, {\n            limit_value: limit_value,\n            show_value: length\n          }, true);\n        }\n      };\n    },\n    maxLength: function(limit_value, message) {\n      return function(value) {\n        var returnMessage = '';\n        var length = $.trim(value).length;\n\n        if (length > limit_value) {\n          if (message) {\n            returnMessage = message(limit_value, length);\n          } else {\n            returnMessage = ngettext(\n              \"Ensure this value has at most %(limit_value)s character (it has %(show_value)s).\",\n              \"Ensure this value has at most %(limit_value)s characters (it has %(show_value)s).\",\n              limit_value);\n          }\n          return interpolate(returnMessage, {\n            limit_value: limit_value,\n            show_value: length\n          }, true);\n        }\n      };\n    },\n    usernameMinLength: function(settings) {\n      var message = function(limit_value) {\n        return ngettext(\n          \"Username must be at least %(limit_value)s character long.\",\n          \"Username must be at least %(limit_value)s characters long.\",\n          limit_value);\n      };\n      return this.minLength(settings.username_length_min, message);\n    },\n    usernameMaxLength: function(settings) {\n      var message = function(limit_value) {\n        return ngettext(\n          \"Username cannot be longer than %(limit_value)s character.\",\n          \"Username cannot be longer than %(limit_value)s characters.\",\n          limit_value);\n      };\n      return this.maxLength(settings.username_length_max, message);\n    },\n    usernameContent: function() {\n      return function(value) {\n        if (!USERNAME.test($.trim(value))) {\n          return gettext(\"Username can only contain latin alphabet letters and digits.\");\n        }\n      };\n    },\n    passwordMinLength: function(settings) {\n      var message = function(limit_value) {\n        return ngettext(\n          \"Valid password must be at least %(limit_value)s character long.\",\n          \"Valid password must be at least %(limit_value)s characters long.\",\n          limit_value);\n      };\n      return this.minLength(settings.password_length_min, message);\n    }\n  };\n\n  var validateField = function(value, validators) {\n    var result = Misago.validators.required()(value);\n    var errors = [];\n\n    if (result) {\n      return [result];\n    } else {\n      for (var i in validators) {\n        result = validators[i](value);\n\n        if (result) {\n          errors.push(result);\n        }\n      }\n    }\n\n    return errors.length ? errors : true;\n  };\n\n  var validateForm = function(form) {\n    var errors = {};\n    var value = null;\n\n    var isValid = true;\n\n    for (var key in form.validation) {\n      if (form.validation.hasOwnProperty(key)) {\n        value = form[key]();\n        errors[key] = validateField(form[key](), form.validation[key]);\n        if (errors[key] !== true) {\n          isValid = false;\n        }\n      }\n    }\n\n    form.errors = errors;\n    return isValid;\n  };\n\n  var validate = function(form, name) {\n    if (name) {\n      return function(value) {\n        var errors = null;\n        if (typeof value !== 'undefined') {\n          errors = validateField(value, form.validation[name]);\n          if (errors) {\n            if (!form.errors) {\n              form.errors = {};\n            }\n            form.errors[name] = errors;\n          }\n          form[name](value);\n          return form[name](value);\n        } else {\n          return form[name]();\n        }\n      };\n    } else {\n      return validateForm(form);\n    }\n  };\n\n  Misago.addService('validate', {\n    factory: function() {\n      return validate;\n    }\n  });\n}(Misago.prototype));\n\n/* global zxcvbn */\n(function (Misago) {\n  'use strict';\n\n  var Zxcvbn = function(_) {\n    this.included = false;\n\n    this.scorePassword = function(password, inputs) {\n      // 0-4 score, the more the stronger password\n      return zxcvbn(password, inputs).score;\n    };\n\n    // loading\n    this.include = function() {\n      _.include('misago/js/zxcvbn.js');\n      this.included = true;\n    };\n\n    var wait = function(promise) {\n      if (typeof zxcvbn !== \"undefined\") {\n        promise.resolve();\n      } else {\n        _.runloop.runOnce(function() {\n          wait(promise);\n        }, 'loading-zxcvbn', 150);\n      }\n    };\n\n    var deferred = m.deferred();\n    this.load = function() {\n      if (!this.included) {\n        this.include();\n      }\n      wait(deferred);\n      return deferred.promise;\n    };\n  };\n\n  Misago.addService('zxcvbn', function(_) {\n    return new Zxcvbn(_);\n  },\n  {\n    after: 'include'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Ban = function(data) {\n    this.message = {\n      html: data.message.html,\n      plain: data.message.plain,\n    };\n\n    this.expires_on = data.expires_on;\n  };\n\n  var deserializeBan = function(data) {\n    data.expires_on = Misago.deserializeDatetime(data.expires_on);\n\n    return data;\n  };\n\n  Misago.addService('model:ban', function(_) {\n    _.models.add('ban', {\n      class: Ban,\n      deserialize: deserializeBan\n    });\n  },\n  {\n    after: 'models'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var LegalPage = function(data) {\n    this.title = data.title;\n    this.body = data.body;\n    this.link = data.link;\n  };\n\n  Misago.addService('model:legal-page', function(_) {\n    _.models.add('legal-page', {\n      class: LegalPage\n    });\n  },\n  {\n    after: 'models'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var User = function(data) {\n    this.id = data.id;\n\n    this.isAuthenticated = !!this.id;\n    this.isAnonymous = !this.isAuthenticated;\n\n    this.slug = data.slug;\n    this.username = data.username;\n\n    this.acl = data.acl;\n    this.rank = data.rank;\n  };\n\n  var deserializeUser = function(data) {\n    if (data.joined_on) {\n      data.joined_on = Misago.deserializeDatetime(data.joined_on);\n    }\n\n    return data;\n  };\n\n  Misago.addService('model:user', function(_) {\n    _.models.add('user', {\n      class: User,\n      deserialize: deserializeUser\n    });\n  },\n  {\n    after: 'models'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var errorPage = function(error) {\n    var error_message = [\n      m('p.lead', error.message)\n    ];\n\n    if (error.help) {\n      error_message.push(m('p.help', error.help));\n    }\n\n    return m('.page.page-error.page-error-' + error.code,\n      m('.container',\n        m('.error-panel', [\n          m('.error-icon',\n            m('span.material-icon', error.icon)\n          ),\n          m('.error-message', error_message)\n        ])\n      )\n    );\n  };\n\n  var errorBanned = {\n    controller: function() {\n      this.container.title.set(gettext('You are banned'));\n    },\n    view: function(ctrl, message, ban) {\n      var error_message = [];\n\n      if (ban.message.html) {\n        error_message.push(m('.lead', m.trust(ban.message.html)));\n      } else if (message) {\n        error_message.push(m('p.lead', message));\n      } else {\n        error_message.push(m('p.lead', gettext('You are banned.')));\n      }\n\n      var expirationMessage = null;\n      if (ban.expires_on) {\n        if (ban.expires_on.isAfter(moment())) {\n          expirationMessage = interpolate(\n            gettext('This ban expires %(expires_on)s.'),\n            {'expires_on': ban.expires_on.fromNow()},\n            true);\n        } else {\n          expirationMessage = gettext('This ban has expired.');\n        }\n      } else {\n        expirationMessage = gettext('This ban is permanent.');\n      }\n      error_message.push(m('p', expirationMessage));\n\n      return m('.page.page-error.page-error-banned',\n        m('.container',\n          m('.error-panel', [\n            m('.error-icon',\n              m('span.material-icon', 'highlight_off')\n            ),\n            m('.error-message', error_message)\n          ])\n        )\n      );\n    }\n  };\n\n  var error403 = {\n    controller: function() {\n      this.container.title.set(gettext('Page not available'));\n    },\n    view: function(ctrl, message) {\n      if (message === \"Permission denied\") {\n        message = gettext(\"You don't have permission to access this page.\");\n      }\n\n      return errorPage({\n        code: 403,\n        icon: 'remove_circle_outline',\n        message: gettext(\"This page is not available.\"),\n        help: message\n      });\n    }\n  };\n\n  var error404 = {\n    controller: function() {\n      this.container.title.set(gettext('Page not found'));\n    },\n    view: function() {\n      return errorPage({\n        code: 404,\n        icon: 'info_outline',\n        message: gettext(\"Requested page could not be found.\"),\n        help: gettext(\"The link you followed was incorrect or the page has been moved or deleted.\")\n      });\n    }\n  };\n\n  var error500 = {\n    controller: function() {\n      this.container.title.set(gettext('Application error occured'));\n    },\n    view: function() {\n      return errorPage({\n        code: 500,\n        icon: 'error_outline',\n        message: gettext(\"Requested page could not be displayed due to an error.\"),\n        help: gettext(\"Please try again later or contact site staff if error persists.\")\n      });\n    }\n  };\n\n  var error0 = {\n    controller: function() {\n      this.container.title.set(gettext('Lost connection with application'));\n    },\n    view: function() {\n      return errorPage({\n        code: 0,\n        icon: 'sync_problem',\n        message: gettext(\"Could not connect to application.\"),\n        help: gettext(\"This may be caused by problems with your connection or application server. Please check your internet connection and refresh page if problem persists.\")\n      });\n    }\n  };\n\n  Misago.addService('route:error-pages', function(_) {\n    _.route('error:banned', errorBanned);\n    _.route('error:403', error403);\n    _.route('error:404', error404);\n    _.route('error:500', error500);\n    _.route('error:0', error0);\n  },\n  {\n    after: 'routes'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var index = {\n    controller: function(_) {\n      document.title = _.settings.forum_index_title || _.settings.forum_name;\n\n      return {\n        active: function() {\n          _.modal('register-complete', {\n            'activation': 'active',\n            'username': 'BobBoberson',\n            'email': 'bob-boberson@somewhere.com'\n          });\n        },\n        user: function() {\n          _.modal('register-complete', {\n            'activation': 'by_user',\n            'username': 'BobBoberson',\n            'email': 'bob-boberson@somewhere.com'\n          });\n        },\n        admin: function() {\n          _.modal('register-complete', {\n            'activation': 'by_admin',\n            'username': 'BobBoberson',\n            'email': 'bob-boberson@somewhere.com'\n          });\n        }\n      };\n    },\n    view: function(ctrl, _) {\n      return m('.container', [\n        m('h1', 'Buttons'),\n        m('p', 'Test registration successful modal!'),\n        m('',\n          _.component('button', {\n            class: '.btn-success',\n            label: 'Registration done, account active',\n            onclick: ctrl.active\n          })\n        ),\n        m('',\n          _.component('button', {\n            class: '.btn-warning',\n            label: 'Registration done, account inactive (user)',\n            onclick: ctrl.user\n          })\n        ),\n        m('',\n          _.component('button', {\n            class: '.btn-danger',\n            label: 'Registration done, account inactive (admin)',\n            onclick: ctrl.admin\n          })\n        ),\n      ]);\n    }\n  };\n\n  Misago.addService('route:index', function(_) {\n    _.route('index', index);\n  },\n  {\n    after: 'routes'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var legalPageFactory = function(typeName, defaultTitle) {\n    var dashedTypeName = typeName.replace(/_/g, '-');\n\n    return {\n      controller: function(_) {\n        if (Misago.get(_.settings, typeName + '_link')) {\n          window.location = Misago.get(_.settings, typeName + '_link');\n        } else {\n          this.vm.init(this, _);\n        }\n      },\n      vm: {\n        page: null,\n        isReady: false,\n        init: function(component, _) {\n          if (this.isReady) {\n            _.title.set(this.title);\n          } else {\n            _.title.set();\n            return _.api.model('legal-page', dashedTypeName);\n          }\n        },\n        ondata: function(page, component, _) {\n          m.startComputation();\n\n          if (page.link) {\n            window.location = page.link;\n          } else {\n            page.title = page.title || defaultTitle;\n            this.page = page;\n            this.isReady = true;\n\n            m.endComputation();\n\n            if (component.isActive) {\n              _.title.set(this.page.title);\n            }\n          }\n        }\n      },\n      view: function(ctrl, _) {\n        return m('.page.page-legal.page-legal-' + dashedTypeName, [\n          _.component('header', {title: this.vm.page.title}),\n          m('.container',\n            _.component('markup', this.vm.page.body)\n          )\n        ]);\n      }\n    };\n  };\n\n  Misago.addService('route:legal-pages', function(_) {\n    _.route('terms-of-service', legalPageFactory(\n      'terms_of_service', gettext('Terms of service')));\n    _.route('privacy-policy', legalPageFactory(\n      'privacy_policy', gettext('Privacy policy')));\n  },\n  {\n    after: 'routes'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var isMenuVisible = function(settings) {\n    return [\n      !!settings.forum_footnote,\n      !!settings.terms_of_service,\n      !!settings.terms_of_service_link,\n      !!settings.privacy_policy,\n      !!settings.privacy_policy_link\n    ].indexOf(true) !== -1;\n  };\n\n  var footer = {\n    view: function(ctrl, _) {\n      var nav = null;\n      if (isMenuVisible(_.settings)) {\n        nav = _.component('footer:menu');\n      }\n\n      return m('footer.forum-footer', [\n        m('.container',\n          m('.footer-content', [\n            nav,\n            _.component('footer:branding')\n          ])\n        )\n      ]);\n    }\n  };\n\n  Misago.addService('component:footer', function(_) {\n    _.component('footer', footer);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var legalLink = function(_, legalType, defaultTitle) {\n    var url = Misago.get(_.settings, legalType + '_link');\n    if (!url && Misago.get(_.settings, legalType)) {\n      url = _.router.url(legalType);\n    }\n\n    if (url) {\n      return m('li',\n        m('a', {href: url},\n          Misago.get(_.settings, legalType + '_title', defaultTitle)\n        )\n      );\n    } else {\n      return null;\n    }\n  };\n\n  var menu = {\n    isVisible: function(settings) {\n      return [\n        !!settings.forum_footnote,\n        !!settings.terms_of_service,\n        !!settings.terms_of_service_link,\n        !!settings.privacy_policy,\n        !!settings.privacy_policy_link\n      ].indexOf(true) !== -1;\n    },\n    view: function(ctrl, _) {\n      var items = [];\n\n      if (_.settings.forum_footnote) {\n        items.push(m('li.forum-footnote', m.trust(_.settings.forum_footnote)));\n      }\n\n      items.push(\n        legalLink(_, 'terms_of_service', gettext('Terms of service')));\n      items.push(\n        legalLink(_, 'privacy_policy', gettext('Privacy policy')));\n\n      return m('ul.list-inline.footer-nav', items);\n    }\n  };\n\n  Misago.addService('component:footer:menu', function(_) {\n    _.component('footer:menu', menu);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var branding = {\n    view: function() {\n      return m('a.misago-branding[href=http://misago-project.org]', [\n        \"powered by \", m('strong', \"misago\")\n      ]);\n    }\n  };\n\n  Misago.addService('component:footer:branding', function(_) {\n    _.component('footer:branding', branding);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var header = {\n    view: function(ctrl, title) {\n      return m('.modal-header', [\n        m('button.close[type=\"button\"]',\n          {'data-dismiss': 'modal', 'aria-label': gettext('Close')},\n          m('span', {'aria-hidden': 'true'}, m.trust('&times;'))\n        ),\n        m('h4#misago-modal-label.modal-title', title)\n      ]);\n    }\n  };\n\n  Misago.addService('component:modal:header', function(_) {\n    _.component('modal:header', header);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var refresh = function() {\n    document.location.reload();\n  };\n\n  var registerComplete = {\n    controller: function(message, _) {\n      if (message.activation === 'active') {\n        _.runloop.runOnce(\n          refresh, 'refresh-after-registration', 10000);\n      }\n    },\n    view: function(ctrl, message, _) {\n      var messageHtml = null;\n\n      if (message.activation === 'active') {\n        messageHtml = this.active(message);\n      } else {\n        messageHtml = this.inactive(message);\n      }\n\n      return m('.modal-dialog.modal-message.modal-register[role=\"document\"]',\n        {config: persistent},\n        m('.modal-content', [\n          _.component('modal:header', gettext('Registration complete')),\n          m('.modal-body',\n            messageHtml\n          )\n        ])\n      );\n    },\n    active: function(message) {\n      var lead = gettext(\"%(username)s, your account has been created and you were signed in.\");\n      return [\n        m('.message-icon',\n          m('span.material-icon', 'check')\n        ),\n        m('.message-body', [\n          m('p.lead',\n            interpolate(lead, {'username': message.username}, true)\n          ),\n          m('p',\n            gettext('The page will refresh automatically in 10 seconds.')\n          ),\n          m('p',\n            m('button[type=\"button\"].btn.btn-default', {onclick: refresh},\n              gettext('Refresh page')\n            )\n          )\n        ])\n      ];\n    },\n    inactive: function(message) {\n      var lead = null;\n      var help = null;\n\n      if (message.activation === 'user') {\n        lead = gettext(\"%(username)s, your account has been created but you need to activate it before you will be able to sign in.\");\n        help = gettext(\"We have sent an e-mail to %(email)s with link that you have to click to activate your account.\");\n      } else if (message.activation === 'admin') {\n        lead = gettext(\"%(username)s, your account has been created but board administrator will have to activate it before you will be able to sign in.\");\n        help = gettext(\"We will send an e-mail to %(email)s when this takes place.\");\n      }\n\n      return [\n        m('.message-icon',\n          m('span.material-icon', 'info_outline')\n        ),\n        m('.message-body', [\n          m('p.lead',\n            interpolate(lead, {'username': message.username}, true)\n          ),\n          m('p',\n            interpolate(help, {'email': message.email}, true)\n          )\n        ])\n      ];\n    }\n  };\n\n  Misago.addService('modal:register-complete', function(_) {\n    _.modal('register-complete', registerComplete);\n  },\n  {\n    after: 'modals'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var register = {\n    controller: function(_) {\n      return {\n        form: _.form('register')\n      };\n    },\n    view: function(ctrl, _) {\n      var captcha = _.captcha.component({\n        form: ctrl.form,\n\n        labelClass: '.col-md-4',\n        controlClass: '.col-md-8'\n      });\n\n      var footnote = null;\n      var termsUrl = _.settings.terms_of_service_link;\n\n      if (!termsUrl && _.settings.terms_of_service) {\n        termsUrl = _.router.url('terms_of_service');\n      }\n\n      if (termsUrl) {\n        footnote = m('a', {href: termsUrl},\n          m.trust(interpolate(gettext(\"By registering you agree to site's %(terms)s.\"), {\n            terms: '<strong>' + gettext(\"terms and conditions\") + '</strong>'\n          }, true))\n        );\n      }\n\n      return m('.modal-dialog.modal-form.modal-register[role=\"document\"]',\n        {config: persistent},\n        m('.modal-content', [\n          _.component('modal:header', gettext('Register')),\n          m('form.form-horizontal',\n          {\n            onsubmit: ctrl.form.submit\n          },\n          [\n            m('input[type=\"text\"]', {\n              name:'_username',\n              style: 'display: none'\n            }),\n            m('input[type=\"password\"]', {\n              name:'_password',\n              style: 'display: none'\n            }),\n            m('.modal-body', [\n              _.component('form-group', {\n                label: gettext(\"Username\"),\n                labelClass: '.col-md-4',\n                controlClass: '.col-md-8',\n                control: _.input({\n                  value: _.validate(ctrl.form, 'username'),\n                  id: 'id_username',\n                  disabled: ctrl.form.isBusy\n                }),\n                validation: ctrl.form.errors,\n                validationKey: 'username'\n              }),\n              _.component('form-group', {\n                label: gettext(\"E-mail\"),\n                labelClass: '.col-md-4',\n                controlClass: '.col-md-8',\n                control: _.input({\n                  value: _.validate(ctrl.form, 'email'),\n                  id: 'id_email',\n                  disabled: ctrl.form.isBusy\n                }),\n                validation: ctrl.form.errors,\n                validationKey: 'email'\n              }),\n              _.component('form-group', {\n                label: gettext(\"Password\"),\n                labelClass: '.col-md-4',\n                controlClass: '.col-md-8',\n                control: _.input({\n                  value: _.validate(ctrl.form, 'password'),\n                  type: 'password',\n                  id: 'id_password',\n                  disabled: ctrl.form.isBusy\n                }),\n                validation: ctrl.form.errors,\n                validationKey: 'password',\n                helpText: _.component('password-strength', {\n                  inputs: [\n                    ctrl.form.username(),\n                    ctrl.form.email()\n                  ],\n                  password: ctrl.form.password()\n                })\n              }),\n              captcha\n            ]),\n            m('.modal-footer', [\n              footnote,\n              _.component('button', {\n                class: '.btn-primary',\n                submit: true,\n                loading: ctrl.form.isBusy,\n                label: gettext(\"Register account\")\n              })\n            ])\n          ])\n        ])\n      );\n    }\n  };\n\n  Misago.addService('modal:register', function(_) {\n    _.modal('register', register);\n  },\n  {\n    after: 'modals'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  function persistent(el, isInit, context) {\n    context.retain = true;\n  }\n\n  var signin = {\n    controller: function(_) {\n      return {\n        form: _.form('sign-in')\n      };\n    },\n    view: function(ctrl, _) {\n      return m('.modal-dialog.modal-sm.modal-signin[role=\"document\"]',\n        {config: persistent},\n        m('.modal-content', [\n          _.component('modal:header', gettext(\"Sign in\")),\n          m('form', {onsubmit: ctrl.form.submit}, [\n            m('.modal-body', [\n              m('.form-group',\n                m('.control-input',\n                  Misago.input({\n                    disabled: ctrl.form.isBusy,\n                    value: ctrl.form.username,\n                    placeholder: gettext(\"Username or e-mail\")\n                  })\n                )\n              ),\n              m('.form-group',\n                m('.control-input',\n                  Misago.input({\n                    type: 'password',\n                    disabled: ctrl.form.isBusy,\n                    value: ctrl.form.password,\n                    placeholder: gettext(\"Password\")\n                  })\n                )\n              )\n            ]),\n            m('.modal-footer',\n              _.component('button', {\n                class: '.btn-primary.btn-block',\n                submit: true,\n                loading: ctrl.form.isBusy,\n                label: gettext(\"Sign in\")\n              })\n            )\n          ])\n        ])\n      );\n    }\n  };\n\n  Misago.addService('modal:sign-in', function(_) {\n    _.modal('sign-in', signin);\n  },\n  {\n    after: 'modals'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var navbar = {\n    view: function(ctrl, _) {\n      var style = '.navbar.navbar-default.navbar-static-top';\n      return m('nav' + style + '[role=\"navigation\"]', [\n        _.component('navbar:desktop')\n      ]);\n    }\n  };\n\n  Misago.addService('component:navbar', function(_) {\n    _.component('navbar', navbar);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var brand = {\n    view: function(ctrl, branding, _) {\n      var children = [\n        m('img', {\n          src: _.router.staticUrl('misago/img/site-logo.png'),\n          alt: _.settings.forum_name\n        })\n      ];\n\n      if (branding) {\n        children.push(branding);\n      }\n\n      return m('a.navbar-brand', {href: _.router.url('index')}, children);\n    }\n  };\n\n  Misago.addService('component:navbar:desktop:brand', function(_) {\n    _.component('navbar:desktop:brand', brand);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var menu = {\n    controller: function(_) {\n      return {\n        showSignIn: function() {\n          _.modal('sign-in');\n        },\n\n        isBusy: false,\n        showRegister: function() {\n          if (_.settings.account_activation === 'closed') {\n            _.alert.info(gettext(\"New registrations are currently disabled.\"));\n          } else {\n            m.startComputation();\n            this.isBusy = true;\n            m.endComputation();\n\n            var self = this;\n            m.sync([\n              _.zxcvbn.load(),\n              _.captcha.load()\n            ]).then(function() {\n              _.modal('register');\n            }, function() {\n              _.alert.error(gettext('Registation is not available now due to an error.'));\n            }).then(function() {\n              m.startComputation();\n              self.isBusy = false;\n              m.endComputation();\n            });\n          }\n        }\n      };\n    },\n    view: function(ctrl, _) {\n      return m('div.nav.nav-guest', [\n        _.component('button', {\n          class: '.navbar-btn.btn-default',\n          onclick: ctrl.showSignIn,\n          disabled: ctrl.isBusy,\n          label: gettext('Sign in')\n        }),\n        _.component('button', {\n          class: '.navbar-btn.btn-primary',\n          onclick: ctrl.showRegister.bind(ctrl),\n          loading: ctrl.isBusy,\n          label: gettext('Register')\n        })\n      ]);\n    }\n  };\n\n  Misago.addService('component:navbar:desktop:guest-menu', function(_) {\n    _.component('navbar:desktop:guest-menu', menu);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var navbar = {\n    view: function(ctrl, _) {\n      var menu = [];\n\n      if (_.settings.forum_branding_display) {\n        menu.push(\n          _.component('navbar:desktop:brand', _.settings.forum_branding_text));\n      }\n\n      menu.push(m('ul.nav.navbar-nav', [\n        m('li',\n          m(\"a\", {config: m.route, href: _.router.url('index')}, 'Index')\n        )\n      ]));\n\n      if (_.user.isAuthenticated) {\n        menu.push(_.component('navbar:desktop:user-menu'));\n      } else {\n        menu.push(_.component('navbar:desktop:guest-menu'));\n      }\n\n      return m('.container.navbar-full.hidden-xs.hidden-sm', menu);\n    }\n  };\n\n  Misago.addService('component:navbar:desktop', function(_) {\n    _.component('navbar:desktop', navbar);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var menu = {\n    controller: function() {\n      return {\n        logout: function() {\n          $('#hidden-logout-form').submit();\n        }\n      };\n    },\n    view: function(ctrl, _) {\n      return m('div.nav.nav-user', [\n        m('p.navbar-text',\n          _.user.username\n        ),\n        m('button.navbar-btn.btn.btn-default.navbar-right',\n          {\n            onclick: ctrl.logout.bind(ctrl)\n          },\n          gettext(\"Logout\")\n        )\n      ]);\n    }\n  };\n\n  Misago.addService('component:navbar:desktop:user-menu', function(_) {\n    _.component('navbar:desktop:user-menu', menu);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  function persistent(el, isInit, context) {\n    context.retain = true;\n  }\n\n  var alert = {\n    classes: {\n      'info': 'alert-info',\n      'success': 'alert-success',\n      'warning': 'alert-warning',\n      'error': 'alert-danger'\n    },\n    view: function(ctrl, _) {\n      return m(\n        '.alerts',\n        {\n          config: persistent,\n          class: _.alert.isVisible ? 'in' : 'out'\n        },\n        m('p.alert',\n          {\n            class: this.classes[_.alert.type]\n          },\n          _.alert.message\n        )\n      );\n    }\n  };\n\n  Misago.addService('component:alert', function(_) {\n    _.component('alert', alert);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var button = {\n    view: function(ctrl, kwargs) {\n      var options = {\n        disabled: kwargs.disabled || kwargs.loading || false,\n        config: kwargs.config || null,\n        loading: kwargs.loading || false,\n        type: kwargs.submit ? 'submit' : 'button',\n        onclick: kwargs.onclick || null\n      };\n\n      var element = 'button[type=\"' + options.type + '\"].btn';\n      if (options.loading) {\n        element += '.btn-loading';\n      }\n\n      if (kwargs.id) {\n        element += '#' + kwargs.id;\n      }\n\n      element += (kwargs.class || '');\n\n      var label = kwargs.label;\n      if (options.loading) {\n        label = [\n          label,\n          m('.loader-compact', [\n            m('.bounce1'),\n            m('.bounce2'),\n            m('.bounce3')\n          ])\n        ];\n      }\n\n      return m(element, options, label);\n    },\n  };\n\n  Misago.addService('component:button', function(_) {\n    _.component('button', button);\n  },\n  {\n    after: 'components'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var textFields = ['text', 'password', 'email'];\n\n  var formGroup = {\n    view: function(ctrl, kwargs) {\n      var groupClass = '.form-group';\n      var errors = null;\n      var helpText = null;\n\n      var controlType = kwargs.control.attrs.type;\n      var controlId = kwargs.control.attrs.id;\n\n      var feedbackId = controlId + '_feedback';\n      var feedbackIcon = null;\n      var showFeedbackIcon = null;\n\n      var isValidated = kwargs.validationKey && kwargs.validation !== null;\n\n      kwargs.control.attrs['aria-describedby'] = '';\n\n      if (isValidated && kwargs.validation[kwargs.validationKey]) {\n        showFeedbackIcon = textFields.indexOf(controlType) >= 0;\n        kwargs.control.attrs['aria-describedby'] = feedbackId;\n\n        if (kwargs.validation[kwargs.validationKey] === true) {\n          groupClass += '.has-success';\n          feedbackIcon = [\n            m('span.material-icon.form-control-feedback',\n              {\n                'aria-hidden': 'true'\n              },\n              'check'\n            ),\n            m('span.sr-only#' + feedbackId, gettext(\"(success)\"))\n          ];\n        } else {\n          groupClass += '.has-error';\n          errors = kwargs.validation[kwargs.validationKey];\n          feedbackIcon = [\n            m('span.material-icon.form-control-feedback',\n              {\n                'aria-hidden': 'true'\n              },\n              'clear'\n            ),\n            m('span.sr-only#' + feedbackId, gettext(\"(error)\"))\n          ];\n        }\n      }\n\n      if (kwargs.helpText) {\n        if (typeof kwargs.helpText === 'string' ||\n            kwargs.helpText instanceof String) {\n          helpText = m('p.help-block', kwargs.helpText);\n        } else {\n          helpText = kwargs.helpText;\n        }\n      }\n\n      return m(groupClass, [\n        m('label.control-label' + (kwargs.labelClass || ''),\n          {\n            for: kwargs.labelFor || controlId\n          },\n          kwargs.label + ':'\n        ),\n        m(kwargs.controlClass || '', [\n          kwargs.control,\n          showFeedbackIcon ? feedbackIcon : null,\n          errors ? m('.help-block.errors', errors.map(function(item) {\n            return m('p', item);\n          })) : null,\n          helpText\n        ])\n      ]);\n    },\n  };\n\n  Misago.addService('component:form-group', function(_) {\n    _.component('form-group', formGroup);\n  },\n  {\n    after: 'components'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var forumLayout = {\n    view: function(ctrl, _) {\n      return [\n        _.component('alert'),\n        _.component('navbar'),\n        m('#router-fixture', {config: persistent}),\n        _.component('footer'),\n        _.component('modal')\n      ];\n    }\n  };\n\n  Misago.addService('component:layout', function(_) {\n    _.component('forum-layout', forumLayout);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var loader = {\n    view: function() {\n      return m('.loader.sk-folding-cube', [\n        m('.sk-cube1.sk-cube'),\n        m('.sk-cube2.sk-cube'),\n        m('.sk-cube4.sk-cube'),\n        m('.sk-cube3.sk-cube')\n      ]);\n    }\n  };\n\n  Misago.addService('component:loader', function(_) {\n    _.component('loader', loader);\n  },\n  {\n    after: 'components'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var markup = {\n    view: function(ctrl, content) {\n      return m('article.misago-markup', {config: persistent},\n        m.trust(content)\n      );\n    }\n  };\n\n  Misago.addService('component:markup', function(_) {\n    _.component('markup', markup);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var modal = {\n    view: function() {\n      return m(\n        '#misago-modal.modal.fade[role=\"dialog\"]',\n        {\n          config: persistent,\n          tabindex: \"-1\",\n          \"aria-labelledby\": \"misago-modal-label\"\n        }\n      );\n    }\n  };\n\n  Misago.addService('component:modal', function(_) {\n    _.component('modal', modal);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var header = {\n    view: function(ctrl, options) {\n      return m('.page-header',\n        m('.container', [\n          m('h1', options.title),\n        ])\n      );\n    }\n  };\n\n  Misago.addService('component:header', function(_) {\n    _.component('header', header);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var styles = [\n    'progress-bar-danger',\n    'progress-bar-warning',\n    'progress-bar-warning',\n    'progress-bar-primary',\n    'progress-bar-success'\n  ];\n\n  var labels = [\n    gettext('Entered password is very weak.'),\n    gettext('Entered password is weak.'),\n    gettext('Entered password is average.'),\n    gettext('Entered password is strong.'),\n    gettext('Entered password is very strong.')\n  ];\n\n  var passwordStrength = {\n    view: function(ctrl, kwargs, _) {\n      var score = _.zxcvbn.scorePassword(kwargs.password, kwargs.inputs);\n      var options = {\n        config: persistent,\n        class: styles[score],\n        style: \"width: \" + (20 + (20 * score)) + '%',\n        'role': \"progressbar\",\n        'aria-valuenow': score,\n        'aria-valuemin': \"0\",\n        'aria-valuemax': \"4\"\n      };\n\n      return m('.help-block.password-strength', {key: 'password-strength'}, [\n        m('.progress',\n          m('.progress-bar', options,\n            m('span.sr-only', labels[score])\n          )\n        ),\n        m('p.text-small', labels[score])\n      ]);\n    },\n  };\n\n  Misago.addService('component:password-strength', function(_) {\n    _.component('password-strength', passwordStrength);\n  },\n  {\n    after: 'components'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Register = function(_) {\n    var self = this;\n\n    this.showActivation = false;\n\n    this.username = m.prop('');\n    this.email = m.prop('');\n    this.password = m.prop('');\n\n    this.captcha = _.captcha.value;\n\n    this.errors = null;\n\n    this.validation = {\n      'username': [\n        Misago.validators.usernameContent(),\n        Misago.validators.usernameMinLength(_.settings),\n        Misago.validators.usernameMaxLength(_.settings)\n      ],\n      'email': [\n        Misago.validators.email()\n      ],\n      'password': [\n        Misago.validators.passwordMinLength(_.settings)\n      ],\n      'captcha': _.captcha.validator()\n    };\n\n    this.clean = function() {\n      if (this.errors === null) {\n        _.validate(this);\n      }\n\n      _.captcha.clean(this);\n\n      if (this.hasErrors()) {\n        _.alert.error(gettext(\"Form contains errors.\"));\n        return false;\n      } else {\n        return true;\n      }\n    };\n\n    this.submit = function() {\n      _.api.model('user').post({\n        username: this.username(),\n        email: this.email(),\n        password: this.password(),\n        captcha: this.captcha()\n      }).then(this.success, this.error);\n    };\n\n    this.success = function(data) {\n      _.modal('register-complete', data);\n    };\n\n    this.error = function(rejection) {\n      if (rejection.status === 400) {\n        _.alert.error(gettext(\"Form contains errors.\"));\n        $.extend(self.errors, rejection);\n      } else {\n        _.api.alert(rejection);\n      }\n    };\n  };\n\n  Misago.addService('form:register', function(_) {\n    _.form('register', Register);\n  },\n  {\n    after: 'forms'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var SignIn = function(_) {\n    var self = this;\n\n    this.showActivation = false;\n\n    this.username = m.prop('');\n    this.password = m.prop('');\n\n    this.validation = {\n      'username': [],\n      'password': []\n    };\n\n    this.clean = function() {\n      if (!_.validate(this)) {\n        _.alert.error(gettext(\"Fill out both fields.\"));\n        return false;\n      } else {\n        return true;\n      }\n    };\n\n    this.submit = function() {\n      _.api.endpoint('auth').post({\n        username: self.username(),\n        password: self.password()\n      }).then(function() {\n        self.success();\n      }, function(error) {\n        self.error(error);\n      });\n    };\n\n    this.success = function() {\n      _.modal();\n\n      var $form = $('#hidden-login-form');\n\n      // refresh CSRF token because api call to /auth/ changed it\n      _.ajax.refreshCsrfToken();\n\n      // fill out form with user credentials and submit it, this will tell\n      // misago to redirect user back to right page, and will trigger browser's\n      // key ring feature\n      $form.find('input[type=\"hidden\"]').val(_.ajax.csrfToken);\n      $form.find('input[name=\"redirect_to\"]').val(m.route());\n      $form.find('input[name=\"username\"]').val(this.username());\n      $form.find('input[name=\"password\"]').val(this.password());\n      $form.submit();\n    };\n\n    this.error = function(rejection) {\n      if (rejection.status === 400) {\n        if (rejection.code === 'inactive_admin') {\n          _.alert.info(rejection.detail);\n        } else if (rejection.code === 'inactive_user') {\n          _.alert.info(rejection.detail);\n          self.showActivation = true;\n        } else if (rejection.code === 'banned') {\n          _.modal();\n          _.router.error403({\n            message: '',\n            ban: rejection.detail\n          });\n        } else {\n          _.alert.error(rejection.detail);\n        }\n      } else {\n        _.api.alert(rejection);\n      }\n    };\n  };\n\n  Misago.addService('form:sign-in', function(_) {\n    _.form('sign-in', SignIn);\n  },\n  {\n    after: 'forms'\n  });\n} (Misago.prototype));\n\n(function (Misago, UrlConf) {\n  'use strict';\n\n  var urls = new UrlConf();\n  urls.url('/', 'index');\n\n  // Legal pages\n  urls.url(\n    '/terms-of-service/',\n    'terms_of_service');\n\n  urls.url(\n    '/privacy-policy/',\n    'privacy_policy');\n\n  // Catch-all 404 not found route\n  urls.url('/:rest...', 'error:404', 'not_found');\n\n  Misago.urls = urls;\n} (Misago.prototype, Misago.prototype.UrlConf));\n"],"sourceRoot":"/source/"}
+{"version":3,"sources":["misago.js"],"names":["window","Misago","ns","Object","getPrototypeOf","this","self","_initServices","services","orderedServices","OrderedList","order","forEach","item","factory","undefined","serviceInstance","key","_destroyServices","reverse","destroy","context","SETTINGS","setup","init","fixture","get","test","api","_services","proto","prototype","addService","name","push","after","before","PermissionDenied","message","detail","status","toString","has","obj","hasOwnProperty","value","pop","returnValue","persistent","el","isInit","retain","input","kwargs","options","disabled","config","placeholder","autocomplete","element","id","type","oninput","m","withAttr","noop","stateHooks","component","loadingState","errorState","_hasLifecycleHooks","isActive","errorHandler","bind","_controller","controller","apply","arguments","_onunload","onunload","e","vm","loading","loadingHandler","_view","view","isReady","_init","initArgs","promise","then","ondata","finalArgs","i","length","f","error","items","isOrdered","_items","add","values","values_only","_order","unordered","insertItem","insertAt","ordering","indexOf","ordered","splice","index","iterations","serializeDatetime","serialized","format","deserializeDatetime","deserialized","moment","startsWith","string","beginning","endsWith","tail","UrlConf","_patterns","patterns","prefixPattern","prefix","pattern","replace","include","url","loadingPage","_","getCsrfToken","cookie_name","document","cookie","cookieRegex","RegExp","match","split","Ajax","refreshCsrfToken","csrfToken","CSRF_COOKIE_NAME","runningGets","ajax","method","data","progress","deferred","ajax_settings","headers","X-CSRFToken","dataType","success","resolve","jqXHR","rejection","responseJSON","statusText","reject","$","preloaded","post","patch","put","ALERT_BASE_DISPLAY_TIME","ALERT_LENGTH_FACTOR","ALERT_MAX_DISPLAY_TIME","ALERT_HIDE_ANIMATION_LENGTH","Alert","isVisible","show","displayTime","runloop","runOnce","startComputation","endComputation","set","stop","info","warning","filtersUrl","filters","encodedKey","encodeURIComponent","encodedValue","join","Query","call","path","related","model","relation","endpoint","results","map","models","Api","alert","gettext","Auth","user","deserialize","denyAuthenticated","isAuthenticated","denyAnonymous","isAnonymous","NoCaptcha","load","QACaptcha","question","prop","label","labelClass","controlClass","control","validate","form","isBusy","validation","errors","validationKey","helpText","help_text","validator","ReCaptcha","included","wait","grecaptcha","reset","controlConfig","render","sitekey","settings","recaptcha_site_key","getResponse","clean","captcha","Captcha","types","no","qa","re","captcha_type","_components","argumentsArray","boilerplate","_submit","submit","_success","_error","hasErrors","constructor","_forms","mount","getElementById","script","remote","STATIC_URL","cache","Modal","delegateName","on","hide","off","removeClass","remove","modal","open","_modal","_modals","Models","classes","deserializers","relations","json","locale","attr","Router","baseUrl","staticUrl","mediaUrl","urls","reverses","populatePatterns","urlconf","finalPattern","route","startRouting","mode","delegateElement","cleanUrl","isRelative","substr","location","protocol","host","avatarsUrl","delegateClicks","target","href","preventDefault","prefixUrl","error403","ban","error404","error500","error0","errorPage","router","_hasRouteBoilerplate","loadingView","container","onerror","_routes","RunLoop","_intervals","stopInterval","clearTimeout","run","callable","delay","setTimeout","result","loop","ticks","PageTitle","forum_name","title","_set_complex","completeTitle","page","page_label","interpolate","parent","EMAIL","USERNAME","validators","required","trim","email","minLength","limit_value","returnMessage","ngettext","show_value","maxLength","usernameMinLength","username_length_min","usernameMaxLength","username_length_max","usernameContent","passwordMinLength","password_length_min","validateField","validateForm","isValid","Zxcvbn","scorePassword","password","inputs","zxcvbn","score","Ban","html","plain","expires_on","deserializeBan","class","LegalPage","body","link","User","slug","username","acl","rank","deserializeUser","joined_on","viewModel","param","activateByToken","auth","ctrl","rejected","error_message","help","code","icon","errorBanned","trust","expirationMessage","isAfter","fromNow","forum_index_title","activation","legalPageFactory","typeName","defaultTitle","dashedTypeName","formOptions","requestActivation","completed","onclick","isMenuVisible","forum_footnote","terms_of_service","terms_of_service_link","privacy_policy","privacy_policy_link","footer","nav","legalLink","legalType","menu","branding","onsubmit","header","data-dismiss","aria-label","aria-hidden","refresh","reload","registerComplete","messageHtml","active","inactive","lead","register","footnote","termsUrl","terms","style","signin","activateButton","showActivation","navbar","brand","children","src","alt","showSignIn","showRegister","account_activation","sync","forum_branding_display","forum_branding_text","logout","button","textFields","formGroup","groupClass","controlType","attrs","controlId","feedbackId","feedbackIcon","showFeedbackIcon","isValidated","String","for","labelFor","forumLayout","loader","markup","content","tabindex","aria-labelledby","styles","labels","passwordStrength","role","aria-valuenow","aria-valuemin","aria-valuemax","Register","extend","RequestLink","SignIn","$form","find","val"],"mappings":"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","file":"misago.js","sourcesContent":["/* global -Misago */\n/* exported Misago */\n(function () {\n  'use strict';\n\n  window.Misago = function() {\n    var ns = Object.getPrototypeOf(this);\n    var self = this;\n\n    // Services init/destroy\n    this._initServices = function(services) {\n      var orderedServices = new ns.OrderedList(services).order(false);\n      orderedServices.forEach(function (item) {\n        var factory = null;\n        if (item.item.factory !== undefined) {\n          factory = item.item.factory;\n        } else {\n          factory = item.item;\n        }\n\n        var serviceInstance = factory(self);\n        if (serviceInstance) {\n          self[item.key] = serviceInstance;\n        }\n      });\n    };\n\n    this._destroyServices = function(services) {\n      var orderedServices = new ns.OrderedList(services).order();\n      orderedServices.reverse();\n      orderedServices.forEach(function (item) {\n        if (item.destroy !== undefined) {\n          item.destroy(self);\n        }\n      });\n    };\n\n    // Context data\n    this.context = {\n      // Empty settings\n      SETTINGS: {}\n    };\n\n    // App init/destory\n    this.setup = false;\n    this.init = function(setup, context) {\n      this.setup = {\n        fixture: ns.get(setup, 'fixture', null),\n        test: ns.get(setup, 'test', false),\n        api: ns.get(setup, 'api', '/api/')\n      };\n\n      if (context) {\n        this.context = context;\n      }\n\n      this._initServices(ns._services);\n    };\n\n    this.destroy = function() {\n      this._destroyServices(ns._services);\n    };\n  };\n\n  // Services\n  var proto = window.Misago.prototype;\n\n  proto._services = [];\n  proto.addService = function(name, factory, order) {\n    proto._services.push({\n      key: name,\n      item: factory,\n      after: proto.get(order, 'after'),\n      before: proto.get(order, 'before')\n    });\n  };\n\n  // Exceptions\n  proto.PermissionDenied = function(message) {\n    this.detail = message;\n    this.status = 403;\n\n    this.toString = function() {\n      return this.detail || 'Permission denied';\n    };\n  };\n}());\n\n(function (Misago) {\n  'use strict';\n\n  Misago.has = function(obj, key) {\n    if (obj) {\n      return obj.hasOwnProperty(key);\n    } else {\n      return false;\n    }\n  };\n\n  Misago.get = function(obj, key, value) {\n    if (Misago.has(obj, key)) {\n      return obj[key];\n    } else if (value !== undefined) {\n      return value;\n    } else {\n      return undefined;\n    }\n  };\n\n  Misago.pop = function(obj, key, value) {\n    var returnValue = Misago.get(obj, key, value);\n    if (Misago.has(obj, key)) {\n      obj[key] = null;\n    }\n    return returnValue;\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  function persistent(el, isInit, context) {\n    context.retain = true;\n  }\n\n  Misago.input = function(kwargs) {\n    var options = {\n      disabled: kwargs.disabled || false,\n      config: kwargs.config || persistent\n    };\n\n    if (kwargs.placeholder) {\n      options.placeholder = kwargs.placeholder;\n    }\n\n    if (kwargs.autocomplete === false) {\n      options.autocomplete = 'off';\n    }\n\n    var element = 'input';\n\n    if (kwargs.id) {\n      element += '#' + kwargs.id;\n      options.key = 'field-' + kwargs.id;\n    }\n\n    element += '.form-control' + (kwargs.class || '');\n    element += '[type=\"' + (kwargs.type || 'text') + '\"]';\n\n    if (kwargs.value) {\n      options.value = kwargs.value();\n      options.oninput = m.withAttr('value', kwargs.value);\n    }\n\n    return m(element, options);\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var noop = function() {};\n\n  Misago.stateHooks = function(component, loadingState, errorState) {\n    /*\n      Boilerplate for Misago components with lifecycles\n    */\n\n    // Component boilerplated (this may happen in tests)\n    if (component._hasLifecycleHooks) {\n      return component;\n    }\n    component._hasLifecycleHooks = true;\n\n    // Component active state\n    component.isActive = true;\n\n    var errorHandler = errorState.bind(component);\n\n    // Wrap controller to store lifecycle methods\n    var _controller = component.controller || noop;\n    component.controller = function() {\n      try {\n        component.isActive = true;\n        var controller = _controller.apply(component, arguments) || {};\n\n        // wrap onunload for lifestate\n        var _onunload = controller.onunload || noop;\n        controller.onunload = function() {\n          _onunload.apply(component, arguments);\n          component.isActive = false;\n        };\n\n        return controller;\n      } catch (e) {\n        errorHandler(e);\n      }\n    };\n\n    // Add state callbacks to View-Model\n    if (component.vm && component.vm.init) {\n      // setup default loading view\n      if (!component.loading) {\n        var loadingHandler = loadingState.bind(component);\n        component.loading = loadingHandler;\n      }\n\n      var _view = component.view;\n      component.view = function() {\n        if (component.vm.isReady) {\n          return _view.apply(component, arguments);\n        } else {\n          return component.loading.apply(component, arguments);\n        }\n      };\n\n      // wrap vm.init in promise handler\n      var _init = component.vm.init;\n      component.vm.init = function() {\n        var initArgs = arguments;\n        var promise = _init.apply(component.vm, initArgs);\n\n        if (promise) {\n          promise.then(function() {\n            if (component.isActive && component.vm.ondata) {\n              var finalArgs = [];\n              for (var i = 0; i < arguments.length; i++) {\n                finalArgs.push(arguments[i]);\n              }\n              for (var f = 0; f < initArgs.length; f++) {\n                finalArgs.push(initArgs[f]);\n              }\n\n              component.vm.ondata.apply(component.vm, finalArgs);\n            }\n          }, function(error) {\n            if (component.isActive) {\n              errorHandler(error);\n            }\n          });\n        }\n      };\n    }\n\n    return component;\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.OrderedList = function(items) {\n    this.isOrdered = false;\n    this._items = items || [];\n\n    this.add = function(key, item, order) {\n      this._items.push({\n        key: key,\n        item: item,\n        after: Misago.get(order, 'after'),\n        before: Misago.get(order, 'before')\n      });\n    };\n\n    this.get = function(key, value) {\n      for (var i = 0; i < this._items.length; i++) {\n        if (this._items[i].key === key) {\n          return this._items[i].item;\n        }\n      }\n\n      return value;\n    };\n\n    this.has = function(key) {\n      return this.get(key) !== undefined;\n    };\n\n    this.values = function() {\n      var values = [];\n      for (var i = 0; i < this._items.length; i++) {\n        values.push(this._items[i].item);\n      }\n      return values;\n    };\n\n    this.order = function(values_only) {\n      if (!this.isOrdered) {\n        this._items = this._order(this._items);\n        this.isOrdered = true;\n      }\n\n      if (values_only || typeof values_only === 'undefined') {\n        return this.values();\n      } else {\n        return this._items;\n      }\n    };\n\n    this._order = function(unordered) {\n      // Index of unordered items\n      var index = [];\n      unordered.forEach(function (item) {\n        index.push(item.key);\n      });\n\n      // Ordered items\n      var ordered = [];\n      var ordering = [];\n\n      // First pass: register items that\n      // don't specify their order\n      unordered.forEach(function (item) {\n        if (!item.after && !item.before) {\n          ordered.push(item);\n          ordering.push(item.key);\n        }\n      });\n\n      // Second pass: register items that\n      // specify their before to \"_end\"\n      unordered.forEach(function (item) {\n        if (item.before === \"_end\") {\n          ordered.push(item);\n          ordering.push(item.key);\n        }\n      });\n\n      // Third pass: keep iterating items\n      // until we hit iterations limit or finish\n      // ordering list\n      function insertItem(item) {\n        var insertAt = -1;\n        if (ordering.indexOf(item.key) === -1) {\n          if (item.after) {\n            insertAt = ordering.indexOf(item.after);\n            if (insertAt !== -1) {\n              insertAt += 1;\n            }\n          } else if (item.before) {\n            insertAt = ordering.indexOf(item.before);\n          }\n\n          if (insertAt !== -1) {\n            ordered.splice(insertAt, 0, item);\n            ordering.splice(insertAt, 0, item.key);\n          }\n        }\n      }\n\n      var iterations = 200;\n      while (iterations > 0 && index.length !== ordering.length) {\n        iterations -= 1;\n        unordered.forEach(insertItem);\n      }\n\n      return ordered;\n    };\n  };\n} (Misago.prototype));\n\n(function (Misago) {\n  Misago.serializeDatetime = function(serialized) {\n    return serialized ? serialized.format() : null;\n  };\n\n  Misago.deserializeDatetime = function(deserialized) {\n    return deserialized ? moment(deserialized) : null;\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.startsWith = function(string, beginning) {\n    return string.indexOf(beginning) === 0;\n  };\n\n  Misago.endsWith = function(string, tail) {\n    return string.indexOf(tail, string.length - tail.length) !== -1;\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.UrlConf = function() {\n    var self = this;\n    this._patterns = [];\n\n    this.patterns = function() {\n      return this._patterns;\n    };\n\n    var prefixPattern = function(prefix, pattern) {\n      return (prefix + pattern).replace('//', '/');\n    };\n\n    var include = function(prefix, patterns) {\n      for (var i = 0; i < patterns.length; i ++) {\n        self.url(prefixPattern(prefix, patterns[i].pattern),\n                 patterns[i].component,\n                 patterns[i].name);\n      }\n    };\n\n    this.url = function(pattern, component, name) {\n      if (pattern === '') {\n        pattern = '/';\n      }\n\n      if (component instanceof Misago.UrlConf) {\n        include(pattern, component.patterns());\n      } else {\n        this._patterns.push({\n          pattern: pattern,\n          component: component.replace(/_/g, '-'),\n          name: name || component\n        });\n      }\n    };\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.loadingPage = function(_) {\n    return m('.page.page-loading',\n      _.component('loader')\n    );\n  };\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var getCsrfToken = function(cookie_name) {\n    if (document.cookie.indexOf(cookie_name) !== -1) {\n      var cookieRegex = new RegExp(cookie_name + '\\=([^;]*)');\n      var cookie = Misago.get(document.cookie.match(cookieRegex), 0);\n      return cookie.split('=')[1];\n    } else {\n      return null;\n    }\n  };\n\n  var Ajax = function(_) {\n    this.refreshCsrfToken = function() {\n      this.csrfToken = getCsrfToken(_.context.CSRF_COOKIE_NAME);\n    };\n    this.refreshCsrfToken();\n\n    /*\n      List of GETs underway\n      We are limiting number of GETs to API to 1 per url\n    */\n    var runningGets = {};\n\n    this.ajax = function(method, url, data, progress) {\n      var promise = m.deferred();\n\n      var ajax_settings = {\n        url: url,\n        method: method,\n        headers: {\n          'X-CSRFToken': this.csrfToken\n        },\n\n        data: data || {},\n        dataType: 'json',\n\n        success: function(data) {\n          if (method === 'GET') {\n            Misago.pop(runningGets, url);\n          }\n          promise.resolve(data);\n        },\n        error: function(jqXHR) {\n          if (method === 'GET') {\n            Misago.pop(runningGets, url);\n          }\n\n          var rejection = jqXHR.responseJSON || {};\n\n          rejection.status = jqXHR.status;\n          rejection.statusText = jqXHR.statusText;\n\n          promise.reject(rejection);\n        }\n      };\n\n      if (progress) {\n        return; // not implemented... yet!\n      }\n\n      $.ajax(ajax_settings);\n      return promise.promise;\n    };\n\n    this.get = function(url) {\n      var preloaded = Misago.pop(_.context, url);\n      if (preloaded) {\n        var deferred = m.deferred();\n        deferred.resolve(preloaded);\n        return deferred.promise;\n      } else if (runningGets[url] !== undefined) {\n        return runningGets[url];\n      } else {\n        runningGets[url] = this.ajax('GET', url);\n        return runningGets[url];\n      }\n    };\n\n    this.post = function(url, data) {\n      return this.ajax('POST', url, data);\n    };\n\n    this.patch = function(url, data) {\n      return this.ajax('PATCH', url, data);\n    };\n\n    this.put = function(url, data) {\n      return this.ajax('PUT', url, data);\n    };\n\n    this.delete = function(url) {\n      return this.ajax('DELETE', url);\n    };\n  };\n\n  Misago.addService('ajax', function(_) {\n    return new Ajax(_);\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var ALERT_BASE_DISPLAY_TIME = 5 * 1000;\n  var ALERT_LENGTH_FACTOR = 70;\n  var ALERT_MAX_DISPLAY_TIME = 9 * 1000;\n  var ALERT_HIDE_ANIMATION_LENGTH = 300;\n\n  var Alert = function(_) {\n    var self = this;\n\n    this.type = 'info';\n    this.message = null;\n    this.isVisible = false;\n\n    var show = function(type, message) {\n      self.type = type;\n      self.message = message;\n      self.isVisible = true;\n\n      var displayTime = ALERT_BASE_DISPLAY_TIME;\n      displayTime += message.length * ALERT_LENGTH_FACTOR;\n      if (displayTime > ALERT_MAX_DISPLAY_TIME) {\n        displayTime = ALERT_MAX_DISPLAY_TIME;\n      }\n\n      _.runloop.runOnce(function () {\n        m.startComputation();\n        self.isVisible = false;\n        m.endComputation();\n      }, 'flash-message-hide', displayTime);\n    };\n\n    var set = function(type, message) {\n      _.runloop.stop('flash-message-hide');\n      _.runloop.stop('flash-message-show');\n\n      if (self.isVisible) {\n        self.isVisible = false;\n        _.runloop.runOnce(function () {\n          m.startComputation();\n          show(type, message);\n          m.endComputation();\n        }, 'flash-message-show', ALERT_HIDE_ANIMATION_LENGTH);\n      } else {\n        show(type, message);\n      }\n    };\n\n    this.info = function(message) {\n      set('info', message);\n    };\n\n    this.success = function(message) {\n      set('success', message);\n    };\n\n    this.warning = function(message) {\n      set('warning', message);\n    };\n\n    this.error = function(message) {\n      set('error', message);\n    };\n  };\n\n  Misago.addService('alert', {\n    factory: function(_) {\n      return new Alert(_);\n    }\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var filtersUrl = function(filters) {\n    if (typeof filters === 'object') {\n      var values = [];\n      for (var key in filters) {\n        if (filters.hasOwnProperty(key)) {\n          var encodedKey = encodeURIComponent(key);\n          var encodedValue = encodeURIComponent(filters[key]);\n          values.push(encodedKey + '=' + encodedValue);\n        }\n      }\n      return '?' + values.join('&');\n    } else {\n      return filters + '/';\n    }\n  };\n\n  var Query = function(_, call) {\n    this.url = call.url || _.setup.api;\n\n    if (call.path) {\n      this.url += call.path + '/';\n    } else if (call.related) {\n      this.url += call.related + '/';\n    } else {\n      this.url += call.model + 's' + '/';\n    }\n\n    if (call.filters) {\n      this.url += filtersUrl(call.filters);\n    }\n\n    if (call.model) {\n      this.related = function(model, filters) {\n        return new Query(_, {\n          url: this.url,\n          relation: call.model,\n          related: model,\n          filters: filters,\n        });\n      };\n    }\n\n    this.endpoint = function(path, filters) {\n      return new Query(_, {\n        url: this.url,\n        path: path,\n        filters: filters\n      });\n    };\n\n    this.get = function() {\n      var model = null;\n      if (call.related) {\n        model = call.relation + ':' + call.related;\n      } else if (call.model) {\n        model = call.model;\n      }\n\n      return _.ajax.get(this.url).then(function(data) {\n        if (model) {\n          if (data.results) {\n            data.results.map(function(item) {\n              return _.models.new(model, item);\n            });\n            return data;\n          } else {\n            return _.models.new(model, data);\n          }\n        } else {\n          return data;\n        }\n      });\n    };\n\n    this.post = function(data) {\n      return _.ajax.post(this.url, data);\n    };\n\n    this.patch = function(data) {\n      return _.ajax.patch(this.url, data);\n    };\n\n    this.put = function(data) {\n      return _.ajax.put(this.url, data);\n    };\n\n    this.delete = function() {\n      return _.ajax.delete(this.url);\n    };\n\n    // shortcut for get()\n    this.then = function(resolve, reject) {\n      return this.get().then(resolve, reject);\n    };\n  };\n\n  var Api = function(_) {\n    this.model = function(model, filters) {\n      return new Query(_, {\n        model: model,\n        filters: filters,\n      });\n    };\n\n    this.endpoint = function(path, filters) {\n      return new Query(_, {\n        path: path,\n        filters: filters\n      });\n    };\n\n    this.alert = function(rejection) {\n      // Shorthand for API errors\n      var message = gettext(\"Unknown error has occured.\");\n\n      if (rejection.status === 0) {\n        message = gettext(\"Lost connection with application.\");\n      }\n\n      if (rejection.status === 403) {\n        message = rejection.detail;\n        if (message === \"Permission denied\") {\n          message = gettext(\n            \"You don't have permission to perform this action.\");\n        }\n      }\n\n      if (rejection.status === 404) {\n        message = gettext(\"Action link is invalid.\");\n      }\n\n      _.alert.error(message);\n    };\n  };\n\n  Misago.addService('api', function(_) {\n    return new Api(_);\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Auth = function(_) {\n    _.user = _.models.deserialize('user', _.context.user);\n\n    // Access controls\n    this.denyAuthenticated = function(message) {\n      if (_.user.isAuthenticated) {\n        throw new Misago.PermissionDenied(\n          message || gettext(\"This page is not available to signed in users.\"));\n      }\n    };\n\n    this.denyAnonymous = function(message) {\n      if (_.user.isAnonymous) {\n        throw new Misago.PermissionDenied(\n          message || gettext(\"This page is not available to guests.\"));\n      }\n    };\n  };\n\n  Misago.addService('auth', function(_) {\n    return new Auth(_);\n  },\n  {\n    after: 'model:user'\n  });\n}(Misago.prototype));\n\n/* global grecaptcha */\n(function (Misago) {\n  'use strict';\n\n  var NoCaptcha = function() {\n    var deferred = m.deferred();\n    deferred.resolve();\n\n    this.load = function() {\n      return deferred.promise;\n    };\n\n    this.value = function() {\n      return null;\n    };\n  };\n\n  var QACaptcha = function(_) {\n    var self = this;\n\n    this.loading = false;\n    this.question = null;\n    this.value = m.prop('');\n\n    var deferred = m.deferred();\n    this.load = function() {\n      this.value('');\n\n      if (!this.question && !this.loading) {\n        this.loading = true;\n\n        _.api.endpoint('captcha-question').get().then(function(question) {\n          self.question = question;\n          deferred.resolve();\n        }, function() {\n          _.api.alert(gettext('Failed to load CAPTCHA.'));\n          deferred.reject();\n        }).then(function() {\n          self.loading = true;\n        });\n      }\n\n      return deferred.promise;\n    };\n\n    this.component = function(kwargs) {\n      return _.component('form-group', {\n        label: this.question.question,\n        labelClass: kwargs.labelClass || null,\n        controlClass: kwargs.controlClass || null,\n        control: _.input({\n          value: _.validate(kwargs.form, 'captcha'),\n          id: 'id_captcha',\n          disabled: kwargs.form.isBusy\n        }),\n        validation: kwargs.form.errors,\n        validationKey: 'captcha',\n        helpText: this.question.help_text\n      });\n    };\n\n    this.validator = function() {\n      return [];\n    };\n  };\n\n  var ReCaptcha = function(_) {\n    this.included = false;\n    this.question = null;\n\n    var deferred = m.deferred();\n\n    var wait = function(promise) {\n      if (typeof grecaptcha !== \"undefined\") {\n        promise.resolve();\n      } else {\n        _.runloop.runOnce(function() {\n          wait(promise);\n        }, 'loading-grecaptcha', 150);\n      }\n    };\n\n    this.load = function() {\n      if (typeof grecaptcha !== \"undefined\") {\n        grecaptcha.reset();\n      }\n\n      if (!this.included) {\n        _.include('https://www.google.com/recaptcha/api.js', true);\n        this.included = true;\n      }\n\n      wait(deferred);\n\n      return deferred.promise;\n    };\n\n    var controlConfig = function(el, isInit, context) {\n      context.retain = true;\n\n      if (!isInit) {\n        grecaptcha.render('recaptcha', {\n          'sitekey': _.settings.recaptcha_site_key\n        });\n      }\n    };\n\n    this.component = function(kwargs) {\n      var control = m('#recaptcha', {\n        config: controlConfig\n      });\n\n      return _.component('form-group', {\n        label: gettext(\"Security test\"),\n        labelClass: kwargs.labelClass || null,\n        controlClass: kwargs.controlClass || null,\n        control: control,\n        validation: kwargs.form.errors,\n        validationKey: 'captcha'\n      });\n    };\n\n    this.value = function() {\n      if (typeof grecaptcha !== \"undefined\") {\n        return grecaptcha.getResponse();\n      } else {\n        return '';\n      }\n    };\n\n    this.clean = function(form) {\n      if (!this.value()) {\n        form.errors.captcha = [\n          gettext('This field is required.')\n        ];\n      } else {\n        form.errors.captcha = true;\n      }\n    };\n\n    this.validator = function() {\n      return [];\n    };\n  };\n\n  var Captcha = function(_) {\n    var types = {\n      'no': NoCaptcha,\n      'qa': QACaptcha,\n      're': ReCaptcha\n    };\n\n    var captcha = new types[_.settings.captcha_type](_);\n\n    this.value = captcha.value;\n\n    this.load = function() {\n      return captcha.load();\n    };\n\n    this.component = function(kwargs) {\n      if (captcha.component) {\n        return captcha.component(kwargs);\n      } else {\n        return null;\n      }\n    };\n\n    this.validator = function() {\n      if (captcha.validator) {\n        return captcha.validator();\n      } else {\n        return null;\n      }\n    };\n\n    this.clean = function(form) {\n      if (captcha.clean) {\n        captcha.clean(form);\n      } else {\n        form.errors.captcha = true;\n      }\n    };\n  };\n\n  Misago.addService('captcha', function(_) {\n    return new Captcha(_);\n  },\n  {\n    after: 'include'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var component = function(name, component) {\n    if (this._components[name]) {\n      if (arguments.length > 1) {\n        var argumentsArray = [this._components[name]];\n        for (var i = 1; i < arguments.length; i += 1) {\n          argumentsArray.push(arguments[i]);\n        }\n        argumentsArray.push(this);\n        return m.component.apply(undefined, argumentsArray);\n      } else {\n        return m.component(this._components[name], this);\n      }\n    } else if (component) {\n      this._components[name] = component;\n    } else {\n      throw '\"' + name + '\" component is not registered and can\\'t be created';\n    }\n  };\n\n  Misago.addService('components', function(_) {\n    _._components = {};\n    _.component = component;\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.addService('conf', function(_) {\n    _.settings = Misago.get(_.context, 'SETTINGS', {});\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var boilerplate = function(form) {\n    var _submit = form.submit;\n    var _success = form.success;\n    var _error = form.error;\n\n    form.isBusy = false;\n\n    form.errors = null;\n\n    form.submit = function() {\n      if (form.isBusy) {\n        return false;\n      }\n\n      if (form.clean) {\n        if (form.clean()) {\n          form.isBusy = true;\n          _submit.apply(form);\n        }\n      } else {\n        form.isBusy = true;\n      }\n      return false;\n    };\n\n    form.success = function() {\n      m.startComputation();\n\n      _success.apply(form, arguments);\n      form.isBusy = false;\n\n      m.endComputation();\n    };\n\n    form.error = function() {\n      m.startComputation();\n\n      _error.apply(form, arguments);\n      form.isBusy = false;\n\n      m.endComputation();\n    };\n\n    form.hasErrors = function() {\n      if (form.errors === null) {\n        return false;\n      }\n\n      for (var key in form.validation) {\n        if (form.validation.hasOwnProperty(key)) {\n          if (form.errors[key] !== true) {\n            return true;\n          }\n        }\n      }\n\n      return false;\n    };\n\n    return form;\n  };\n\n  var form = function(name, constructor) {\n    if (this._forms[name]) {\n      if (constructor) {\n        return boilerplate(new this._forms[name](constructor, this));\n      } else {\n        return boilerplate(new this._forms[name](this));\n      }\n    } else {\n      this._forms[name] = constructor;\n    }\n  };\n\n  Misago.addService('forms', function(_) {\n    _._forms = {};\n    _.form = form;\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.addService('forum-layout', {\n    factory: function(_) {\n      if (_.setup.fixture) {\n        m.mount(document.getElementById(_.setup.fixture),\n                _.component('forum-layout'));\n      }\n    },\n\n    destroy: function(_) {\n      if (_.setup.fixture) {\n        m.mount(document.getElementById(_.setup.fixture), null);\n      }\n    }\n  },\n  {\n    before: 'start-routing'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var include = function(script, remote) {\n    if (!remote) {\n      script = this.context.STATIC_URL + script;\n    }\n\n    $.ajax({\n      url: script,\n      cache: true,\n      dataType: 'script'\n    });\n  };\n\n  Misago.addService('include', function(_) {\n    _.include = include;\n  },\n  {\n    after: 'conf'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Modal = function() {\n    var self = this;\n\n    var element = document.getElementById('misago-modal');\n\n    // href clicks within modal should close it\n    var delegateName = 'click.misago-modal';\n    $(element).on(delegateName, 'a', function() {\n      self.hide();\n    });\n\n    this.destroy = function() {\n      $(element).off();\n      $('body').removeClass('modal-open');\n      $('.modal-backdrop').remove();\n    };\n\n    // Open/close modal\n    var modal = $(element).modal({show: false});\n    this.open = false;\n\n    modal.on('hidden.bs.modal', function () {\n      if (self.open) {\n        m.mount(element, null);\n        this.open = false;\n      }\n    });\n\n    this.show = function(component) {\n      this.open = true;\n      m.mount(element, component);\n      modal.modal('show');\n    };\n\n    this.hide = function() {\n      modal.modal('hide');\n    };\n  };\n\n  Misago.addService('_modal', {\n    factory: function() {\n      return new Modal();\n    },\n    destroy: function(_) {\n      _._modal.destroy();\n    }\n  },\n  {\n    after: 'start-routing'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var modal = function(name, component) {\n    if (this._modals[name]) {\n      var argumentsArray = [this._modals[name]];\n      for (var i = 1; i < arguments.length; i += 1) {\n        argumentsArray.push(arguments[i]);\n      }\n      argumentsArray.push(this);\n      this._modal.show(m.component.apply(m, argumentsArray));\n    } else if (name) {\n      this._modals[name] = component;\n    } else {\n      this._modal.hide();\n    }\n  };\n\n  Misago.addService('modals', function(_) {\n    _._modals = {};\n    _.modal = modal;\n  },\n  {\n    after: '_modal'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Models = function() {\n    this.classes = {};\n    this.deserializers = {};\n    this.relations = {};\n\n    this.add = function(name, kwargs) {\n      if (kwargs.class) {\n        this.classes[name] = kwargs.class;\n      }\n\n      if (kwargs.deserialize) {\n        this.deserializers[name] = kwargs.deserialize;\n      }\n\n      if (kwargs.relations) {\n        for (var key in kwargs.relations) {\n          if (kwargs.relations.hasOwnProperty(key)) {\n            this.relations[name + ':' + key] = kwargs.relations[key];\n          }\n        }\n      }\n    };\n\n    this.new = function(name, data) {\n      if (this.classes[name]) {\n        return new this.classes[name](data);\n      } else {\n        return data;\n      }\n    };\n\n    this.deserialize = function(name, json) {\n      if (this.relations[name]) {\n        name = this.relations[name];\n      }\n\n      if (this.deserializers[name]) {\n        return this.new(name, this.deserializers[name](json, this));\n      } else {\n        return this.new(name, json);\n      }\n    };\n  };\n\n  Misago.addService('models', function() {\n    return new Models();\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.addService('set-momentjs-locale', function() {\n    moment.locale($('html').attr('lang'));\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Router = function(_) {\n    var self = this;\n    this.baseUrl = $('base').attr('href');\n\n    var staticUrl = Misago.get(_.context, 'STATIC_URL', '/');\n    var mediaUrl = Misago.get(_.context, 'MEDIA_URL', '/');\n\n    // Routing\n    this.urls = {};\n    this.reverses = {};\n\n    var populatePatterns = function(urlconf) {\n      urlconf.patterns().forEach(function(url) {\n        var finalPattern = self.baseUrl + url.pattern;\n        finalPattern = finalPattern.replace('//', '/');\n\n        self.urls[finalPattern] = _.route(url.component);\n        self.reverses[url.name] = finalPattern;\n      });\n    };\n\n    this.startRouting = function(urlconf, fixture) {\n      populatePatterns(urlconf);\n      this.fixture = fixture;\n\n      if (_.setup.test) {\n        m.route.mode = 'search';\n      } else {\n        m.route.mode = 'pathname';\n      }\n\n      m.route(fixture, '/', this.urls);\n    };\n\n    this.url = function(name) {\n      return this.reverses[name];\n    };\n\n    this.route = function(url) {\n      m.route(url);\n    };\n\n    // Delegate clicks\n    this.delegateElement = null;\n\n    this.cleanUrl = function(url) {\n      if (!url) { return; }\n\n      // Is link relative?\n      var isRelative = url.substr(0, 1) === '/' && url.substr(0, 2) !== '//';\n\n      // If link contains host, validate to see if its outgoing\n      if (!isRelative) {\n        var location = window.location;\n\n        // If protocol matches current one, strip it from string\n        // otherwhise stop handler\n        if (url.substr(0, 2) !== '//') {\n          var protocol = url.substr(0, location.protocol.length + 2);\n          if (protocol !== location.protocol + '//') { return; }\n          url = url.substr(location.protocol.length + 2);\n        } else {\n          url = url.substr(2);\n        }\n\n        // Host checks out?\n        if (url.substr(0, location.host.length) !== location.host) { return; }\n        url = url.substr(location.host.length);\n      }\n\n      // Is link within Ember app?\n      if (url.substr(0, this.baseUrl.length) !== this.baseUrl) { return; }\n\n      // Is link to media/static/avatar server?\n      if (url.substr(0, staticUrl.length) === staticUrl) { return; }\n\n      if (url.substr(0, mediaUrl.length) === mediaUrl) { return; }\n\n      var avatarsUrl = '/user-avatar/';\n      if (url.substr(0, avatarsUrl.length) === avatarsUrl) { return; }\n\n      return url;\n    };\n\n    var delegateName = 'click.misago-router';\n    this.delegateClicks = function(element) {\n      this.delegateElement = element;\n      $(this.delegateElement).on(delegateName, 'a', function(e) {\n        var cleanUrl = self.cleanUrl(e.target.href);\n        if (cleanUrl) {\n          if (cleanUrl != m.route()) {\n            self.route(cleanUrl);\n          }\n          e.preventDefault();\n        }\n      });\n    };\n\n    this.destroy = function() {\n      $(this.delegateElement).off(delegateName);\n    };\n\n    // Media/Static url\n    var prefixUrl = function(prefix) {\n      return function(url) {\n        return prefix + url;\n      };\n    };\n\n    this.staticUrl = prefixUrl(staticUrl);\n    this.mediaUrl = prefixUrl(mediaUrl);\n\n    // Errors\n    this.error403 = function(error) {\n      var component = null;\n      if (error.ban) {\n        component = _.route('error:banned',\n          error.detail,\n          _.models.deserialize('ban', error.ban));\n      } else {\n        component = _.route('error:403', error.detail);\n      }\n      m.mount(this.fixture, component);\n    };\n\n    this.error404 = function() {\n      m.mount(this.fixture, _.route('error:404'));\n    };\n\n    this.error500 = function() {\n      m.mount(this.fixture, _.route('error:500'));\n    };\n\n    this.error0 = function() {\n      m.mount(this.fixture, _.route('error:0'));\n    };\n\n    this.errorPage = function(error) {\n      if (error.status === 0) {\n        this.error0();\n      }\n\n      if (error.status === 500) {\n        this.error500();\n      }\n\n      if (error.status === 404) {\n        this.error404();\n      }\n\n      if (error.status === 403) {\n        this.error403(error);\n      }\n    };\n  };\n\n  Misago.addService('router', function(_) {\n    return new Router(_);\n  });\n\n  Misago.addService('start-routing', function(_) {\n    _.router.startRouting(\n      Misago.urls, document.getElementById('router-fixture'));\n    _.router.delegateClicks(document.getElementById(_.setup.fixture));\n  },\n  {\n    before: '_end'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var boilerplate = function(component) {\n    // Component already boilerplated (this may happen in tests)\n    if (component._hasRouteBoilerplate) {\n      return component;\n    }\n    component._hasRouteBoilerplate = true;\n\n    // Add lifecycle hooks\n    var loadingView = function () {\n      var _ = this.container;\n      return m('.page.page-loading',\n        _.component('loader')\n      );\n    };\n\n    var errorHandler = function(error) {\n      if (this.isActive && error.status) {\n        if (this.vm && this.vm.onerror) {\n          this.vm.onerror(error, this.container);\n        } else {\n          this.container.router.errorPage(error);\n        }\n      } else {\n        throw error;\n      }\n    };\n\n    return Misago.stateHooks(component, loadingView, errorHandler);\n  };\n\n  Misago.addService('routes', function(_) {\n    _._routes = {};\n    _.route = function(name, component) {\n      if (this._routes[name]) {\n        if (arguments.length > 1) {\n          var argumentsArray = [this._routes[name]];\n          for (var i = 1; i < arguments.length; i += 1) {\n            argumentsArray.push(arguments[i]);\n          }\n          argumentsArray.push(this);\n          return m.component.apply(undefined, argumentsArray);\n        } else {\n          return m.component(this._routes[name], this);\n        }\n      } else if (component) {\n        component.container = _;\n        this._routes[name] = boilerplate(component);\n      } else {\n        throw '\"' + name + '\" route is not registered and can\\'t be created';\n      }\n    };\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var RunLoop = function(_) {\n    var self = this;\n\n    this._intervals = {};\n\n    var stopInterval = function(name) {\n      if (self._intervals[name]) {\n        window.clearTimeout(self._intervals[name]);\n        self._intervals[name] = null;\n      }\n    };\n\n    this.run = function(callable, name, delay) {\n      this._intervals[name] = window.setTimeout(function() {\n        stopInterval(name);\n        var result = callable(_);\n        if (result !== false) {\n          self.run(callable, name, delay);\n        }\n      }, delay);\n    };\n\n    this.runOnce = function(callable, name, delay) {\n      this._intervals[name] = window.setTimeout(function() {\n        stopInterval(name);\n        callable(_);\n      }, delay);\n    };\n\n    this.stop = function(name) {\n      for (var loop in this._intervals) {\n        if (!name || name === loop) {\n          stopInterval(loop);\n        }\n      }\n    };\n  };\n\n  Misago.addService('runloop', {\n    factory: function(_) {\n      return new RunLoop(_);\n    },\n\n    destroy: function(_) {\n      _.runloop.stop();\n    }\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  Misago.addService('start-tick', function(_) {\n    var ticks = m.prop();\n\n    _.runloop.run(function() {\n      m.startComputation();\n      // just tick once a minute so stuff gets rerendered\n      ticks(ticks() + 1);\n      // syncing dynamic timestamps, etc ect\n      m.endComputation();\n    }, 'tick', 60000);\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var PageTitle = function(forum_name) {\n    this.set = function(title) {\n      if (title) {\n        this._set_complex(title);\n      } else {\n        document.title = forum_name;\n      }\n    };\n\n    this._set_complex = function(title) {\n      if (typeof title === 'string') {\n        title = {title: title};\n      }\n\n      var completeTitle = title.title;\n\n      if (typeof title.page !== 'undefined' && title.page > 1) {\n        var page_label = interpolate(\n          gettext('page %(page)s'), { page:title.page }, true);\n        completeTitle += ' (' + page_label + ')';\n      }\n\n      if (typeof title.parent !== 'undefined') {\n        completeTitle += ' | ' + title.parent;\n      }\n\n      document.title = completeTitle + ' | ' + forum_name;\n    };\n  };\n\n  Misago.addService('page-title', function(_) {\n    _.title = new PageTitle(_.settings.forum_name);\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var EMAIL = /^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$/i;\n  var USERNAME = new RegExp('^[0-9a-z]+$', 'i');\n\n  // Validators namespace\n  Misago.validators = {\n    required: function() {\n      return function(value) {\n        if ($.trim(value).length === 0) {\n          return gettext(\"This field is required.\");\n        }\n      };\n    },\n    email: function(message) {\n      return function(value) {\n        if (!EMAIL.test(value)) {\n          return message || gettext(\"Enter a valid email address.\");\n        }\n      };\n    },\n    minLength: function(limit_value, message) {\n      return function(value) {\n        var returnMessage = '';\n        var length = $.trim(value).length;\n\n        if (length < limit_value) {\n          if (message) {\n            returnMessage = message(limit_value, length);\n          } else {\n            returnMessage = ngettext(\n              \"Ensure this value has at least %(limit_value)s character (it has %(show_value)s).\",\n              \"Ensure this value has at least %(limit_value)s characters (it has %(show_value)s).\",\n              limit_value);\n          }\n          return interpolate(returnMessage, {\n            limit_value: limit_value,\n            show_value: length\n          }, true);\n        }\n      };\n    },\n    maxLength: function(limit_value, message) {\n      return function(value) {\n        var returnMessage = '';\n        var length = $.trim(value).length;\n\n        if (length > limit_value) {\n          if (message) {\n            returnMessage = message(limit_value, length);\n          } else {\n            returnMessage = ngettext(\n              \"Ensure this value has at most %(limit_value)s character (it has %(show_value)s).\",\n              \"Ensure this value has at most %(limit_value)s characters (it has %(show_value)s).\",\n              limit_value);\n          }\n          return interpolate(returnMessage, {\n            limit_value: limit_value,\n            show_value: length\n          }, true);\n        }\n      };\n    },\n    usernameMinLength: function(settings) {\n      var message = function(limit_value) {\n        return ngettext(\n          \"Username must be at least %(limit_value)s character long.\",\n          \"Username must be at least %(limit_value)s characters long.\",\n          limit_value);\n      };\n      return this.minLength(settings.username_length_min, message);\n    },\n    usernameMaxLength: function(settings) {\n      var message = function(limit_value) {\n        return ngettext(\n          \"Username cannot be longer than %(limit_value)s character.\",\n          \"Username cannot be longer than %(limit_value)s characters.\",\n          limit_value);\n      };\n      return this.maxLength(settings.username_length_max, message);\n    },\n    usernameContent: function() {\n      return function(value) {\n        if (!USERNAME.test($.trim(value))) {\n          return gettext(\"Username can only contain latin alphabet letters and digits.\");\n        }\n      };\n    },\n    passwordMinLength: function(settings) {\n      var message = function(limit_value) {\n        return ngettext(\n          \"Valid password must be at least %(limit_value)s character long.\",\n          \"Valid password must be at least %(limit_value)s characters long.\",\n          limit_value);\n      };\n      return this.minLength(settings.password_length_min, message);\n    }\n  };\n\n  var validateField = function(value, validators) {\n    var result = Misago.validators.required()(value);\n    var errors = [];\n\n    if (result) {\n      return [result];\n    } else {\n      for (var i in validators) {\n        result = validators[i](value);\n\n        if (result) {\n          errors.push(result);\n        }\n      }\n    }\n\n    return errors.length ? errors : true;\n  };\n\n  var validateForm = function(form) {\n    var errors = {};\n    var value = null;\n\n    var isValid = true;\n\n    for (var key in form.validation) {\n      if (form.validation.hasOwnProperty(key)) {\n        value = form[key]();\n        errors[key] = validateField(form[key](), form.validation[key]);\n        if (errors[key] !== true) {\n          isValid = false;\n        }\n      }\n    }\n\n    form.errors = errors;\n    return isValid;\n  };\n\n  var validate = function(form, name) {\n    if (name) {\n      return function(value) {\n        var errors = null;\n        if (typeof value !== 'undefined') {\n          errors = validateField(value, form.validation[name]);\n          if (errors) {\n            if (!form.errors) {\n              form.errors = {};\n            }\n            form.errors[name] = errors;\n          }\n          form[name](value);\n          return form[name](value);\n        } else {\n          return form[name]();\n        }\n      };\n    } else {\n      return validateForm(form);\n    }\n  };\n\n  Misago.addService('validate', {\n    factory: function() {\n      return validate;\n    }\n  });\n}(Misago.prototype));\n\n/* global zxcvbn */\n(function (Misago) {\n  'use strict';\n\n  var Zxcvbn = function(_) {\n    this.included = false;\n\n    this.scorePassword = function(password, inputs) {\n      // 0-4 score, the more the stronger password\n      return zxcvbn(password, inputs).score;\n    };\n\n    // loading\n    this.include = function() {\n      _.include('misago/js/zxcvbn.js');\n      this.included = true;\n    };\n\n    var wait = function(promise) {\n      if (typeof zxcvbn !== \"undefined\") {\n        promise.resolve();\n      } else {\n        _.runloop.runOnce(function() {\n          wait(promise);\n        }, 'loading-zxcvbn', 150);\n      }\n    };\n\n    var deferred = m.deferred();\n    this.load = function() {\n      if (!this.included) {\n        this.include();\n      }\n      wait(deferred);\n      return deferred.promise;\n    };\n  };\n\n  Misago.addService('zxcvbn', function(_) {\n    return new Zxcvbn(_);\n  },\n  {\n    after: 'include'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Ban = function(data) {\n    this.message = {\n      html: data.message.html,\n      plain: data.message.plain,\n    };\n\n    this.expires_on = data.expires_on;\n  };\n\n  var deserializeBan = function(data) {\n    data.expires_on = Misago.deserializeDatetime(data.expires_on);\n\n    return data;\n  };\n\n  Misago.addService('model:ban', function(_) {\n    _.models.add('ban', {\n      class: Ban,\n      deserialize: deserializeBan\n    });\n  },\n  {\n    after: 'models'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var LegalPage = function(data) {\n    this.title = data.title;\n    this.body = data.body;\n    this.link = data.link;\n  };\n\n  Misago.addService('model:legal-page', function(_) {\n    _.models.add('legal-page', {\n      class: LegalPage\n    });\n  },\n  {\n    after: 'models'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var User = function(data) {\n    this.id = data.id;\n\n    this.isAuthenticated = !!this.id;\n    this.isAnonymous = !this.isAuthenticated;\n\n    this.slug = data.slug;\n    this.username = data.username;\n\n    this.acl = data.acl;\n    this.rank = data.rank;\n  };\n\n  var deserializeUser = function(data) {\n    if (data.joined_on) {\n      data.joined_on = Misago.deserializeDatetime(data.joined_on);\n    }\n\n    return data;\n  };\n\n  Misago.addService('model:user', function(_) {\n    _.models.add('user', {\n      class: User,\n      deserialize: deserializeUser\n    });\n  },\n  {\n    after: 'models'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var viewModel = {\n    error: null,\n    username: null,\n    isReady: false,\n    init: function(_) {\n      this.error = null;\n      this.user = null;\n      this.isReady = false;\n\n      var endpoint = _.api.endpoint('auth').endpoint('activate-account');\n      endpoint = endpoint.endpoint(m.route.param('user_id'));\n      endpoint = endpoint.endpoint(m.route.param('token'));\n\n      return endpoint.post();\n    },\n    ondata: function(data, _) {\n      m.startComputation();\n\n      _.title.set(gettext(\"Account activated\"));\n\n      this.username = data.username;\n      this.isReady = true;\n\n      m.endComputation();\n    },\n    onerror: function(error, _) {\n      if (error.status === 400) {\n        m.startComputation();\n\n        this.error = error;\n        this.isReady = true;\n\n        m.endComputation();\n      } else {\n        _.router.errorPage(error);\n      }\n    }\n  };\n\n  var activateByToken = {\n    controller: function(_) {\n      _.auth.denyAuthenticated(\n        gettext(\"You have to be signed out to activate account.\"));\n\n      _.title.set(gettext(\"Account activation\"));\n      this.vm.init(_);\n    },\n    vm: viewModel,\n    view: function(ctrl, _) {\n      if (this.vm.error) {\n        return this.rejected(this.vm.error, _);\n      } else {\n        return this.success(this.vm.username, _);\n      }\n    },\n    success: function(username) {\n      var message = gettext('%(username)s, your account has been successfully activated!');\n\n      return m('.page.page-message.page-message-success',\n        m('.container',\n          m('.message-panel', [\n            m('.message-icon',\n              m('span.material-icon', 'check')\n            ),\n            m('.message-body', [\n              m('p.lead',\n                interpolate(message, {\n                  username: username\n                }, true)\n              ),\n              m('p',\n                gettext('You can now sign in to finish setting up your account and to participate in or start new discussions.')\n              )\n            ])\n          ])\n        )\n      );\n    },\n    rejected: function(error) {\n      return m('.page.page-message.page-message-info',\n        m('.container',\n          m('.message-panel', [\n            m('.message-icon',\n              m('span.material-icon', 'info_outline')\n            ),\n            m('.message-body', [\n              m('p.lead',\n                gettext(\"Your account can't be activated at this time.\")\n              ),\n              m('p',\n                error.detail\n              )\n            ])\n          ])\n        )\n      );\n    },\n    loading: function(ctrl, _) {\n      return m('.page.page-loading', [\n        _.component('loader'),\n        m('p.lead', gettext(\"Activating account...\"))\n      ]);\n    }\n  };\n\n  Misago.addService('route:activate-by-token', function(_) {\n    _.route('activate-by-token', activateByToken);\n  },\n  {\n    after: 'routes'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var errorPage = function(error) {\n    var error_message = [\n      m('p.lead', error.message)\n    ];\n\n    if (error.help) {\n      error_message.push(m('p.help', error.help));\n    }\n\n    return m('.page.page-error.page-error-' + error.code,\n      m('.container',\n        m('.message-panel', [\n          m('.message-icon',\n            m('span.material-icon', error.icon)\n          ),\n          m('.message-body', error_message)\n        ])\n      )\n    );\n  };\n\n  var errorBanned = {\n    controller: function() {\n      this.container.title.set(gettext('You are banned'));\n    },\n    view: function(ctrl, message, ban) {\n      var error_message = [];\n\n      if (ban.message.html) {\n        error_message.push(m('.lead', m.trust(ban.message.html)));\n      } else if (message) {\n        error_message.push(m('p.lead', message));\n      } else {\n        error_message.push(m('p.lead', gettext('You are banned.')));\n      }\n\n      var expirationMessage = null;\n      if (ban.expires_on) {\n        if (ban.expires_on.isAfter(moment())) {\n          expirationMessage = interpolate(\n            gettext('This ban expires %(expires_on)s.'),\n            {'expires_on': ban.expires_on.fromNow()},\n            true);\n        } else {\n          expirationMessage = gettext('This ban has expired.');\n        }\n      } else {\n        expirationMessage = gettext('This ban is permanent.');\n      }\n      error_message.push(m('p', expirationMessage));\n\n      return m('.page.page-error.page-error-banned',\n        m('.container',\n          m('.message-panel', [\n            m('.message-icon',\n              m('span.material-icon', 'highlight_off')\n            ),\n            m('.message-body', error_message)\n          ])\n        )\n      );\n    }\n  };\n\n  var error403 = {\n    controller: function() {\n      this.container.title.set(gettext('Page not available'));\n    },\n    view: function(ctrl, message) {\n      if (message === \"Permission denied\") {\n        message = gettext(\"You don't have permission to access this page.\");\n      }\n\n      return errorPage({\n        code: 403,\n        icon: 'remove_circle_outline',\n        message: gettext(\"This page is not available.\"),\n        help: message\n      });\n    }\n  };\n\n  var error404 = {\n    controller: function() {\n      this.container.title.set(gettext('Page not found'));\n    },\n    view: function() {\n      return errorPage({\n        code: 404,\n        icon: 'info_outline',\n        message: gettext(\"Requested page could not be found.\"),\n        help: gettext(\"The link you followed was incorrect or the page has been moved or deleted.\")\n      });\n    }\n  };\n\n  var error500 = {\n    controller: function() {\n      this.container.title.set(gettext('Application error occured'));\n    },\n    view: function() {\n      return errorPage({\n        code: 500,\n        icon: 'error_outline',\n        message: gettext(\"Requested page could not be displayed due to an error.\"),\n        help: gettext(\"Please try again later or contact site staff if error persists.\")\n      });\n    }\n  };\n\n  var error0 = {\n    controller: function() {\n      this.container.title.set(gettext('Lost connection with application'));\n    },\n    view: function() {\n      return errorPage({\n        code: 0,\n        icon: 'sync_problem',\n        message: gettext(\"Could not connect to application.\"),\n        help: gettext(\"This may be caused by problems with your connection or application server. Please check your internet connection and refresh page if problem persists.\")\n      });\n    }\n  };\n\n  Misago.addService('route:error-pages', function(_) {\n    _.route('error:banned', errorBanned);\n    _.route('error:403', error403);\n    _.route('error:404', error404);\n    _.route('error:500', error500);\n    _.route('error:0', error0);\n  },\n  {\n    after: 'routes'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var index = {\n    controller: function(_) {\n      document.title = _.settings.forum_index_title || _.settings.forum_name;\n\n      return {\n        activation: function() {\n          _.router.url('request_activation');\n        }\n      };\n    },\n    view: function(ctrl, _) {\n      return m('.container', [\n        m('h1', 'Activation'),\n        m('p', 'Test auth blocks'),\n        m('p',\n          m('a', {href: _.router.url('request_activation')},\n            'Request activation.'\n          )\n        )\n      ]);\n    }\n  };\n\n  Misago.addService('route:index', function(_) {\n    _.route('index', index);\n  },\n  {\n    after: 'routes'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var legalPageFactory = function(typeName, defaultTitle) {\n    var dashedTypeName = typeName.replace(/_/g, '-');\n\n    return {\n      controller: function(_) {\n        if (Misago.get(_.settings, typeName + '_link')) {\n          window.location = Misago.get(_.settings, typeName + '_link');\n        } else {\n          this.vm.init(this, _);\n        }\n      },\n      vm: {\n        page: null,\n        isReady: false,\n        init: function(component, _) {\n          if (this.isReady) {\n            _.title.set(this.title);\n          } else {\n            _.title.set();\n            return _.api.model('legal-page', dashedTypeName);\n          }\n        },\n        ondata: function(page, component, _) {\n          m.startComputation();\n\n          if (page.link) {\n            window.location = page.link;\n          } else {\n            page.title = page.title || defaultTitle;\n            this.page = page;\n            this.isReady = true;\n\n            m.endComputation();\n\n            if (component.isActive) {\n              _.title.set(this.page.title);\n            }\n          }\n        }\n      },\n      view: function(ctrl, _) {\n        return m('.page.page-legal.page-legal-' + dashedTypeName, [\n          _.component('header', {title: this.vm.page.title}),\n          m('.container',\n            _.component('markup', this.vm.page.body)\n          )\n        ]);\n      }\n    };\n  };\n\n  Misago.addService('route:legal-pages', function(_) {\n    _.route('terms-of-service', legalPageFactory(\n      'terms_of_service', gettext('Terms of service')));\n    _.route('privacy-policy', legalPageFactory(\n      'privacy_policy', gettext('Privacy policy')));\n  },\n  {\n    after: 'routes'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var formOptions = {\n    endpoint: 'send-activation',\n    user: null,\n\n    success: function(user) {\n      this.user = user;\n    },\n    error: function(rejection, _) {\n      if (rejection.code === 'already_active') {\n        _.alert.info(rejection.detail);\n        _.modal('sign-in');\n      } else if (rejection.code === 'inactive_admin') {\n        _.alert.info(rejection.detail);\n      } else {\n        _.alert.error(rejection.detail);\n      }\n    },\n    reset: function() {\n      this.user = null;\n    }\n  };\n\n  var requestActivation = {\n    controller: function(_) {\n      _.auth.denyAuthenticated(\n        gettext(\"You have to be signed out to activate account.\"));\n\n      _.title.set(gettext(\"Activate your account\"));\n\n      return {\n        form: _.form('request-link', formOptions)\n      };\n    },\n    view: function(ctrl, _) {\n      if (formOptions.user) {\n        return this.completed(ctrl.form, formOptions, _);\n      } else {\n        return this.form(ctrl.form, _);\n      }\n    },\n    completed: function(form, formOptions, _) {\n      var message = gettext(\"%(username)s, we have sent your activation link to %(email)s.\");\n\n      return m('.page.page-message.page-message-success',\n        m('.container',\n          m('.message-panel', [\n            m('.message-icon',\n              m('span.material-icon', 'check')\n            ),\n            m('.message-body', [\n              m('p.lead',\n                gettext(\"Activation link has been sent.\")\n              ),\n              m('p',\n                interpolate(message, {\n                  username: formOptions.user.username,\n                  email: formOptions.user.email\n                }, true)\n              ),\n              m('p',\n                _.component('button', {\n                  class: '.btn-default',\n                  submit: false,\n                  label: gettext(\"Request another link\"),\n                  onclick: form.reset.bind(form)\n                })\n              )\n            ])\n          ])\n        )\n      );\n    },\n    form: function(form, _) {\n      return m('.page.page-request-activation', [\n        _.component('header', {\n          title: gettext(\"Request activation link\")\n        }),\n        m('.container',\n          m('.row', [\n            m('.col-md-8', [\n              m('p',\n                gettext(\"Site administrator may impose requirement on newly regitered accounts to be activated before users will be able to sign in.\")\n              ),\n              m('p',\n                gettext(\"Depending on time of registration, you will be able activate your account by clicking special activation link. This link will be valid only for your browser, for seven days or until your account is activated.\")\n              ),\n              m('p',\n                gettext(\"To receive this link, enter your account's e-mail addres in form and press \\\"Send link\\\" button.\")\n              )\n            ]),\n            m('.col-md-4',\n              _.component('request-link-form', form)\n            )\n          ])\n        )\n      ]);\n    }\n  };\n\n  Misago.addService('route:request-activation', function(_) {\n    _.route('request-activation', requestActivation);\n  },\n  {\n    after: 'routes'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var isMenuVisible = function(settings) {\n    return [\n      !!settings.forum_footnote,\n      !!settings.terms_of_service,\n      !!settings.terms_of_service_link,\n      !!settings.privacy_policy,\n      !!settings.privacy_policy_link\n    ].indexOf(true) !== -1;\n  };\n\n  var footer = {\n    view: function(ctrl, _) {\n      var nav = null;\n      if (isMenuVisible(_.settings)) {\n        nav = _.component('footer:menu');\n      }\n\n      return m('footer.forum-footer', [\n        m('.container',\n          m('.footer-content', [\n            nav,\n            _.component('footer:branding')\n          ])\n        )\n      ]);\n    }\n  };\n\n  Misago.addService('component:footer', function(_) {\n    _.component('footer', footer);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var legalLink = function(_, legalType, defaultTitle) {\n    var url = Misago.get(_.settings, legalType + '_link');\n    if (!url && Misago.get(_.settings, legalType)) {\n      url = _.router.url(legalType);\n    }\n\n    if (url) {\n      return m('li',\n        m('a', {href: url},\n          Misago.get(_.settings, legalType + '_title', defaultTitle)\n        )\n      );\n    } else {\n      return null;\n    }\n  };\n\n  var menu = {\n    isVisible: function(settings) {\n      return [\n        !!settings.forum_footnote,\n        !!settings.terms_of_service,\n        !!settings.terms_of_service_link,\n        !!settings.privacy_policy,\n        !!settings.privacy_policy_link\n      ].indexOf(true) !== -1;\n    },\n    view: function(ctrl, _) {\n      var items = [];\n\n      if (_.settings.forum_footnote) {\n        items.push(m('li.forum-footnote', m.trust(_.settings.forum_footnote)));\n      }\n\n      items.push(\n        legalLink(_, 'terms_of_service', gettext('Terms of service')));\n      items.push(\n        legalLink(_, 'privacy_policy', gettext('Privacy policy')));\n\n      return m('ul.list-inline.footer-nav', items);\n    }\n  };\n\n  Misago.addService('component:footer:menu', function(_) {\n    _.component('footer:menu', menu);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var branding = {\n    view: function() {\n      return m('a.misago-branding[href=http://misago-project.org]', [\n        \"powered by \", m('strong', \"misago\")\n      ]);\n    }\n  };\n\n  Misago.addService('component:footer:branding', function(_) {\n    _.component('footer:branding', branding);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var form = {\n    view: function(ctrl, form, _) {\n      return m('.well.well-form',\n        m('form', {onsubmit: form.submit}, [\n          m('.form-group',\n            m('.control-input',\n              Misago.input({\n                disabled: form.isBusy,\n                value: form.email,\n                placeholder: gettext(\"Your e-mail address\")\n              })\n            )\n          ),\n          _.component('button', {\n            class: '.btn-primary.btn-block',\n            submit: true,\n            loading: form.isBusy,\n            label: gettext(\"Send link\")\n          })\n        ])\n      );\n    }\n  };\n\n  Misago.addService('component:request-link-form', function(_) {\n    _.component('request-link-form', form);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var header = {\n    view: function(ctrl, title) {\n      return m('.modal-header', [\n        m('button.close[type=\"button\"]',\n          {'data-dismiss': 'modal', 'aria-label': gettext('Close')},\n          m('span', {'aria-hidden': 'true'}, m.trust('&times;'))\n        ),\n        m('h4#misago-modal-label.modal-title', title)\n      ]);\n    }\n  };\n\n  Misago.addService('component:modal:header', function(_) {\n    _.component('modal:header', header);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var refresh = function() {\n    document.location.reload();\n  };\n\n  var registerComplete = {\n    controller: function(message, _) {\n      if (message.activation === 'active') {\n        _.runloop.runOnce(\n          refresh, 'refresh-after-registration', 10000);\n      }\n    },\n    view: function(ctrl, message, _) {\n      var messageHtml = null;\n\n      if (message.activation === 'active') {\n        messageHtml = this.active(message);\n      } else {\n        messageHtml = this.inactive(message);\n      }\n\n      return m('.modal-dialog.modal-message.modal-register[role=\"document\"]',\n        {config: persistent},\n        m('.modal-content', [\n          _.component('modal:header', gettext('Registration complete')),\n          m('.modal-body',\n            messageHtml\n          )\n        ])\n      );\n    },\n    active: function(message) {\n      var lead = gettext(\"%(username)s, your account has been created and you were signed in.\");\n      return [\n        m('.message-icon',\n          m('span.material-icon', 'check')\n        ),\n        m('.message-body', [\n          m('p.lead',\n            interpolate(lead, {'username': message.username}, true)\n          ),\n          m('p',\n            gettext('The page will refresh automatically in 10 seconds.')\n          ),\n          m('p',\n            m('button[type=\"button\"].btn.btn-default', {onclick: refresh},\n              gettext('Refresh page')\n            )\n          )\n        ])\n      ];\n    },\n    inactive: function(message) {\n      var lead = null;\n      var help = null;\n\n      if (message.activation === 'user') {\n        lead = gettext(\"%(username)s, your account has been created but you need to activate it before you will be able to sign in.\");\n        help = gettext(\"We have sent an e-mail to %(email)s with link that you have to click to activate your account.\");\n      } else if (message.activation === 'admin') {\n        lead = gettext(\"%(username)s, your account has been created but board administrator will have to activate it before you will be able to sign in.\");\n        help = gettext(\"We will send an e-mail to %(email)s when this takes place.\");\n      }\n\n      return [\n        m('.message-icon',\n          m('span.material-icon', 'info_outline')\n        ),\n        m('.message-body', [\n          m('p.lead',\n            interpolate(lead, {'username': message.username}, true)\n          ),\n          m('p',\n            interpolate(help, {'email': message.email}, true)\n          )\n        ])\n      ];\n    }\n  };\n\n  Misago.addService('modal:register-complete', function(_) {\n    _.modal('register-complete', registerComplete);\n  },\n  {\n    after: 'modals'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var register = {\n    controller: function(_) {\n      return {\n        form: _.form('register')\n      };\n    },\n    view: function(ctrl, _) {\n      var captcha = _.captcha.component({\n        form: ctrl.form,\n\n        labelClass: '.col-md-4',\n        controlClass: '.col-md-8'\n      });\n\n      var footnote = null;\n      var termsUrl = _.settings.terms_of_service_link;\n\n      if (!termsUrl && _.settings.terms_of_service) {\n        termsUrl = _.router.url('terms_of_service');\n      }\n\n      if (termsUrl) {\n        footnote = m('a', {href: termsUrl},\n          m.trust(interpolate(gettext(\"By registering you agree to site's %(terms)s.\"), {\n            terms: '<strong>' + gettext(\"terms and conditions\") + '</strong>'\n          }, true))\n        );\n      }\n\n      return m('.modal-dialog.modal-form.modal-register[role=\"document\"]',\n        {config: persistent},\n        m('.modal-content', [\n          _.component('modal:header', gettext('Register')),\n          m('form.form-horizontal',\n          {\n            onsubmit: ctrl.form.submit\n          },\n          [\n            m('input[type=\"text\"]', {\n              name:'_username',\n              style: 'display: none'\n            }),\n            m('input[type=\"password\"]', {\n              name:'_password',\n              style: 'display: none'\n            }),\n            m('.modal-body', [\n              _.component('form-group', {\n                label: gettext(\"Username\"),\n                labelClass: '.col-md-4',\n                controlClass: '.col-md-8',\n                control: _.input({\n                  value: _.validate(ctrl.form, 'username'),\n                  id: 'id_username',\n                  disabled: ctrl.form.isBusy\n                }),\n                validation: ctrl.form.errors,\n                validationKey: 'username'\n              }),\n              _.component('form-group', {\n                label: gettext(\"E-mail\"),\n                labelClass: '.col-md-4',\n                controlClass: '.col-md-8',\n                control: _.input({\n                  value: _.validate(ctrl.form, 'email'),\n                  id: 'id_email',\n                  disabled: ctrl.form.isBusy\n                }),\n                validation: ctrl.form.errors,\n                validationKey: 'email'\n              }),\n              _.component('form-group', {\n                label: gettext(\"Password\"),\n                labelClass: '.col-md-4',\n                controlClass: '.col-md-8',\n                control: _.input({\n                  value: _.validate(ctrl.form, 'password'),\n                  type: 'password',\n                  id: 'id_password',\n                  disabled: ctrl.form.isBusy\n                }),\n                validation: ctrl.form.errors,\n                validationKey: 'password',\n                helpText: _.component('password-strength', {\n                  inputs: [\n                    ctrl.form.username(),\n                    ctrl.form.email()\n                  ],\n                  password: ctrl.form.password()\n                })\n              }),\n              captcha\n            ]),\n            m('.modal-footer', [\n              footnote,\n              _.component('button', {\n                class: '.btn-primary',\n                submit: true,\n                loading: ctrl.form.isBusy,\n                label: gettext(\"Register account\")\n              })\n            ])\n          ])\n        ])\n      );\n    }\n  };\n\n  Misago.addService('modal:register', function(_) {\n    _.modal('register', register);\n  },\n  {\n    after: 'modals'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  function persistent(el, isInit, context) {\n    context.retain = true;\n  }\n\n  var signin = {\n    controller: function(_) {\n      return {\n        form: _.form('sign-in')\n      };\n    },\n    view: function(ctrl, _) {\n      var activateButton = null;\n\n      if (ctrl.form.showActivation) {\n        activateButton = m('a.btn.btn-block.btn-success',\n          {href: _.router.url('request_activation')},\n          gettext('Activate account')\n        );\n      }\n\n      return m('.modal-dialog.modal-sm.modal-signin[role=\"document\"]',\n        {config: persistent},\n        m('.modal-content', [\n          _.component('modal:header', gettext(\"Sign in\")),\n          m('form', {onsubmit: ctrl.form.submit}, [\n            m('.modal-body', [\n              m('.form-group',\n                m('.control-input',\n                  Misago.input({\n                    disabled: ctrl.form.isBusy,\n                    value: ctrl.form.username,\n                    placeholder: gettext(\"Username or e-mail\")\n                  })\n                )\n              ),\n              m('.form-group',\n                m('.control-input',\n                  Misago.input({\n                    type: 'password',\n                    disabled: ctrl.form.isBusy,\n                    value: ctrl.form.password,\n                    placeholder: gettext(\"Password\")\n                  })\n                )\n              )\n            ]),\n            m('.modal-footer', [\n              activateButton,\n              _.component('button', {\n                class: '.btn-primary.btn-block',\n                submit: true,\n                loading: ctrl.form.isBusy,\n                label: gettext(\"Sign in\")\n              })\n            ])\n          ])\n        ])\n      );\n    }\n  };\n\n  Misago.addService('modal:sign-in', function(_) {\n    _.modal('sign-in', signin);\n  },\n  {\n    after: 'modals'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var navbar = {\n    view: function(ctrl, _) {\n      var style = '.navbar.navbar-default.navbar-static-top';\n      return m('nav' + style + '[role=\"navigation\"]', [\n        _.component('navbar:desktop')\n      ]);\n    }\n  };\n\n  Misago.addService('component:navbar', function(_) {\n    _.component('navbar', navbar);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var brand = {\n    view: function(ctrl, branding, _) {\n      var children = [\n        m('img', {\n          src: _.router.staticUrl('misago/img/site-logo.png'),\n          alt: _.settings.forum_name\n        })\n      ];\n\n      if (branding) {\n        children.push(branding);\n      }\n\n      return m('a.navbar-brand', {href: _.router.url('index')}, children);\n    }\n  };\n\n  Misago.addService('component:navbar:desktop:brand', function(_) {\n    _.component('navbar:desktop:brand', brand);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var menu = {\n    controller: function(_) {\n      return {\n        showSignIn: function() {\n          _.modal('sign-in');\n        },\n\n        isBusy: false,\n        showRegister: function() {\n          if (_.settings.account_activation === 'closed') {\n            _.alert.info(gettext(\"New registrations are currently disabled.\"));\n          } else {\n            m.startComputation();\n            this.isBusy = true;\n            m.endComputation();\n\n            var self = this;\n            m.sync([\n              _.zxcvbn.load(),\n              _.captcha.load()\n            ]).then(function() {\n              _.modal('register');\n            }, function() {\n              _.alert.error(gettext('Registation is not available now due to an error.'));\n            }).then(function() {\n              m.startComputation();\n              self.isBusy = false;\n              m.endComputation();\n            });\n          }\n        }\n      };\n    },\n    view: function(ctrl, _) {\n      return m('div.nav.nav-guest', [\n        _.component('button', {\n          class: '.navbar-btn.btn-default',\n          onclick: ctrl.showSignIn,\n          disabled: ctrl.isBusy,\n          label: gettext('Sign in')\n        }),\n        _.component('button', {\n          class: '.navbar-btn.btn-primary',\n          onclick: ctrl.showRegister.bind(ctrl),\n          loading: ctrl.isBusy,\n          label: gettext('Register')\n        })\n      ]);\n    }\n  };\n\n  Misago.addService('component:navbar:desktop:guest-menu', function(_) {\n    _.component('navbar:desktop:guest-menu', menu);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var navbar = {\n    view: function(ctrl, _) {\n      var menu = [];\n\n      if (_.settings.forum_branding_display) {\n        menu.push(\n          _.component('navbar:desktop:brand', _.settings.forum_branding_text));\n      }\n\n      menu.push(m('ul.nav.navbar-nav', [\n        m('li',\n          m(\"a\", {config: m.route, href: _.router.url('index')}, 'Index')\n        )\n      ]));\n\n      if (_.user.isAuthenticated) {\n        menu.push(_.component('navbar:desktop:user-menu'));\n      } else {\n        menu.push(_.component('navbar:desktop:guest-menu'));\n      }\n\n      return m('.container.navbar-full.hidden-xs.hidden-sm', menu);\n    }\n  };\n\n  Misago.addService('component:navbar:desktop', function(_) {\n    _.component('navbar:desktop', navbar);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var menu = {\n    controller: function() {\n      return {\n        logout: function() {\n          $('#hidden-logout-form').submit();\n        }\n      };\n    },\n    view: function(ctrl, _) {\n      return m('div.nav.nav-user', [\n        m('p.navbar-text',\n          _.user.username\n        ),\n        m('button.navbar-btn.btn.btn-default.navbar-right',\n          {\n            onclick: ctrl.logout.bind(ctrl)\n          },\n          gettext(\"Logout\")\n        )\n      ]);\n    }\n  };\n\n  Misago.addService('component:navbar:desktop:user-menu', function(_) {\n    _.component('navbar:desktop:user-menu', menu);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  function persistent(el, isInit, context) {\n    context.retain = true;\n  }\n\n  var alert = {\n    classes: {\n      'info': 'alert-info',\n      'success': 'alert-success',\n      'warning': 'alert-warning',\n      'error': 'alert-danger'\n    },\n    view: function(ctrl, _) {\n      return m(\n        '.alerts',\n        {\n          config: persistent,\n          class: _.alert.isVisible ? 'in' : 'out'\n        },\n        m('p.alert',\n          {\n            class: this.classes[_.alert.type]\n          },\n          _.alert.message\n        )\n      );\n    }\n  };\n\n  Misago.addService('component:alert', function(_) {\n    _.component('alert', alert);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var button = {\n    view: function(ctrl, kwargs) {\n      var options = {\n        disabled: kwargs.disabled || kwargs.loading || false,\n        config: kwargs.config || null,\n        loading: kwargs.loading || false,\n        type: kwargs.submit ? 'submit' : 'button',\n        onclick: kwargs.onclick || null\n      };\n\n      var element = 'button[type=\"' + options.type + '\"].btn';\n      if (options.loading) {\n        element += '.btn-loading';\n      }\n\n      if (kwargs.id) {\n        element += '#' + kwargs.id;\n      }\n\n      element += (kwargs.class || '');\n\n      var label = kwargs.label;\n      if (options.loading) {\n        label = [\n          label,\n          m('.loader-compact', [\n            m('.bounce1'),\n            m('.bounce2'),\n            m('.bounce3')\n          ])\n        ];\n      }\n\n      return m(element, options, label);\n    },\n  };\n\n  Misago.addService('component:button', function(_) {\n    _.component('button', button);\n  },\n  {\n    after: 'components'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var textFields = ['text', 'password', 'email'];\n\n  var formGroup = {\n    view: function(ctrl, kwargs) {\n      var groupClass = '.form-group';\n      var errors = null;\n      var helpText = null;\n\n      var controlType = kwargs.control.attrs.type;\n      var controlId = kwargs.control.attrs.id;\n\n      var feedbackId = controlId + '_feedback';\n      var feedbackIcon = null;\n      var showFeedbackIcon = null;\n\n      var isValidated = kwargs.validationKey && kwargs.validation !== null;\n\n      kwargs.control.attrs['aria-describedby'] = '';\n\n      if (isValidated && kwargs.validation[kwargs.validationKey]) {\n        showFeedbackIcon = textFields.indexOf(controlType) >= 0;\n        kwargs.control.attrs['aria-describedby'] = feedbackId;\n\n        if (kwargs.validation[kwargs.validationKey] === true) {\n          groupClass += '.has-success';\n          feedbackIcon = [\n            m('span.material-icon.form-control-feedback',\n              {\n                'aria-hidden': 'true'\n              },\n              'check'\n            ),\n            m('span.sr-only#' + feedbackId, gettext(\"(success)\"))\n          ];\n        } else {\n          groupClass += '.has-error';\n          errors = kwargs.validation[kwargs.validationKey];\n          feedbackIcon = [\n            m('span.material-icon.form-control-feedback',\n              {\n                'aria-hidden': 'true'\n              },\n              'clear'\n            ),\n            m('span.sr-only#' + feedbackId, gettext(\"(error)\"))\n          ];\n        }\n      }\n\n      if (kwargs.helpText) {\n        if (typeof kwargs.helpText === 'string' ||\n            kwargs.helpText instanceof String) {\n          helpText = m('p.help-block', kwargs.helpText);\n        } else {\n          helpText = kwargs.helpText;\n        }\n      }\n\n      return m(groupClass, [\n        m('label.control-label' + (kwargs.labelClass || ''),\n          {\n            for: kwargs.labelFor || controlId\n          },\n          kwargs.label + ':'\n        ),\n        m(kwargs.controlClass || '', [\n          kwargs.control,\n          showFeedbackIcon ? feedbackIcon : null,\n          errors ? m('.help-block.errors', errors.map(function(item) {\n            return m('p', item);\n          })) : null,\n          helpText\n        ])\n      ]);\n    },\n  };\n\n  Misago.addService('component:form-group', function(_) {\n    _.component('form-group', formGroup);\n  },\n  {\n    after: 'components'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var forumLayout = {\n    view: function(ctrl, _) {\n      return [\n        _.component('alert'),\n        _.component('navbar'),\n        m('#router-fixture', {config: persistent}),\n        _.component('footer'),\n        _.component('modal')\n      ];\n    }\n  };\n\n  Misago.addService('component:layout', function(_) {\n    _.component('forum-layout', forumLayout);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var loader = {\n    view: function() {\n      return m('.loader.sk-folding-cube', [\n        m('.sk-cube1.sk-cube'),\n        m('.sk-cube2.sk-cube'),\n        m('.sk-cube4.sk-cube'),\n        m('.sk-cube3.sk-cube')\n      ]);\n    }\n  };\n\n  Misago.addService('component:loader', function(_) {\n    _.component('loader', loader);\n  },\n  {\n    after: 'components'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var markup = {\n    view: function(ctrl, content) {\n      return m('article.misago-markup', {config: persistent},\n        m.trust(content)\n      );\n    }\n  };\n\n  Misago.addService('component:markup', function(_) {\n    _.component('markup', markup);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var modal = {\n    view: function() {\n      return m(\n        '#misago-modal.modal.fade[role=\"dialog\"]',\n        {\n          config: persistent,\n          tabindex: \"-1\",\n          \"aria-labelledby\": \"misago-modal-label\"\n        }\n      );\n    }\n  };\n\n  Misago.addService('component:modal', function(_) {\n    _.component('modal', modal);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var header = {\n    view: function(ctrl, options) {\n      return m('.page-header',\n        m('.container', [\n          m('h1', options.title),\n        ])\n      );\n    }\n  };\n\n  Misago.addService('component:header', function(_) {\n    _.component('header', header);\n  },\n  {\n    after: 'components'\n  });\n}(Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var persistent = function(el, isInit, context) {\n    context.retain = true;\n  };\n\n  var styles = [\n    'progress-bar-danger',\n    'progress-bar-warning',\n    'progress-bar-warning',\n    'progress-bar-primary',\n    'progress-bar-success'\n  ];\n\n  var labels = [\n    gettext('Entered password is very weak.'),\n    gettext('Entered password is weak.'),\n    gettext('Entered password is average.'),\n    gettext('Entered password is strong.'),\n    gettext('Entered password is very strong.')\n  ];\n\n  var passwordStrength = {\n    view: function(ctrl, kwargs, _) {\n      var score = _.zxcvbn.scorePassword(kwargs.password, kwargs.inputs);\n      var options = {\n        config: persistent,\n        class: styles[score],\n        style: \"width: \" + (20 + (20 * score)) + '%',\n        'role': \"progressbar\",\n        'aria-valuenow': score,\n        'aria-valuemin': \"0\",\n        'aria-valuemax': \"4\"\n      };\n\n      return m('.help-block.password-strength', {key: 'password-strength'}, [\n        m('.progress',\n          m('.progress-bar', options,\n            m('span.sr-only', labels[score])\n          )\n        ),\n        m('p.text-small', labels[score])\n      ]);\n    },\n  };\n\n  Misago.addService('component:password-strength', function(_) {\n    _.component('password-strength', passwordStrength);\n  },\n  {\n    after: 'components'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var Register = function(_) {\n    var self = this;\n\n    this.showActivation = false;\n\n    this.username = m.prop('');\n    this.email = m.prop('');\n    this.password = m.prop('');\n\n    this.captcha = _.captcha.value;\n\n    this.errors = null;\n\n    this.validation = {\n      'username': [\n        Misago.validators.usernameContent(),\n        Misago.validators.usernameMinLength(_.settings),\n        Misago.validators.usernameMaxLength(_.settings)\n      ],\n      'email': [\n        Misago.validators.email()\n      ],\n      'password': [\n        Misago.validators.passwordMinLength(_.settings)\n      ],\n      'captcha': _.captcha.validator()\n    };\n\n    this.clean = function() {\n      if (this.errors === null) {\n        _.validate(this);\n      }\n\n      _.captcha.clean(this);\n\n      if (this.hasErrors()) {\n        _.alert.error(gettext(\"Form contains errors.\"));\n        return false;\n      } else {\n        return true;\n      }\n    };\n\n    this.submit = function() {\n      _.api.model('user').post({\n        username: this.username(),\n        email: this.email(),\n        password: this.password(),\n        captcha: this.captcha()\n      }).then(this.success, this.error);\n    };\n\n    this.success = function(data) {\n      _.modal('register-complete', data);\n    };\n\n    this.error = function(rejection) {\n      if (rejection.status === 400) {\n        _.alert.error(gettext(\"Form contains errors.\"));\n        $.extend(self.errors, rejection);\n      } else {\n        _.api.alert(rejection);\n      }\n    };\n  };\n\n  Misago.addService('form:register', function(_) {\n    _.form('register', Register);\n  },\n  {\n    after: 'forms'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var RequestLink = function(options, _) {\n    var self = this;\n\n    this.email = m.prop('');\n\n    this.validation = {\n      'email': [\n        Misago.validators.email()\n      ]\n    };\n\n    this.clean = function() {\n      if (!_.validate(this)) {\n        _.alert.error(gettext(\"Enter a valid email address.\"));\n        return false;\n      } else {\n        return true;\n      }\n    };\n\n    this.submit = function() {\n      _.api.endpoint('auth').endpoint(options.endpoint).post({\n        email: self.email()\n      }).then(function(user) {\n        self.success(user);\n      }, function(error) {\n        self.error(error);\n      });\n    };\n\n    this.success = function(user) {\n      options.success(user);\n    };\n\n    this.error = function(rejection) {\n      if (rejection.status === 400) {\n        if (rejection.code === 'banned') {\n          _.router.error403({\n            message: '',\n            ban: rejection.detail\n          });\n        } else {\n          options.error(rejection, _);\n        }\n      } else {\n        _.api.alert(rejection);\n      }\n    };\n\n    this.reset = function() {\n      this.email('');\n      options.reset();\n    };\n  };\n\n  Misago.addService('form:request-link', function(_) {\n    _.form('request-link', RequestLink);\n  },\n  {\n    after: 'forms'\n  });\n} (Misago.prototype));\n\n(function (Misago) {\n  'use strict';\n\n  var SignIn = function(_) {\n    var self = this;\n\n    this.showActivation = false;\n\n    this.username = m.prop('');\n    this.password = m.prop('');\n\n    this.validation = {\n      'username': [],\n      'password': []\n    };\n\n    this.clean = function() {\n      if (!_.validate(this)) {\n        _.alert.error(gettext(\"Fill out both fields.\"));\n        return false;\n      } else {\n        return true;\n      }\n    };\n\n    this.submit = function() {\n      _.api.endpoint('auth').post({\n        username: self.username(),\n        password: self.password()\n      }).then(function() {\n        self.success();\n      }, function(error) {\n        self.error(error);\n      });\n    };\n\n    this.success = function() {\n      _.modal();\n\n      var $form = $('#hidden-login-form');\n\n      // refresh CSRF token because api call to /auth/ changed it\n      _.ajax.refreshCsrfToken();\n\n      // fill out form with user credentials and submit it, this will tell\n      // misago to redirect user back to right page, and will trigger browser's\n      // key ring feature\n      $form.find('input[type=\"hidden\"]').val(_.ajax.csrfToken);\n      $form.find('input[name=\"redirect_to\"]').val(m.route());\n      $form.find('input[name=\"username\"]').val(this.username());\n      $form.find('input[name=\"password\"]').val(this.password());\n      $form.submit();\n    };\n\n    this.error = function(rejection) {\n      if (rejection.status === 400) {\n        if (rejection.code === 'inactive_admin') {\n          _.alert.info(rejection.detail);\n        } else if (rejection.code === 'inactive_user') {\n          _.alert.info(rejection.detail);\n          self.showActivation = true;\n        } else if (rejection.code === 'banned') {\n          _.modal();\n          _.router.error403({\n            message: '',\n            ban: rejection.detail\n          });\n        } else {\n          _.alert.error(rejection.detail);\n        }\n      } else {\n        _.api.alert(rejection);\n      }\n    };\n  };\n\n  Misago.addService('form:sign-in', function(_) {\n    _.form('sign-in', SignIn);\n  },\n  {\n    after: 'forms'\n  });\n} (Misago.prototype));\n\n(function (Misago, UrlConf) {\n  'use strict';\n\n  var urls = new UrlConf();\n\n  // Board index\n  urls.url('/', 'index');\n\n  // Account activation\n  urls.url('/activation/', 'request_activation');\n  urls.url('/activation/:user_id/:token/', 'activate_by_token');\n\n  // Legal pages\n  urls.url('/terms-of-service/', 'terms_of_service');\n  urls.url('/privacy-policy/', 'privacy_policy');\n\n  // Catch-all 404 not found route\n  urls.url('/:rest...', 'error:404', 'not_found');\n\n  Misago.urls = urls;\n} (Misago.prototype, Misago.prototype.UrlConf));\n"],"sourceRoot":"/source/"}

+ 1 - 1
misago/templates/misago/emails/activation/by_user.txt

@@ -6,5 +6,5 @@
 {% blocktrans trimmed with user=recipient %}
 {% blocktrans trimmed with user=recipient %}
 {{ user }}, to activate your account click the below link:
 {{ user }}, to activate your account click the below link:
 {% endblocktrans %}
 {% endblocktrans %}
-{{ SITE_ADDRESS }}{% url 'misago:activate_by_token' user_id=recipient.id token=activation_token %}"
+{{ SITE_ADDRESS }}{% url 'misago:activate_by_token' user_id=recipient.id token=activation_token %}
 {% endblock content %}
 {% endblock content %}

+ 4 - 4
misago/templates/misago/errorpages/403.html

@@ -9,15 +9,15 @@
 
 
 
 
 {% block content %}
 {% block content %}
-<div class="page error-page error-403">
+<div class="page page-error page-error-403">
   <div class="container">
   <div class="container">
-    <div class="error-panel">
+    <div class="message-panel">
 
 
-      <div class="error-icon">
+      <div class="message-icon">
         <i class="material-icon">remove_circle_outline</i>
         <i class="material-icon">remove_circle_outline</i>
       </div>
       </div>
 
 
-      <div class="error-message">
+      <div class="message-body">
         <p class="lead">{% trans "This page is not available." %}</p>
         <p class="lead">{% trans "This page is not available." %}</p>
         {% if message %}
         {% if message %}
         <p>{{ message|escape|urlize|linebreaksbr }}</p>
         <p>{{ message|escape|urlize|linebreaksbr }}</p>

+ 4 - 4
misago/templates/misago/errorpages/404.html

@@ -9,15 +9,15 @@
 
 
 
 
 {% block content %}
 {% block content %}
-<div class="page error-page error-404">
+<div class="page page-error page-error-404">
   <div class="container">
   <div class="container">
-    <div class="error-panel">
+    <div class="message-panel">
 
 
-      <div class="error-icon">
+      <div class="message-icon">
         <i class="material-icon">info_outline</i>
         <i class="material-icon">info_outline</i>
       </div>
       </div>
 
 
-      <div class="error-message">
+      <div class="message-body">
         <p class="lead">{% trans "Requested page could not be found." %}</p>
         <p class="lead">{% trans "Requested page could not be found." %}</p>
         <p>{% trans "The link you followed was incorrect or the page has been moved or deleted." %}</p>
         <p>{% trans "The link you followed was incorrect or the page has been moved or deleted." %}</p>
       </div>
       </div>

+ 4 - 4
misago/templates/misago/errorpages/405.html

@@ -9,15 +9,15 @@
 
 
 
 
 {% block content %}
 {% block content %}
-<div class="page error-page error-405">
+<div class="page page-error page-error-405">
   <div class="container">
   <div class="container">
-    <div class="error-panel">
+    <div class="message-panel">
 
 
-      <div class="error-icon">
+      <div class="message-icon">
         <i class="material-icon">remove_circle_outline</i>
         <i class="material-icon">remove_circle_outline</i>
       </div>
       </div>
 
 
-      <div class="error-message">
+      <div class="message-body">
         <p class="lead">{% trans "Page reached in wrong way." %}</p>
         <p class="lead">{% trans "Page reached in wrong way." %}</p>
         <p>{% trans "This page should be reached via form submission or pressing button." %}</p>
         <p>{% trans "This page should be reached via form submission or pressing button." %}</p>
       </div>
       </div>

+ 4 - 4
misago/templates/misago/errorpages/csrf_failure.html

@@ -9,15 +9,15 @@
 
 
 
 
 {% block content %}
 {% block content %}
-<div class="page error-page error-csrf">
+<div class="page page-error page-error-csrf">
   <div class="container">
   <div class="container">
-    <div class="error-panel">
+    <div class="message-panel">
 
 
-      <div class="error-icon">
+      <div class="message-icon">
         <i class="material-icon">remove_circle_outline</i>
         <i class="material-icon">remove_circle_outline</i>
       </div>
       </div>
 
 
-      <div class="error-message">
+      <div class="message-body">
         <p class="lead">{% trans "Suspicious request blocked." %}</p>
         <p class="lead">{% trans "Suspicious request blocked." %}</p>
         <p>{% trans "This is usually caused by your browser not accepting or using outdated cookies." %}</p>
         <p>{% trans "This is usually caused by your browser not accepting or using outdated cookies." %}</p>
         <p>{% trans "Check your browser configuration and try again." %}</p>
         <p>{% trans "Check your browser configuration and try again." %}</p>

+ 4 - 4
misago/templates/misago/errorpages/csrf_failure_authenticated.html

@@ -6,15 +6,15 @@
 
 
 
 
 {% block content %}
 {% block content %}
-<div class="page error-page error-csrf">
+<div class="page page-error page-error-csrf">
   <div class="container">
   <div class="container">
-    <div class="error-panel">
+    <div class="message-panel">
 
 
-      <div class="error-icon">
+      <div class="message-icon">
         <i class="material-icon">remove_circle_outline</i>
         <i class="material-icon">remove_circle_outline</i>
       </div>
       </div>
 
 
-      <div class="error-message">
+      <div class="message-body">
         <p class="lead">{% trans "Suspicious request blocked." %}</p>
         <p class="lead">{% trans "Suspicious request blocked." %}</p>
         <p>{% trans "This is usually caused by your browser not accepting or using outdated cookies." %}</p>
         <p>{% trans "This is usually caused by your browser not accepting or using outdated cookies." %}</p>
         <p>{% trans "Check your browser configuration and try again." %}</p>
         <p>{% trans "Check your browser configuration and try again." %}</p>

+ 3 - 3
misago/templates/misago/noscript.html

@@ -6,12 +6,12 @@
 
 
 
 
 {% block content %}
 {% block content %}
-<div class="error-page error-noscript">
+<div class="page error-page error-noscript">
   <div class="container">
   <div class="container">
-    <div class="error">
+    <div class="error-panel">
 
 
       <div class="error-icon">
       <div class="error-icon">
-        <i class="material-icons">code</i>
+        <i class="material-icon">code</i>
       </div>
       </div>
 
 
       <div class="error-message">
       <div class="error-message">

+ 2 - 3
misago/users/api/auth.py

@@ -128,10 +128,9 @@ def activate_account(request, user_id, token):
     user.requires_activation = False
     user.requires_activation = False
     user.save(update_fields=['requires_activation'])
     user.save(update_fields=['requires_activation'])
 
 
-    message = _("%(user)s, your account has been activated.")
     return Response({
     return Response({
-            'detail': message % {'user': user.username}
-        })
+        'username': user.username
+    })
 
 
 
 
 """
 """