From d37e5637a087f4489482fc26094cdd425658ee1f Mon Sep 17 00:00:00 2001 From: Dev Date: Sun, 12 Oct 2014 17:18:57 +0200 Subject: [PATCH 1/7] Play authenticate usage example copy --- samples/scala/Getting Started.md | 393 ++ .../scala/play-authenticate-usage/.gitignore | 15 + .../scala/play-authenticate-usage/Procfile | 1 + .../scala/play-authenticate-usage/README.md | 6 + .../play-authenticate-usage/app/Global.java | 83 + .../app/controllers/Account.java | 219 + .../app/controllers/Application.java | 100 + .../app/controllers/Signup.java | 212 + .../app/models/LinkedAccount.java | 54 + .../app/models/SecurityRole.java | 50 + .../app/models/TokenAction.java | 87 + .../app/models/User.java | 249 + .../app/models/UserPermission.java | 35 + .../MyLoginUsernamePasswordAuthUser.java | 40 + .../providers/MyStupidBasicAuthProvider.java | 63 + .../MyUsernamePasswordAuthProvider.java | 386 ++ .../providers/MyUsernamePasswordAuthUser.java | 35 + .../app/security/MyDeadboltHandler.java | 72 + .../app/service/MyUserServicePlugin.java | 60 + .../app/views/_emailPartial.scala.html | 10 + .../app/views/_passwordPartial.scala.html | 16 + .../app/views/_providerIcon.scala.html | 2 + .../app/views/_providerPartial.scala.html | 24 + .../app/views/account/ask_link.scala.html | 35 + .../app/views/account/ask_merge.scala.html | 35 + .../email/password_reset_de.scala.html | 15 + .../account/email/password_reset_de.scala.txt | 12 + .../email/password_reset_en.scala.html | 15 + .../account/email/password_reset_en.scala.txt | 11 + .../email/password_reset_es.scala.html | 16 + .../account/email/password_reset_es.scala.txt | 11 + .../email/password_reset_pl.scala.html | 15 + .../account/email/password_reset_pl.scala.txt | 11 + .../email/password_reset_pt.scala.html | 15 + .../account/email/password_reset_pt.scala.txt | 11 + .../account/email/verify_email_de.scala.html | 12 + .../account/email/verify_email_de.scala.txt | 9 + .../account/email/verify_email_en.scala.html | 12 + .../account/email/verify_email_en.scala.txt | 8 + .../account/email/verify_email_es.scala.html | 12 + .../account/email/verify_email_es.scala.txt | 8 + .../account/email/verify_email_pl.scala.html | 12 + .../account/email/verify_email_pl.scala.txt | 8 + .../account/email/verify_email_pt.scala.html | 12 + .../account/email/verify_email_pt.scala.txt | 8 + .../app/views/account/link.scala.html | 10 + .../views/account/password_change.scala.html | 23 + .../signup/email/verify_email_de.scala.html | 14 + .../signup/email/verify_email_de.scala.txt | 11 + .../signup/email/verify_email_en.scala.html | 14 + .../signup/email/verify_email_en.scala.txt | 10 + .../signup/email/verify_email_es.scala.html | 14 + .../signup/email/verify_email_es.scala.txt | 10 + .../signup/email/verify_email_pl.scala.html | 14 + .../signup/email/verify_email_pl.scala.txt | 10 + .../signup/email/verify_email_pt.scala.html | 14 + .../signup/email/verify_email_pt.scala.txt | 10 + .../views/account/signup/exists.scala.html | 5 + .../signup/no_token_or_invalid.scala.html | 5 + .../account/signup/oAuthDenied.scala.html | 12 + .../account/signup/password_forgot.scala.html | 23 + .../account/signup/password_reset.scala.html | 32 + .../account/signup/unverified.scala.html | 11 + .../app/views/account/unverified.scala.html | 8 + .../app/views/index.scala.html | 27 + .../app/views/login.scala.html | 56 + .../app/views/main.scala.html | 103 + .../app/views/profile.scala.html | 51 + .../app/views/restricted.scala.html | 9 + .../app/views/signup.scala.html | 47 + .../scala/play-authenticate-usage/build.sbt | 41 + .../conf/application.conf | 71 + .../play-authenticate-usage/conf/messages.de | 150 + .../play-authenticate-usage/conf/messages.en | 150 + .../play-authenticate-usage/conf/messages.es | 148 + .../play-authenticate-usage/conf/messages.fr | 149 + .../play-authenticate-usage/conf/messages.ja | 149 + .../play-authenticate-usage/conf/messages.pl | 149 + .../play-authenticate-usage/conf/messages.pt | 149 + .../conf/play-authenticate/deadbolt.conf | 8 + .../conf/play-authenticate/mine.conf | 296 + .../conf/play-authenticate/smtp.conf | 27 + .../play-authenticate-usage/conf/play.plugins | 18 + .../scala/play-authenticate-usage/conf/routes | 47 + .../modules/play-authenticate | 1 + .../project/build.properties | 1 + .../project/plugins.sbt | 8 + .../public/css/bootstrap.css | 4914 +++++++++++++++++ .../public/css/bootstrap.min.css | 727 +++ .../public/css/main.css | 32 + .../public/icons/basic-24x24.png | Bin 0 -> 1460 bytes .../public/icons/eventbrite-24x24.png | Bin 0 -> 1151 bytes .../public/icons/facebook-24x24.png | Bin 0 -> 1035 bytes .../public/icons/foursquare-24x24.png | Bin 0 -> 1192 bytes .../public/icons/github-24x24.png | Bin 0 -> 1807 bytes .../public/icons/google-24x24.png | Bin 0 -> 1452 bytes .../public/icons/linkedin-24x24.png | Bin 0 -> 1113 bytes .../public/icons/openid-24x24.png | Bin 0 -> 1002 bytes .../public/icons/password-24x24.png | Bin 0 -> 897 bytes .../public/icons/pocket-24x24.png | Bin 0 -> 1460 bytes .../public/icons/twitter-24x24.png | Bin 0 -> 993 bytes .../public/icons/untappd-24x24.png | Bin 0 -> 1460 bytes .../public/icons/vk-24x24.png | Bin 0 -> 1460 bytes .../public/icons/xing-24x24.png | Bin 0 -> 1189 bytes .../public/img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../public/img/glyphicons-halflings.png | Bin 0 -> 13826 bytes .../public/js/bootstrap.js | 1836 ++++++ .../public/js/bootstrap.min.js | 7 + .../test/EventbriteOAuth2Test.java | 68 + .../test/GoogleOAuth2Test.java | 54 + .../test/OAuth2Test.java | 72 + 111 files changed, 12330 insertions(+) create mode 100644 samples/scala/Getting Started.md create mode 100644 samples/scala/play-authenticate-usage/.gitignore create mode 100644 samples/scala/play-authenticate-usage/Procfile create mode 100644 samples/scala/play-authenticate-usage/README.md create mode 100644 samples/scala/play-authenticate-usage/app/Global.java create mode 100644 samples/scala/play-authenticate-usage/app/controllers/Account.java create mode 100644 samples/scala/play-authenticate-usage/app/controllers/Application.java create mode 100644 samples/scala/play-authenticate-usage/app/controllers/Signup.java create mode 100644 samples/scala/play-authenticate-usage/app/models/LinkedAccount.java create mode 100644 samples/scala/play-authenticate-usage/app/models/SecurityRole.java create mode 100644 samples/scala/play-authenticate-usage/app/models/TokenAction.java create mode 100644 samples/scala/play-authenticate-usage/app/models/User.java create mode 100644 samples/scala/play-authenticate-usage/app/models/UserPermission.java create mode 100644 samples/scala/play-authenticate-usage/app/providers/MyLoginUsernamePasswordAuthUser.java create mode 100644 samples/scala/play-authenticate-usage/app/providers/MyStupidBasicAuthProvider.java create mode 100644 samples/scala/play-authenticate-usage/app/providers/MyUsernamePasswordAuthProvider.java create mode 100644 samples/scala/play-authenticate-usage/app/providers/MyUsernamePasswordAuthUser.java create mode 100644 samples/scala/play-authenticate-usage/app/security/MyDeadboltHandler.java create mode 100644 samples/scala/play-authenticate-usage/app/service/MyUserServicePlugin.java create mode 100644 samples/scala/play-authenticate-usage/app/views/_emailPartial.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/_passwordPartial.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/_providerIcon.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/_providerPartial.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/ask_link.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/ask_merge.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_de.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_de.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_en.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_en.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_es.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_es.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pl.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pl.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pt.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pt.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_de.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_de.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_en.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_en.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_es.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_es.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pl.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pl.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pt.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pt.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/link.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/password_change.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_de.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_de.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_en.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_en.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_es.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_es.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pl.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pl.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pt.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pt.scala.txt create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/exists.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/no_token_or_invalid.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/oAuthDenied.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/password_forgot.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/password_reset.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/signup/unverified.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/account/unverified.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/index.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/login.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/main.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/profile.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/restricted.scala.html create mode 100644 samples/scala/play-authenticate-usage/app/views/signup.scala.html create mode 100644 samples/scala/play-authenticate-usage/build.sbt create mode 100644 samples/scala/play-authenticate-usage/conf/application.conf create mode 100644 samples/scala/play-authenticate-usage/conf/messages.de create mode 100644 samples/scala/play-authenticate-usage/conf/messages.en create mode 100644 samples/scala/play-authenticate-usage/conf/messages.es create mode 100644 samples/scala/play-authenticate-usage/conf/messages.fr create mode 100644 samples/scala/play-authenticate-usage/conf/messages.ja create mode 100644 samples/scala/play-authenticate-usage/conf/messages.pl create mode 100644 samples/scala/play-authenticate-usage/conf/messages.pt create mode 100644 samples/scala/play-authenticate-usage/conf/play-authenticate/deadbolt.conf create mode 100644 samples/scala/play-authenticate-usage/conf/play-authenticate/mine.conf create mode 100644 samples/scala/play-authenticate-usage/conf/play-authenticate/smtp.conf create mode 100644 samples/scala/play-authenticate-usage/conf/play.plugins create mode 100644 samples/scala/play-authenticate-usage/conf/routes create mode 100644 samples/scala/play-authenticate-usage/modules/play-authenticate create mode 100644 samples/scala/play-authenticate-usage/project/build.properties create mode 100644 samples/scala/play-authenticate-usage/project/plugins.sbt create mode 100644 samples/scala/play-authenticate-usage/public/css/bootstrap.css create mode 100644 samples/scala/play-authenticate-usage/public/css/bootstrap.min.css create mode 100644 samples/scala/play-authenticate-usage/public/css/main.css create mode 100644 samples/scala/play-authenticate-usage/public/icons/basic-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/eventbrite-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/facebook-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/foursquare-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/github-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/google-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/linkedin-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/openid-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/password-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/pocket-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/twitter-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/untappd-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/vk-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/icons/xing-24x24.png create mode 100644 samples/scala/play-authenticate-usage/public/img/glyphicons-halflings-white.png create mode 100644 samples/scala/play-authenticate-usage/public/img/glyphicons-halflings.png create mode 100644 samples/scala/play-authenticate-usage/public/js/bootstrap.js create mode 100644 samples/scala/play-authenticate-usage/public/js/bootstrap.min.js create mode 100644 samples/scala/play-authenticate-usage/test/EventbriteOAuth2Test.java create mode 100644 samples/scala/play-authenticate-usage/test/GoogleOAuth2Test.java create mode 100644 samples/scala/play-authenticate-usage/test/OAuth2Test.java diff --git a/samples/scala/Getting Started.md b/samples/scala/Getting Started.md new file mode 100644 index 00000000..2e8f846b --- /dev/null +++ b/samples/scala/Getting Started.md @@ -0,0 +1,393 @@ +#Getting Started + + +##Importing the Plugin +--- + +Add Play-Authenticate to your app dependencies. This is done by modifying the `project/Build.scala` file. +Add `"com.feth" %% "play-authenticate" % "0.2.1-SNAPSHOT"` (`0.2.1` might actually change - have a look at the version history to select the latest version) as a dependency and add the resolvers as shown below: + + import sbt._ + import Keys._ + import PlayProject._ + + object ApplicationBuild extends Build { + + val appName = "authtut" + val appVersion = "1.0-SNAPSHOT" + + val appDependencies = Seq( + // Add your project dependencies here, + "com.feth" %% "play-authenticate" % "0.2.0-SNAPSHOT" + ) + + val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings( + // Add your own project settings here + resolvers += Resolver.url("play-easymail (release)", url("http://joscha.github.io/play-easymail/repo/releases/"))(Resolver.ivyStylePatterns), + resolvers += Resolver.url("play-easymail (snapshot)", url("http://joscha.github.io/play-easymail/repo/snapshots/"))(Resolver.ivyStylePatterns), + + + resolvers += Resolver.url("play-authenticate (release)", url("http://joscha.github.io/play-authenticate/repo/releases/"))(Resolver.ivyStylePatterns), + resolvers += Resolver.url("play-authenticate (snapshot)", url("http://joscha.github.io/play-authenticate/repo/snapshots/"))(Resolver.ivyStylePatterns) + ) + + } + + +##Configuration File +--- + +Create a new file `play-authenticate/mine.conf` in your conf folder. Include this file in your `application.conf` by adding the following line to it: + + include "play-authenticate/mine.conf" + +In your mine.conf file you can configure play-authenticate. The following example configuration will disable account merging (e.g. when they log in with an existing account whilst being logged in already with another account) and link users automatically when they authenticate with a new provider while being logged in. + + play-authenticate { + accountMergeEnabled=false + accountAutoLink=true + } + +The configuration file is also used to configure the different authentication providers. + +A list of all configuration options can be found here TODO. + +### Configuring Mail + +You also have to configure smtp and play-easymail. For testing purposes you can add the following line to your application.conf file: + + smtp.mock=true + +For a real application you can use the following template ([source](https://github.com/joscha/play-easymail/tree/master/samples/play-easymail-usage/conf)): + + # SMTP mailer settings + smtp { + # SMTP server + # (mandatory) + # defaults to gmail + host=smtp.gmail.com + + # SMTP port + # defaults to 25 + port=587 + + # Use SSL + # for GMail, this should be set to true + ssl=true + + # authentication user + # Optional, comment this line if no auth + # defaults to no auth + user="you@gmail.com" + + # authentication password + # Optional, comment this line to leave password blank + # defaults to no password + password=password + } + + play-easymail { + from { + # Mailing from address + email="you@gmail.com" + + # Mailing name + name="Your Name" + + # Seconds between sending mail through Akka (defaults to 1) + # delay=1 + } + } + + +##Creating the necessary views +--- + +You have to integrate Play-Authenticate into your views by yourself. Play-Authenticate provides some template helpers to do this. +You have to add one import to include theses templates: + + @import com.feth.play.module.pa.views.html._ + +### Login + +The @forProviders helper lets you iterate over all registered providers. The following example creates a login-link for each provider: + + @forProviders() { p => + @p.getKey() + } + +### Logout + +Creating a logout link is straight forward: + + Logout + +### @currentAuth Helper + +The @currentAuth helper lets you do something with the current auth provider. +The following example checks if the user is logged in and displays an logout link if she is. + + @currentAuth() { auth => + @if(auth != null) { + Logout + } + } + +This second example displays some account information: + + @currentAuth() { auth => + Logged in with provider '@auth.getProvider()' and the user ID '@auth.getId()'
+ Your session expires + @if(auth.expires() == -1){ + never + } else { + at @auth.expires() (UNIX timestamp) + } + } + +##Routes +--- +Add the following routes to your `conf/routes` file: + + GET /logout com.feth.play.module.pa.controllers.Authenticate.logout + GET /authenticate/:provider com.feth.play.module.pa.controllers.Authenticate.authenticate(provider: String) + GET /authenticate/:provider/denied controllers.Application.oAuthDenied(provider: String) + +The controllers for the first two routes are provided by the framework, but you have to decide how you handle +denied authentications. In the example above the controller for this is implemented by the method `oAuthDenied` in `controllers.Application`. + +Below you can see an example implementation of this method: + + public static Result oAuthDenied(final String providerKey) { + flash(FLASH_ERROR_KEY, + "You need to accept the OAuth connection in order to use this website!"); + return redirect(routes.Application.index()); + } + + +##Configure the Resolver +--- + +Play-Authenticate needs some pages provided by your application. You configure these pages by setting a resolver +in the `onStart` method of the [Global object](http://www.playframework.org/documentation/2.0.4/JavaGlobal). + +TODO explain Resolver interface and its methods + + import play.Application; + import play.GlobalSettings; + import play.mvc.Call; + + import com.feth.play.module.pa.PlayAuthenticate; + import com.feth.play.module.pa.PlayAuthenticate.Resolver; + import com.feth.play.module.pa.exceptions.AccessDeniedException; + import com.feth.play.module.pa.exceptions.AuthException; + + import controllers.routes; + + public class Global extends GlobalSettings { + + public void onStart(final Application app) { + PlayAuthenticate.setResolver(new Resolver() { + + @Override + public Call login() { + // Your login page + return routes.Application.index(); + } + + @Override + public Call afterAuth() { + // The user will be redirected to this page after authentication + // if no original URL was saved + return routes.Application.index(); + } + + @Override + public Call afterLogout() { + return routes.Application.index(); + } + + @Override + public Call auth(final String provider) { + // You can provide your own authentication implementation, + // however the default should be sufficient for most cases + return com.feth.play.module.pa.controllers.routes.Authenticate + .authenticate(provider); + } + + @Override + public Call onException(final AuthException e) { + if (e instanceof AccessDeniedException) { + return routes.Application + .oAuthDenied(((AccessDeniedException) e) + .getProviderKey()); + } + + // more custom problem handling here... + + return super.onException(e); + } + + @Override + public Call askLink() { + // We don't support moderated account linking in this sample. + // See the play-authenticate-usage project for an example + return null; + } + + @Override + public Call askMerge() { + // We don't support moderated account merging in this sample. + // See the play-authenticate-usage project for an example + return null; + } + }); + } + + } + + +Of course you have to create the pages to which the resolver refers by yourself. + +##User Service Plugin +--- + +We yet have to tell Play-Authenticate how to store users in a database. This is done by creating a sub class +of `com.feth.play.module.pa.service.UserServicePlugin` and implementing the abstract methods of this class. +This subclass has to be registered as a plugin. To do this, create a new text file `play.plugins` in your `conf` folder +(if it does not exist) and add the following line: + + 10005:service.MyUserServicePlugin + +In this line `10005` determines when this plugin is loaded. Plugins with a higher number are loaded first. +`service.MyUserServicePlugin` is the fully qualified class name of your UserService class. + +The `UserService` interface works with `AuthUser` objects. The combination of `getId` and `getProvider` from `AuthUser` can be used to identify an user. + + +- The `getLocalIdentity` function gets called on any login to check whether the session user still has a valid corresponding local user. Returns the local identifying object if the auth provider/id combination has been linked to a local user account already or null if not. +- The `save` method of the UserServicePlugin is called, when the user logs in for the first time (i.e. `getLocalIdentity` returned null for this AuthUser). This method should store the user to the database and return an object identifying the user. +- The `update` method is called when a user logs in. You might make profile updates here with data coming from the login provider or bump a last-logged-in date. +- The `merge` function should merge two different local user accounts to one account. Returns the user to generate the session information from. +- The `link` function links a new account to an existing local user. Returns the auth user to log in with. + + +Here is an example implementation of the UserServicePlugin: + + package service; + + import models.User; + import play.Application; + + import com.feth.play.module.pa.user.AuthUser; + import com.feth.play.module.pa.user.AuthUserIdentity; + import com.feth.play.module.pa.service.UserServicePlugin; + + public class MyUserServicePlugin extends UserServicePlugin { + + public MyUserServicePlugin(final Application app) { + super(app); + } + + @Override + public Object save(final AuthUser authUser) { + final boolean isLinked = User.existsByAuthUserIdentity(authUser); + if (!isLinked) { + return User.create(authUser).id; + } else { + // we have this user already, so return null + return null; + } + } + + @Override + public Object getLocalIdentity(final AuthUserIdentity identity) { + // For production: Caching might be a good idea here... + // ...and dont forget to sync the cache when users get deactivated/deleted + final User u = User.findByAuthUserIdentity(identity); + if(u != null) { + return u.id; + } else { + return null; + } + } + + @Override + public AuthUser merge(final AuthUser newUser, final AuthUser oldUser) { + if (!oldUser.equals(newUser)) { + User.merge(oldUser, newUser); + } + return oldUser; + } + + @Override + public AuthUser link(final AuthUser oldUser, final AuthUser newUser) { + User.addLinkedAccount(oldUser, newUser); + return null; + } + + } + + +##Adding Authentication Providers +--- + +### Google Authentication Provider + +To use google as an authentication provider you first have +to get API keys for your application. You can create your key +using the [Google API console](https://code.google.com/apis/console/). +Go to *API Access* and *Create another client ID*. In the settings you +should add `http://localhost:9000/authenticate/google` as an +*Authorized Redirect URI*. Of course you should adjust this URI to your +application. + +You then have to add the GoogleAuthProvider to the list of plugins +in `conf/play.plugins`. Add the following line: + + 10010:com.feth.play.module.pa.providers.oauth2.google.GoogleAuthProvider + + +Furthermore you need to configure the Google Auth Provider by adding +the following to your `conf/play-authenticate/mine.conf` file (inside +the play-authenticate block): + + google { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Google credentials + # These are mandatory for using OAuth and need to be provided by you, + # if you want to use Google as an authentication provider. + # Get them here: https://code.google.com/apis/console + clientId="180332425123-lbz1g8510ohfu8ecabs10s15a21nf0k.apps.googleusercontent.com" + clientSecret="1ao-clfNeLaXltUNbuUmBzTf" + } + +You have to replace the values for clientId and clientSecret with your +own keys. The keys above are not valid. + + +TODO short description for other providers. + +##Adding Access Control +--- + +TODO + +### Using play.mvc.Security +--- + +TODO + +### Using Deadbolt +--- + +TODO + diff --git a/samples/scala/play-authenticate-usage/.gitignore b/samples/scala/play-authenticate-usage/.gitignore new file mode 100644 index 00000000..47f94a0a --- /dev/null +++ b/samples/scala/play-authenticate-usage/.gitignore @@ -0,0 +1,15 @@ +logs +project/project +project/target +target +tmp +.history +dist +.classpath +.project +.settings +.target +.idea +.idea_modules +bin +RUNNING_PID diff --git a/samples/scala/play-authenticate-usage/Procfile b/samples/scala/play-authenticate-usage/Procfile new file mode 100644 index 00000000..d44e6ef5 --- /dev/null +++ b/samples/scala/play-authenticate-usage/Procfile @@ -0,0 +1 @@ +web: target/start -Dhttp.port=${PORT} -Dplay.version=2.3.2 -DapplyEvolutions.default=true -DapplyDownEvolutions.default=true -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=$DATABASE_URL ${JAVA_OPTS} diff --git a/samples/scala/play-authenticate-usage/README.md b/samples/scala/play-authenticate-usage/README.md new file mode 100644 index 00000000..a0f945f6 --- /dev/null +++ b/samples/scala/play-authenticate-usage/README.md @@ -0,0 +1,6 @@ +# Play Authenticate sample Java application + +Authentication providers that require further configuration parameters +are commented out in `conf/play.plugins`. Please review the configuration +in `conf/play-authenticate/mine.conf` and reenable them if you want to +use them. diff --git a/samples/scala/play-authenticate-usage/app/Global.java b/samples/scala/play-authenticate-usage/app/Global.java new file mode 100644 index 00000000..ae1bbc20 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/Global.java @@ -0,0 +1,83 @@ +import java.util.Arrays; + +import models.SecurityRole; + +import com.feth.play.module.pa.PlayAuthenticate; +import com.feth.play.module.pa.PlayAuthenticate.Resolver; +import com.feth.play.module.pa.exceptions.AccessDeniedException; +import com.feth.play.module.pa.exceptions.AuthException; + +import controllers.routes; + +import play.Application; +import play.GlobalSettings; +import play.mvc.Call; + +public class Global extends GlobalSettings { + + public void onStart(Application app) { + PlayAuthenticate.setResolver(new Resolver() { + + @Override + public Call login() { + // Your login page + return routes.Application.login(); + } + + @Override + public Call afterAuth() { + // The user will be redirected to this page after authentication + // if no original URL was saved + return routes.Application.index(); + } + + @Override + public Call afterLogout() { + return routes.Application.index(); + } + + @Override + public Call auth(final String provider) { + // You can provide your own authentication implementation, + // however the default should be sufficient for most cases + return com.feth.play.module.pa.controllers.routes.Authenticate + .authenticate(provider); + } + + @Override + public Call askMerge() { + return routes.Account.askMerge(); + } + + @Override + public Call askLink() { + return routes.Account.askLink(); + } + + @Override + public Call onException(final AuthException e) { + if (e instanceof AccessDeniedException) { + return routes.Signup + .oAuthDenied(((AccessDeniedException) e) + .getProviderKey()); + } + + // more custom problem handling here... + return super.onException(e); + } + }); + + initialData(); + } + + private void initialData() { + if (SecurityRole.find.findRowCount() == 0) { + for (final String roleName : Arrays + .asList(controllers.Application.USER_ROLE)) { + final SecurityRole role = new SecurityRole(); + role.roleName = roleName; + role.save(); + } + } + } +} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/controllers/Account.java b/samples/scala/play-authenticate-usage/app/controllers/Account.java new file mode 100644 index 00000000..65518e74 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/controllers/Account.java @@ -0,0 +1,219 @@ +package controllers; + +import models.User; +import be.objectify.deadbolt.java.actions.Restrict; +import be.objectify.deadbolt.java.actions.Group; +import be.objectify.deadbolt.java.actions.SubjectPresent; + +import com.feth.play.module.pa.PlayAuthenticate; +import com.feth.play.module.pa.user.AuthUser; + +import play.data.Form; +import play.data.format.Formats.NonEmpty; +import play.data.validation.Constraints.MinLength; +import play.data.validation.Constraints.Required; +import play.i18n.Messages; +import play.mvc.Controller; +import play.mvc.Result; +import providers.MyUsernamePasswordAuthProvider; +import providers.MyUsernamePasswordAuthUser; +import views.html.account.*; + +import static play.data.Form.form; + +public class Account extends Controller { + + public static class Accept { + + @Required + @NonEmpty + public Boolean accept; + + public Boolean getAccept() { + return accept; + } + + public void setAccept(Boolean accept) { + this.accept = accept; + } + + } + + public static class PasswordChange { + @MinLength(5) + @Required + public String password; + + @MinLength(5) + @Required + public String repeatPassword; + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getRepeatPassword() { + return repeatPassword; + } + + public void setRepeatPassword(String repeatPassword) { + this.repeatPassword = repeatPassword; + } + + public String validate() { + if (password == null || !password.equals(repeatPassword)) { + return Messages + .get("playauthenticate.change_password.error.passwords_not_same"); + } + return null; + } + } + + private static final Form ACCEPT_FORM = form(Accept.class); + private static final Form PASSWORD_CHANGE_FORM = form(Account.PasswordChange.class); + + @SubjectPresent + public static Result link() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + return ok(link.render()); + } + + @Restrict(@Group(Application.USER_ROLE)) + public static Result verifyEmail() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final User user = Application.getLocalUser(session()); + if (user.emailValidated) { + // E-Mail has been validated already + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.verify_email.error.already_validated")); + } else if (user.email != null && !user.email.trim().isEmpty()) { + flash(Application.FLASH_MESSAGE_KEY, Messages.get( + "playauthenticate.verify_email.message.instructions_sent", + user.email)); + MyUsernamePasswordAuthProvider.getProvider() + .sendVerifyEmailMailingAfterSignup(user, ctx()); + } else { + flash(Application.FLASH_MESSAGE_KEY, Messages.get( + "playauthenticate.verify_email.error.set_email_first", + user.email)); + } + return redirect(routes.Application.profile()); + } + + @Restrict(@Group(Application.USER_ROLE)) + public static Result changePassword() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final User u = Application.getLocalUser(session()); + + if (!u.emailValidated) { + return ok(unverified.render()); + } else { + return ok(password_change.render(PASSWORD_CHANGE_FORM)); + } + } + + @Restrict(@Group(Application.USER_ROLE)) + public static Result doChangePassword() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final Form filledForm = PASSWORD_CHANGE_FORM + .bindFromRequest(); + if (filledForm.hasErrors()) { + // User did not select whether to link or not link + return badRequest(password_change.render(filledForm)); + } else { + final User user = Application.getLocalUser(session()); + final String newPassword = filledForm.get().password; + user.changePassword(new MyUsernamePasswordAuthUser(newPassword), + true); + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.change_password.success")); + return redirect(routes.Application.profile()); + } + } + + @SubjectPresent + public static Result askLink() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final AuthUser u = PlayAuthenticate.getLinkUser(session()); + if (u == null) { + // account to link could not be found, silently redirect to login + return redirect(routes.Application.index()); + } + return ok(ask_link.render(ACCEPT_FORM, u)); + } + + @SubjectPresent + public static Result doLink() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final AuthUser u = PlayAuthenticate.getLinkUser(session()); + if (u == null) { + // account to link could not be found, silently redirect to login + return redirect(routes.Application.index()); + } + + final Form filledForm = ACCEPT_FORM.bindFromRequest(); + if (filledForm.hasErrors()) { + // User did not select whether to link or not link + return badRequest(ask_link.render(filledForm, u)); + } else { + // User made a choice :) + final boolean link = filledForm.get().accept; + if (link) { + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.accounts.link.success")); + } + return PlayAuthenticate.link(ctx(), link); + } + } + + @SubjectPresent + public static Result askMerge() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + // this is the currently logged in user + final AuthUser aUser = PlayAuthenticate.getUser(session()); + + // this is the user that was selected for a login + final AuthUser bUser = PlayAuthenticate.getMergeUser(session()); + if (bUser == null) { + // user to merge with could not be found, silently redirect to login + return redirect(routes.Application.index()); + } + + // You could also get the local user object here via + // User.findByAuthUserIdentity(newUser) + return ok(ask_merge.render(ACCEPT_FORM, aUser, bUser)); + } + + @SubjectPresent + public static Result doMerge() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + // this is the currently logged in user + final AuthUser aUser = PlayAuthenticate.getUser(session()); + + // this is the user that was selected for a login + final AuthUser bUser = PlayAuthenticate.getMergeUser(session()); + if (bUser == null) { + // user to merge with could not be found, silently redirect to login + return redirect(routes.Application.index()); + } + + final Form filledForm = ACCEPT_FORM.bindFromRequest(); + if (filledForm.hasErrors()) { + // User did not select whether to merge or not merge + return badRequest(ask_merge.render(filledForm, aUser, bUser)); + } else { + // User made a choice :) + final boolean merge = filledForm.get().accept; + if (merge) { + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.accounts.merge.success")); + } + return PlayAuthenticate.merge(ctx(), merge); + } + } + +} diff --git a/samples/scala/play-authenticate-usage/app/controllers/Application.java b/samples/scala/play-authenticate-usage/app/controllers/Application.java new file mode 100644 index 00000000..32868aac --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/controllers/Application.java @@ -0,0 +1,100 @@ +package controllers; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import models.User; +import play.Routes; +import play.data.Form; +import play.mvc.*; +import play.mvc.Http.Response; +import play.mvc.Http.Session; +import play.mvc.Result; +import providers.MyUsernamePasswordAuthProvider; +import providers.MyUsernamePasswordAuthProvider.MyLogin; +import providers.MyUsernamePasswordAuthProvider.MySignup; + +import views.html.*; +import be.objectify.deadbolt.java.actions.Group; +import be.objectify.deadbolt.java.actions.Restrict; + +import com.feth.play.module.pa.PlayAuthenticate; +import com.feth.play.module.pa.providers.password.UsernamePasswordAuthProvider; +import com.feth.play.module.pa.user.AuthUser; + +public class Application extends Controller { + + public static final String FLASH_MESSAGE_KEY = "message"; + public static final String FLASH_ERROR_KEY = "error"; + public static final String USER_ROLE = "user"; + + public static Result index() { + return ok(index.render()); + } + + public static User getLocalUser(final Session session) { + final AuthUser currentAuthUser = PlayAuthenticate.getUser(session); + final User localUser = User.findByAuthUserIdentity(currentAuthUser); + return localUser; + } + + @Restrict(@Group(Application.USER_ROLE)) + public static Result restricted() { + final User localUser = getLocalUser(session()); + return ok(restricted.render(localUser)); + } + + @Restrict(@Group(Application.USER_ROLE)) + public static Result profile() { + final User localUser = getLocalUser(session()); + return ok(profile.render(localUser)); + } + + public static Result login() { + return ok(login.render(MyUsernamePasswordAuthProvider.LOGIN_FORM)); + } + + public static Result doLogin() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final Form filledForm = MyUsernamePasswordAuthProvider.LOGIN_FORM + .bindFromRequest(); + if (filledForm.hasErrors()) { + // User did not fill everything properly + return badRequest(login.render(filledForm)); + } else { + // Everything was filled + return UsernamePasswordAuthProvider.handleLogin(ctx()); + } + } + + public static Result signup() { + return ok(signup.render(MyUsernamePasswordAuthProvider.SIGNUP_FORM)); + } + + public static Result jsRoutes() { + return ok( + Routes.javascriptRouter("jsRoutes", + controllers.routes.javascript.Signup.forgotPassword())) + .as("text/javascript"); + } + + public static Result doSignup() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final Form filledForm = MyUsernamePasswordAuthProvider.SIGNUP_FORM + .bindFromRequest(); + if (filledForm.hasErrors()) { + // User did not fill everything properly + return badRequest(signup.render(filledForm)); + } else { + // Everything was filled + // do something with your part of the form before handling the user + // signup + return UsernamePasswordAuthProvider.handleSignup(ctx()); + } + } + + public static String formatTimestamp(final long t) { + return new SimpleDateFormat("yyyy-dd-MM HH:mm:ss").format(new Date(t)); + } + +} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/controllers/Signup.java b/samples/scala/play-authenticate-usage/app/controllers/Signup.java new file mode 100644 index 00000000..084a113a --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/controllers/Signup.java @@ -0,0 +1,212 @@ +package controllers; + +import models.TokenAction; +import models.TokenAction.Type; +import models.User; +import play.data.Form; +import play.i18n.Messages; +import play.mvc.Controller; +import play.mvc.Result; +import providers.MyLoginUsernamePasswordAuthUser; +import providers.MyUsernamePasswordAuthProvider; +import providers.MyUsernamePasswordAuthProvider.MyIdentity; +import providers.MyUsernamePasswordAuthUser; +import views.html.account.signup.*; + +import com.feth.play.module.pa.PlayAuthenticate; + +import static play.data.Form.form; + +public class Signup extends Controller { + + public static class PasswordReset extends Account.PasswordChange { + + public PasswordReset() { + } + + public PasswordReset(final String token) { + this.token = token; + } + + public String token; + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } + + private static final Form PASSWORD_RESET_FORM = form(PasswordReset.class); + + public static Result unverified() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + return ok(unverified.render()); + } + + private static final Form FORGOT_PASSWORD_FORM = form(MyIdentity.class); + + public static Result forgotPassword(final String email) { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + Form form = FORGOT_PASSWORD_FORM; + if (email != null && !email.trim().isEmpty()) { + form = FORGOT_PASSWORD_FORM.fill(new MyIdentity(email)); + } + return ok(password_forgot.render(form)); + } + + public static Result doForgotPassword() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final Form filledForm = FORGOT_PASSWORD_FORM + .bindFromRequest(); + if (filledForm.hasErrors()) { + // User did not fill in his/her email + return badRequest(password_forgot.render(filledForm)); + } else { + // The email address given *BY AN UNKNWON PERSON* to the form - we + // should find out if we actually have a user with this email + // address and whether password login is enabled for him/her. Also + // only send if the email address of the user has been verified. + final String email = filledForm.get().email; + + // We don't want to expose whether a given email address is signed + // up, so just say an email has been sent, even though it might not + // be true - that's protecting our user privacy. + flash(Application.FLASH_MESSAGE_KEY, + Messages.get( + "playauthenticate.reset_password.message.instructions_sent", + email)); + + final User user = User.findByEmail(email); + if (user != null) { + // yep, we have a user with this email that is active - we do + // not know if the user owning that account has requested this + // reset, though. + final MyUsernamePasswordAuthProvider provider = MyUsernamePasswordAuthProvider + .getProvider(); + // User exists + if (user.emailValidated) { + provider.sendPasswordResetMailing(user, ctx()); + // In case you actually want to let (the unknown person) + // know whether a user was found/an email was sent, use, + // change the flash message + } else { + // We need to change the message here, otherwise the user + // does not understand whats going on - we should not verify + // with the password reset, as a "bad" user could then sign + // up with a fake email via OAuth and get it verified by an + // a unsuspecting user that clicks the link. + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.reset_password.message.email_not_verified")); + + // You might want to re-send the verification email here... + provider.sendVerifyEmailMailingAfterSignup(user, ctx()); + } + } + + return redirect(routes.Application.index()); + } + } + + /** + * Returns a token object if valid, null if not + * + * @param token + * @param type + * @return + */ + private static TokenAction tokenIsValid(final String token, final Type type) { + TokenAction ret = null; + if (token != null && !token.trim().isEmpty()) { + final TokenAction ta = TokenAction.findByToken(token, type); + if (ta != null && ta.isValid()) { + ret = ta; + } + } + + return ret; + } + + public static Result resetPassword(final String token) { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final TokenAction ta = tokenIsValid(token, Type.PASSWORD_RESET); + if (ta == null) { + return badRequest(no_token_or_invalid.render()); + } + + return ok(password_reset.render(PASSWORD_RESET_FORM + .fill(new PasswordReset(token)))); + } + + public static Result doResetPassword() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final Form filledForm = PASSWORD_RESET_FORM + .bindFromRequest(); + if (filledForm.hasErrors()) { + return badRequest(password_reset.render(filledForm)); + } else { + final String token = filledForm.get().token; + final String newPassword = filledForm.get().password; + + final TokenAction ta = tokenIsValid(token, Type.PASSWORD_RESET); + if (ta == null) { + return badRequest(no_token_or_invalid.render()); + } + final User u = ta.targetUser; + try { + // Pass true for the second parameter if you want to + // automatically create a password and the exception never to + // happen + u.resetPassword(new MyUsernamePasswordAuthUser(newPassword), + false); + } catch (final RuntimeException re) { + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.reset_password.message.no_password_account")); + } + final boolean login = MyUsernamePasswordAuthProvider.getProvider() + .isLoginAfterPasswordReset(); + if (login) { + // automatically log in + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.reset_password.message.success.auto_login")); + + return PlayAuthenticate.loginAndRedirect(ctx(), + new MyLoginUsernamePasswordAuthUser(u.email)); + } else { + // send the user to the login page + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.reset_password.message.success.manual_login")); + } + return redirect(routes.Application.login()); + } + } + + public static Result oAuthDenied(final String getProviderKey) { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + return ok(oAuthDenied.render(getProviderKey)); + } + + public static Result exists() { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + return ok(exists.render()); + } + + public static Result verify(final String token) { + com.feth.play.module.pa.controllers.Authenticate.noCache(response()); + final TokenAction ta = tokenIsValid(token, Type.EMAIL_VERIFICATION); + if (ta == null) { + return badRequest(no_token_or_invalid.render()); + } + final String email = ta.targetUser.email; + User.verify(ta.targetUser); + flash(Application.FLASH_MESSAGE_KEY, + Messages.get("playauthenticate.verify_email.success", email)); + if (Application.getLocalUser(session()) != null) { + return redirect(routes.Application.index()); + } else { + return redirect(routes.Application.login()); + } + } +} diff --git a/samples/scala/play-authenticate-usage/app/models/LinkedAccount.java b/samples/scala/play-authenticate-usage/app/models/LinkedAccount.java new file mode 100644 index 00000000..517b62d9 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/models/LinkedAccount.java @@ -0,0 +1,54 @@ +package models; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +import play.db.ebean.Model; + +import com.feth.play.module.pa.user.AuthUser; + +@Entity +public class LinkedAccount extends Model { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + public Long id; + + @ManyToOne + public User user; + + public String providerUserId; + public String providerKey; + + public static final Finder find = new Finder( + Long.class, LinkedAccount.class); + + public static LinkedAccount findByProviderKey(final User user, String key) { + return find.where().eq("user", user).eq("providerKey", key) + .findUnique(); + } + + public static LinkedAccount create(final AuthUser authUser) { + final LinkedAccount ret = new LinkedAccount(); + ret.update(authUser); + return ret; + } + + public void update(final AuthUser authUser) { + this.providerKey = authUser.getProvider(); + this.providerUserId = authUser.getId(); + } + + public static LinkedAccount create(final LinkedAccount acc) { + final LinkedAccount ret = new LinkedAccount(); + ret.providerKey = acc.providerKey; + ret.providerUserId = acc.providerUserId; + + return ret; + } +} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/models/SecurityRole.java b/samples/scala/play-authenticate-usage/app/models/SecurityRole.java new file mode 100644 index 00000000..79efbaf9 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/models/SecurityRole.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012 Steve Chaloner + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package models; + +import javax.persistence.Entity; +import javax.persistence.Id; + +import play.db.ebean.Model; +import be.objectify.deadbolt.core.models.Role; + +/** + * @author Steve Chaloner (steve@objectify.be) + */ +@Entity +public class SecurityRole extends Model implements Role { + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + public Long id; + + public String roleName; + + public static final Finder find = new Finder( + Long.class, SecurityRole.class); + + @Override + public String getName() { + return roleName; + } + + public static SecurityRole findByRoleName(String roleName) { + return find.where().eq("roleName", roleName).findUnique(); + } +} diff --git a/samples/scala/play-authenticate-usage/app/models/TokenAction.java b/samples/scala/play-authenticate-usage/app/models/TokenAction.java new file mode 100644 index 00000000..62f0b5d8 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/models/TokenAction.java @@ -0,0 +1,87 @@ +package models; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +import play.data.format.Formats; +import play.db.ebean.Model; + +import com.avaje.ebean.Ebean; +import com.avaje.ebean.QueryIterator; +import com.avaje.ebean.annotation.EnumValue; + +@Entity +public class TokenAction extends Model { + + public enum Type { + @EnumValue("EV") + EMAIL_VERIFICATION, + + @EnumValue("PR") + PASSWORD_RESET + } + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Verification time frame (until the user clicks on the link in the email) + * in seconds + * Defaults to one week + */ + private final static long VERIFICATION_TIME = 7 * 24 * 3600; + + @Id + public Long id; + + @Column(unique = true) + public String token; + + @ManyToOne + public User targetUser; + + public Type type; + + @Formats.DateTime(pattern = "yyyy-MM-dd HH:mm:ss") + public Date created; + + @Formats.DateTime(pattern = "yyyy-MM-dd HH:mm:ss") + public Date expires; + + public static final Finder find = new Finder( + Long.class, TokenAction.class); + + public static TokenAction findByToken(final String token, final Type type) { + return find.where().eq("token", token).eq("type", type).findUnique(); + } + + public static void deleteByUser(final User u, final Type type) { + QueryIterator iterator = find.where() + .eq("targetUser.id", u.id).eq("type", type).findIterate(); + Ebean.delete(iterator); + iterator.close(); + } + + public boolean isValid() { + return this.expires.after(new Date()); + } + + public static TokenAction create(final Type type, final String token, + final User targetUser) { + final TokenAction ua = new TokenAction(); + ua.targetUser = targetUser; + ua.token = token; + ua.type = type; + final Date created = new Date(); + ua.created = created; + ua.expires = new Date(created.getTime() + VERIFICATION_TIME * 1000); + ua.save(); + return ua; + } +} diff --git a/samples/scala/play-authenticate-usage/app/models/User.java b/samples/scala/play-authenticate-usage/app/models/User.java new file mode 100644 index 00000000..58565eb8 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/models/User.java @@ -0,0 +1,249 @@ +package models; + +import be.objectify.deadbolt.core.models.Permission; +import be.objectify.deadbolt.core.models.Role; +import be.objectify.deadbolt.core.models.Subject; +import com.avaje.ebean.Ebean; +import com.avaje.ebean.ExpressionList; +import com.feth.play.module.pa.providers.password.UsernamePasswordAuthUser; +import com.feth.play.module.pa.user.AuthUser; +import com.feth.play.module.pa.user.AuthUserIdentity; +import com.feth.play.module.pa.user.EmailIdentity; +import com.feth.play.module.pa.user.NameIdentity; +import com.feth.play.module.pa.user.FirstLastNameIdentity; +import models.TokenAction.Type; +import play.data.format.Formats; +import play.data.validation.Constraints; +import play.db.ebean.Model; + +import javax.persistence.*; +import java.util.*; + +/** + * Initial version based on work by Steve Chaloner (steve@objectify.be) for + * Deadbolt2 + */ +@Entity +@Table(name = "users") +public class User extends Model implements Subject { + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + public Long id; + + @Constraints.Email + // if you make this unique, keep in mind that users *must* merge/link their + // accounts then on signup with additional providers + // @Column(unique = true) + public String email; + + public String name; + + public String firstName; + + public String lastName; + + @Formats.DateTime(pattern = "yyyy-MM-dd HH:mm:ss") + public Date lastLogin; + + public boolean active; + + public boolean emailValidated; + + @ManyToMany + public List roles; + + @OneToMany(cascade = CascadeType.ALL) + public List linkedAccounts; + + @ManyToMany + public List permissions; + + public static final Finder find = new Finder( + Long.class, User.class); + + @Override + public String getIdentifier() + { + return Long.toString(id); + } + + @Override + public List getRoles() { + return roles; + } + + @Override + public List getPermissions() { + return permissions; + } + + public static boolean existsByAuthUserIdentity( + final AuthUserIdentity identity) { + final ExpressionList exp; + if (identity instanceof UsernamePasswordAuthUser) { + exp = getUsernamePasswordAuthUserFind((UsernamePasswordAuthUser) identity); + } else { + exp = getAuthUserFind(identity); + } + return exp.findRowCount() > 0; + } + + private static ExpressionList getAuthUserFind( + final AuthUserIdentity identity) { + return find.where().eq("active", true) + .eq("linkedAccounts.providerUserId", identity.getId()) + .eq("linkedAccounts.providerKey", identity.getProvider()); + } + + public static User findByAuthUserIdentity(final AuthUserIdentity identity) { + if (identity == null) { + return null; + } + if (identity instanceof UsernamePasswordAuthUser) { + return findByUsernamePasswordIdentity((UsernamePasswordAuthUser) identity); + } else { + return getAuthUserFind(identity).findUnique(); + } + } + + public static User findByUsernamePasswordIdentity( + final UsernamePasswordAuthUser identity) { + return getUsernamePasswordAuthUserFind(identity).findUnique(); + } + + private static ExpressionList getUsernamePasswordAuthUserFind( + final UsernamePasswordAuthUser identity) { + return getEmailUserFind(identity.getEmail()).eq( + "linkedAccounts.providerKey", identity.getProvider()); + } + + public void merge(final User otherUser) { + for (final LinkedAccount acc : otherUser.linkedAccounts) { + this.linkedAccounts.add(LinkedAccount.create(acc)); + } + // do all other merging stuff here - like resources, etc. + + // deactivate the merged user that got added to this one + otherUser.active = false; + Ebean.save(Arrays.asList(new User[] { otherUser, this })); + } + + public static User create(final AuthUser authUser) { + final User user = new User(); + user.roles = Collections.singletonList(SecurityRole + .findByRoleName(controllers.Application.USER_ROLE)); + // user.permissions = new ArrayList(); + // user.permissions.add(UserPermission.findByValue("printers.edit")); + user.active = true; + user.lastLogin = new Date(); + user.linkedAccounts = Collections.singletonList(LinkedAccount + .create(authUser)); + + if (authUser instanceof EmailIdentity) { + final EmailIdentity identity = (EmailIdentity) authUser; + // Remember, even when getting them from FB & Co., emails should be + // verified within the application as a security breach there might + // break your security as well! + user.email = identity.getEmail(); + user.emailValidated = false; + } + + if (authUser instanceof NameIdentity) { + final NameIdentity identity = (NameIdentity) authUser; + final String name = identity.getName(); + if (name != null) { + user.name = name; + } + } + + if (authUser instanceof FirstLastNameIdentity) { + final FirstLastNameIdentity identity = (FirstLastNameIdentity) authUser; + final String firstName = identity.getFirstName(); + final String lastName = identity.getLastName(); + if (firstName != null) { + user.firstName = firstName; + } + if (lastName != null) { + user.lastName = lastName; + } + } + + user.save(); + user.saveManyToManyAssociations("roles"); + // user.saveManyToManyAssociations("permissions"); + return user; + } + + public static void merge(final AuthUser oldUser, final AuthUser newUser) { + User.findByAuthUserIdentity(oldUser).merge( + User.findByAuthUserIdentity(newUser)); + } + + public Set getProviders() { + final Set providerKeys = new HashSet( + linkedAccounts.size()); + for (final LinkedAccount acc : linkedAccounts) { + providerKeys.add(acc.providerKey); + } + return providerKeys; + } + + public static void addLinkedAccount(final AuthUser oldUser, + final AuthUser newUser) { + final User u = User.findByAuthUserIdentity(oldUser); + u.linkedAccounts.add(LinkedAccount.create(newUser)); + u.save(); + } + + public static void setLastLoginDate(final AuthUser knownUser) { + final User u = User.findByAuthUserIdentity(knownUser); + u.lastLogin = new Date(); + u.save(); + } + + public static User findByEmail(final String email) { + return getEmailUserFind(email).findUnique(); + } + + private static ExpressionList getEmailUserFind(final String email) { + return find.where().eq("active", true).eq("email", email); + } + + public LinkedAccount getAccountByProvider(final String providerKey) { + return LinkedAccount.findByProviderKey(this, providerKey); + } + + public static void verify(final User unverified) { + // You might want to wrap this into a transaction + unverified.emailValidated = true; + unverified.save(); + TokenAction.deleteByUser(unverified, Type.EMAIL_VERIFICATION); + } + + public void changePassword(final UsernamePasswordAuthUser authUser, + final boolean create) { + LinkedAccount a = this.getAccountByProvider(authUser.getProvider()); + if (a == null) { + if (create) { + a = LinkedAccount.create(authUser); + a.user = this; + } else { + throw new RuntimeException( + "Account not enabled for password usage"); + } + } + a.providerUserId = authUser.getHashedPassword(); + a.save(); + } + + public void resetPassword(final UsernamePasswordAuthUser authUser, + final boolean create) { + // You might want to wrap this into a transaction + this.changePassword(authUser, create); + TokenAction.deleteByUser(this, Type.PASSWORD_RESET); + } +} diff --git a/samples/scala/play-authenticate-usage/app/models/UserPermission.java b/samples/scala/play-authenticate-usage/app/models/UserPermission.java new file mode 100644 index 00000000..f6120042 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/models/UserPermission.java @@ -0,0 +1,35 @@ +package models; + +import javax.persistence.Entity; +import javax.persistence.Id; + +import play.db.ebean.Model; +import be.objectify.deadbolt.core.models.Permission; + +/** + * Initial version based on work by Steve Chaloner (steve@objectify.be) for + * Deadbolt2 + */ +@Entity +public class UserPermission extends Model implements Permission { + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + public Long id; + + public String value; + + public static final Model.Finder find = new Model.Finder( + Long.class, UserPermission.class); + + public String getValue() { + return value; + } + + public static UserPermission findByValue(String value) { + return find.where().eq("value", value).findUnique(); + } +} diff --git a/samples/scala/play-authenticate-usage/app/providers/MyLoginUsernamePasswordAuthUser.java b/samples/scala/play-authenticate-usage/app/providers/MyLoginUsernamePasswordAuthUser.java new file mode 100644 index 00000000..5685e082 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/providers/MyLoginUsernamePasswordAuthUser.java @@ -0,0 +1,40 @@ +package providers; + +import com.feth.play.module.pa.providers.password.DefaultUsernamePasswordAuthUser; + +public class MyLoginUsernamePasswordAuthUser extends + DefaultUsernamePasswordAuthUser { + + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * The session timeout in seconds + * Defaults to two weeks + */ + final static long SESSION_TIMEOUT = 24 * 14 * 3600; + private long expiration; + + /** + * For logging the user in automatically + * + * @param email + */ + public MyLoginUsernamePasswordAuthUser(final String email) { + this(null, email); + } + + public MyLoginUsernamePasswordAuthUser(final String clearPassword, + final String email) { + super(clearPassword, email); + + expiration = System.currentTimeMillis() + 1000 * SESSION_TIMEOUT; + } + + @Override + public long expires() { + return expiration; + } + +} diff --git a/samples/scala/play-authenticate-usage/app/providers/MyStupidBasicAuthProvider.java b/samples/scala/play-authenticate-usage/app/providers/MyStupidBasicAuthProvider.java new file mode 100644 index 00000000..a6560806 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/providers/MyStupidBasicAuthProvider.java @@ -0,0 +1,63 @@ +/* + * Copyright © 2014 Florian Hars, nMIT Solutions GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package providers; + +import play.Application; +import play.twirl.api.Content; +import play.mvc.Http.Context; +import views.html.login; + +import com.feth.play.module.pa.providers.wwwauth.basic.BasicAuthProvider; +import com.feth.play.module.pa.user.AuthUser; + +/** A really simple basic auth provider that accepts one hard coded user */ +public class MyStupidBasicAuthProvider extends BasicAuthProvider { + + public MyStupidBasicAuthProvider(Application app) { + super(app); + } + + @Override + protected AuthUser authenticateUser(String username, String password) { + if (username.equals("example") && password.equals("secret")) { + return new AuthUser() { + private static final long serialVersionUID = 1L; + + @Override + public String getId() { + return "example"; + } + + @Override + public String getProvider() { + return "basic"; + } + }; + } + return null; + } + + @Override + public String getKey() { + return "basic"; + } + + /** Diplay the normal login form if HTTP authentication fails */ + @Override + protected Content unauthorized(Context context) { + return login.render(MyUsernamePasswordAuthProvider.LOGIN_FORM); + } +} diff --git a/samples/scala/play-authenticate-usage/app/providers/MyUsernamePasswordAuthProvider.java b/samples/scala/play-authenticate-usage/app/providers/MyUsernamePasswordAuthProvider.java new file mode 100644 index 00000000..43087fa6 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/providers/MyUsernamePasswordAuthProvider.java @@ -0,0 +1,386 @@ +package providers; + +import com.feth.play.module.mail.Mailer.Mail.Body; +import com.feth.play.module.pa.PlayAuthenticate; +import com.feth.play.module.pa.providers.password.UsernamePasswordAuthProvider; +import com.feth.play.module.pa.providers.password.UsernamePasswordAuthUser; +import controllers.routes; +import models.LinkedAccount; +import models.TokenAction; +import models.TokenAction.Type; +import models.User; +import play.Application; +import play.Logger; +import play.data.Form; +import play.data.validation.Constraints.Email; +import play.data.validation.Constraints.MinLength; +import play.data.validation.Constraints.Required; +import play.i18n.Lang; +import play.i18n.Messages; +import play.mvc.Call; +import play.mvc.Http.Context; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static play.data.Form.form; + +public class MyUsernamePasswordAuthProvider + extends + UsernamePasswordAuthProvider { + + private static final String SETTING_KEY_VERIFICATION_LINK_SECURE = SETTING_KEY_MAIL + + "." + "verificationLink.secure"; + private static final String SETTING_KEY_PASSWORD_RESET_LINK_SECURE = SETTING_KEY_MAIL + + "." + "passwordResetLink.secure"; + private static final String SETTING_KEY_LINK_LOGIN_AFTER_PASSWORD_RESET = "loginAfterPasswordReset"; + + private static final String EMAIL_TEMPLATE_FALLBACK_LANGUAGE = "en"; + + @Override + protected List neededSettingKeys() { + final List needed = new ArrayList( + super.neededSettingKeys()); + needed.add(SETTING_KEY_VERIFICATION_LINK_SECURE); + needed.add(SETTING_KEY_PASSWORD_RESET_LINK_SECURE); + needed.add(SETTING_KEY_LINK_LOGIN_AFTER_PASSWORD_RESET); + return needed; + } + + public static MyUsernamePasswordAuthProvider getProvider() { + return (MyUsernamePasswordAuthProvider) PlayAuthenticate + .getProvider(UsernamePasswordAuthProvider.PROVIDER_KEY); + } + + public static class MyIdentity { + + public MyIdentity() { + } + + public MyIdentity(final String email) { + this.email = email; + } + + @Required + @Email + public String email; + + } + + public static class MyLogin extends MyIdentity + implements + com.feth.play.module.pa.providers.password.UsernamePasswordAuthProvider.UsernamePassword { + + @Required + @MinLength(5) + public String password; + + @Override + public String getEmail() { + return email; + } + + @Override + public String getPassword() { + return password; + } + } + + public static class MySignup extends MyLogin { + + @Required + @MinLength(5) + public String repeatPassword; + + @Required + public String name; + + public String validate() { + if (password == null || !password.equals(repeatPassword)) { + return Messages + .get("playauthenticate.password.signup.error.passwords_not_same"); + } + return null; + } + } + + public static final Form SIGNUP_FORM = form(MySignup.class); + public static final Form LOGIN_FORM = form(MyLogin.class); + + public MyUsernamePasswordAuthProvider(Application app) { + super(app); + } + + protected Form getSignupForm() { + return SIGNUP_FORM; + } + + protected Form getLoginForm() { + return LOGIN_FORM; + } + + @Override + protected com.feth.play.module.pa.providers.password.UsernamePasswordAuthProvider.SignupResult signupUser(final MyUsernamePasswordAuthUser user) { + final User u = User.findByUsernamePasswordIdentity(user); + if (u != null) { + if (u.emailValidated) { + // This user exists, has its email validated and is active + return SignupResult.USER_EXISTS; + } else { + // this user exists, is active but has not yet validated its + // email + return SignupResult.USER_EXISTS_UNVERIFIED; + } + } + // The user either does not exist or is inactive - create a new one + @SuppressWarnings("unused") + final User newUser = User.create(user); + // Usually the email should be verified before allowing login, however + // if you return + // return SignupResult.USER_CREATED; + // then the user gets logged in directly + return SignupResult.USER_CREATED_UNVERIFIED; + } + + @Override + protected com.feth.play.module.pa.providers.password.UsernamePasswordAuthProvider.LoginResult loginUser( + final MyLoginUsernamePasswordAuthUser authUser) { + final User u = User.findByUsernamePasswordIdentity(authUser); + if (u == null) { + return LoginResult.NOT_FOUND; + } else { + if (!u.emailValidated) { + return LoginResult.USER_UNVERIFIED; + } else { + for (final LinkedAccount acc : u.linkedAccounts) { + if (getKey().equals(acc.providerKey)) { + if (authUser.checkPassword(acc.providerUserId, + authUser.getPassword())) { + // Password was correct + return LoginResult.USER_LOGGED_IN; + } else { + // if you don't return here, + // you would allow the user to have + // multiple passwords defined + // usually we don't want this + return LoginResult.WRONG_PASSWORD; + } + } + } + return LoginResult.WRONG_PASSWORD; + } + } + } + + @Override + protected Call userExists(final UsernamePasswordAuthUser authUser) { + return routes.Signup.exists(); + } + + @Override + protected Call userUnverified(final UsernamePasswordAuthUser authUser) { + return routes.Signup.unverified(); + } + + @Override + protected MyUsernamePasswordAuthUser buildSignupAuthUser( + final MySignup signup, final Context ctx) { + return new MyUsernamePasswordAuthUser(signup); + } + + @Override + protected MyLoginUsernamePasswordAuthUser buildLoginAuthUser( + final MyLogin login, final Context ctx) { + return new MyLoginUsernamePasswordAuthUser(login.getPassword(), + login.getEmail()); + } + + + @Override + protected MyLoginUsernamePasswordAuthUser transformAuthUser(final MyUsernamePasswordAuthUser authUser, final Context context) { + return new MyLoginUsernamePasswordAuthUser(authUser.getEmail()); + } + + @Override + protected String getVerifyEmailMailingSubject( + final MyUsernamePasswordAuthUser user, final Context ctx) { + return Messages.get("playauthenticate.password.verify_signup.subject"); + } + + @Override + protected String onLoginUserNotFound(final Context context) { + context.flash() + .put(controllers.Application.FLASH_ERROR_KEY, + Messages.get("playauthenticate.password.login.unknown_user_or_pw")); + return super.onLoginUserNotFound(context); + } + + @Override + protected Body getVerifyEmailMailingBody(final String token, + final MyUsernamePasswordAuthUser user, final Context ctx) { + + final boolean isSecure = getConfiguration().getBoolean( + SETTING_KEY_VERIFICATION_LINK_SECURE); + final String url = routes.Signup.verify(token).absoluteURL( + ctx.request(), isSecure); + + final Lang lang = Lang.preferred(ctx.request().acceptLanguages()); + final String langCode = lang.code(); + + final String html = getEmailTemplate( + "views.html.account.signup.email.verify_email", langCode, url, + token, user.getName(), user.getEmail()); + final String text = getEmailTemplate( + "views.txt.account.signup.email.verify_email", langCode, url, + token, user.getName(), user.getEmail()); + + return new Body(text, html); + } + + private static String generateToken() { + return UUID.randomUUID().toString(); + } + + @Override + protected String generateVerificationRecord( + final MyUsernamePasswordAuthUser user) { + return generateVerificationRecord(User.findByAuthUserIdentity(user)); + } + + protected String generateVerificationRecord(final User user) { + final String token = generateToken(); + // Do database actions, etc. + TokenAction.create(Type.EMAIL_VERIFICATION, token, user); + return token; + } + + protected String generatePasswordResetRecord(final User u) { + final String token = generateToken(); + TokenAction.create(Type.PASSWORD_RESET, token, u); + return token; + } + + protected String getPasswordResetMailingSubject(final User user, + final Context ctx) { + return Messages.get("playauthenticate.password.reset_email.subject"); + } + + protected Body getPasswordResetMailingBody(final String token, + final User user, final Context ctx) { + + final boolean isSecure = getConfiguration().getBoolean( + SETTING_KEY_PASSWORD_RESET_LINK_SECURE); + final String url = routes.Signup.resetPassword(token).absoluteURL( + ctx.request(), isSecure); + + final Lang lang = Lang.preferred(ctx.request().acceptLanguages()); + final String langCode = lang.code(); + + final String html = getEmailTemplate( + "views.html.account.email.password_reset", langCode, url, + token, user.name, user.email); + final String text = getEmailTemplate( + "views.txt.account.email.password_reset", langCode, url, token, + user.name, user.email); + + return new Body(text, html); + } + + public void sendPasswordResetMailing(final User user, final Context ctx) { + final String token = generatePasswordResetRecord(user); + final String subject = getPasswordResetMailingSubject(user, ctx); + final Body body = getPasswordResetMailingBody(token, user, ctx); + sendMail(subject, body, getEmailName(user)); + } + + public boolean isLoginAfterPasswordReset() { + return getConfiguration().getBoolean( + SETTING_KEY_LINK_LOGIN_AFTER_PASSWORD_RESET); + } + + protected String getVerifyEmailMailingSubjectAfterSignup(final User user, + final Context ctx) { + return Messages.get("playauthenticate.password.verify_email.subject"); + } + + protected String getEmailTemplate(final String template, + final String langCode, final String url, final String token, + final String name, final String email) { + Class cls = null; + String ret = null; + try { + cls = Class.forName(template + "_" + langCode); + } catch (ClassNotFoundException e) { + Logger.warn("Template: '" + + template + + "_" + + langCode + + "' was not found! Trying to use English fallback template instead."); + } + if (cls == null) { + try { + cls = Class.forName(template + "_" + + EMAIL_TEMPLATE_FALLBACK_LANGUAGE); + } catch (ClassNotFoundException e) { + Logger.error("Fallback template: '" + template + "_" + + EMAIL_TEMPLATE_FALLBACK_LANGUAGE + + "' was not found either!"); + } + } + if (cls != null) { + Method htmlRender = null; + try { + htmlRender = cls.getMethod("render", String.class, + String.class, String.class, String.class); + ret = htmlRender.invoke(null, url, token, name, email) + .toString(); + + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + return ret; + } + + protected Body getVerifyEmailMailingBodyAfterSignup(final String token, + final User user, final Context ctx) { + + final boolean isSecure = getConfiguration().getBoolean( + SETTING_KEY_VERIFICATION_LINK_SECURE); + final String url = routes.Signup.verify(token).absoluteURL( + ctx.request(), isSecure); + + final Lang lang = Lang.preferred(ctx.request().acceptLanguages()); + final String langCode = lang.code(); + + final String html = getEmailTemplate( + "views.html.account.email.verify_email", langCode, url, token, + user.name, user.email); + final String text = getEmailTemplate( + "views.txt.account.email.verify_email", langCode, url, token, + user.name, user.email); + + return new Body(text, html); + } + + public void sendVerifyEmailMailingAfterSignup(final User user, + final Context ctx) { + + final String subject = getVerifyEmailMailingSubjectAfterSignup(user, + ctx); + final String token = generateVerificationRecord(user); + final Body body = getVerifyEmailMailingBodyAfterSignup(token, user, ctx); + sendMail(subject, body, getEmailName(user)); + } + + private String getEmailName(final User user) { + return getEmailName(user.email, user.name); + } +} diff --git a/samples/scala/play-authenticate-usage/app/providers/MyUsernamePasswordAuthUser.java b/samples/scala/play-authenticate-usage/app/providers/MyUsernamePasswordAuthUser.java new file mode 100644 index 00000000..b5432b3d --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/providers/MyUsernamePasswordAuthUser.java @@ -0,0 +1,35 @@ +package providers; + +import providers.MyUsernamePasswordAuthProvider.MySignup; + +import com.feth.play.module.pa.providers.password.UsernamePasswordAuthUser; +import com.feth.play.module.pa.user.NameIdentity; + +public class MyUsernamePasswordAuthUser extends UsernamePasswordAuthUser + implements NameIdentity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private final String name; + + public MyUsernamePasswordAuthUser(final MySignup signup) { + super(signup.password, signup.email); + this.name = signup.name; + } + + /** + * Used for password reset only - do not use this to signup a user! + * @param password + */ + public MyUsernamePasswordAuthUser(final String password) { + super(password, null); + name = null; + } + + @Override + public String getName() { + return name; + } +} diff --git a/samples/scala/play-authenticate-usage/app/security/MyDeadboltHandler.java b/samples/scala/play-authenticate-usage/app/security/MyDeadboltHandler.java new file mode 100644 index 00000000..0a89a429 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/security/MyDeadboltHandler.java @@ -0,0 +1,72 @@ +package security; + +import models.User; +import play.libs.F; +import play.mvc.Http; +import play.mvc.Result; +import be.objectify.deadbolt.java.AbstractDeadboltHandler; +import be.objectify.deadbolt.java.DynamicResourceHandler; +import be.objectify.deadbolt.core.models.Subject; + +import com.feth.play.module.pa.PlayAuthenticate; +import com.feth.play.module.pa.user.AuthUserIdentity; + +public class MyDeadboltHandler extends AbstractDeadboltHandler { + + @Override + public F.Promise beforeAuthCheck(final Http.Context context) { + if (PlayAuthenticate.isLoggedIn(context.session())) { + // user is logged in + return F.Promise.pure(null); + } else { + // user is not logged in + + // call this if you want to redirect your visitor to the page that + // was requested before sending him to the login page + // if you don't call this, the user will get redirected to the page + // defined by your resolver + final String originalUrl = PlayAuthenticate + .storeOriginalUrl(context); + + context.flash().put("error", + "You need to log in first, to view '" + originalUrl + "'"); + return F.Promise.promise(new F.Function0() + { + @Override + public Result apply() throws Throwable + { + return redirect(PlayAuthenticate.getResolver().login()); + } + }); + } + } + + @Override + public Subject getSubject(final Http.Context context) { + final AuthUserIdentity u = PlayAuthenticate.getUser(context); + // Caching might be a good idea here + return User.findByAuthUserIdentity(u); + } + + @Override + public DynamicResourceHandler getDynamicResourceHandler( + final Http.Context context) { + return null; + } + + @Override + public F.Promise onAuthFailure(final Http.Context context, + final String content) { + // if the user has a cookie with a valid user and the local user has + // been deactivated/deleted in between, it is possible that this gets + // shown. You might want to consider to sign the user out in this case. + return F.Promise.promise(new F.Function0() + { + @Override + public Result apply() throws Throwable + { + return forbidden("Forbidden"); + } + }); + } +} diff --git a/samples/scala/play-authenticate-usage/app/service/MyUserServicePlugin.java b/samples/scala/play-authenticate-usage/app/service/MyUserServicePlugin.java new file mode 100644 index 00000000..be3b1628 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/service/MyUserServicePlugin.java @@ -0,0 +1,60 @@ +package service; + +import models.User; +import play.Application; + +import com.feth.play.module.pa.user.AuthUser; +import com.feth.play.module.pa.user.AuthUserIdentity; +import com.feth.play.module.pa.service.UserServicePlugin; + +public class MyUserServicePlugin extends UserServicePlugin { + + public MyUserServicePlugin(final Application app) { + super(app); + } + + @Override + public Object save(final AuthUser authUser) { + final boolean isLinked = User.existsByAuthUserIdentity(authUser); + if (!isLinked) { + return User.create(authUser).id; + } else { + // we have this user already, so return null + return null; + } + } + + @Override + public Object getLocalIdentity(final AuthUserIdentity identity) { + // For production: Caching might be a good idea here... + // ...and dont forget to sync the cache when users get deactivated/deleted + final User u = User.findByAuthUserIdentity(identity); + if(u != null) { + return u.id; + } else { + return null; + } + } + + @Override + public AuthUser merge(final AuthUser newUser, final AuthUser oldUser) { + if (!oldUser.equals(newUser)) { + User.merge(oldUser, newUser); + } + return oldUser; + } + + @Override + public AuthUser link(final AuthUser oldUser, final AuthUser newUser) { + User.addLinkedAccount(oldUser, newUser); + return newUser; + } + + @Override + public AuthUser update(final AuthUser knownUser) { + // User logged in again, bump last login date + User.setLastLoginDate(knownUser); + return knownUser; + } + +} diff --git a/samples/scala/play-authenticate-usage/app/views/_emailPartial.scala.html b/samples/scala/play-authenticate-usage/app/views/_emailPartial.scala.html new file mode 100644 index 00000000..60475c5c --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/_emailPartial.scala.html @@ -0,0 +1,10 @@ +@(f: Form[_], constraints: Boolean = false) + +@import helper._ +@import helper.twitterBootstrap._ + +@inputText( + f("email"), + '_showConstraints -> constraints, + '_label -> Messages("playauthenticate.login.email.placeholder") +) \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/_passwordPartial.scala.html b/samples/scala/play-authenticate-usage/app/views/_passwordPartial.scala.html new file mode 100644 index 00000000..4b8eb2f1 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/_passwordPartial.scala.html @@ -0,0 +1,16 @@ +@(f: Form[_]) + +@import helper._ +@import helper.twitterBootstrap._ + + @inputPassword( + f("password"), + '_label -> Messages("playauthenticate.login.password.placeholder") + ) + + @inputPassword( + f("repeatPassword"), + '_label -> Messages("playauthenticate.login.password.repeat"), + '_showConstraints -> false, + '_error -> f.error("password") + ) \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/_providerIcon.scala.html b/samples/scala/play-authenticate-usage/app/views/_providerIcon.scala.html new file mode 100644 index 00000000..bce8c151 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/_providerIcon.scala.html @@ -0,0 +1,2 @@ +@(providerKey: String) +@providerKey icon \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/_providerPartial.scala.html b/samples/scala/play-authenticate-usage/app/views/_providerPartial.scala.html new file mode 100644 index 00000000..c36559eb --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/_providerPartial.scala.html @@ -0,0 +1,24 @@ +@(skipCurrent: Boolean = true) + +@import com.feth.play.module.pa.views.html._ + + + \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/ask_link.scala.html b/samples/scala/play-authenticate-usage/app/views/account/ask_link.scala.html new file mode 100644 index 00000000..fa015f4b --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/ask_link.scala.html @@ -0,0 +1,35 @@ +@(acceptForm: Form[Account.Accept], newAccount: com.feth.play.module.pa.user.AuthUser) + +@import helper._ +@import helper.twitterBootstrap._ + +@label = { + @_providerIcon(newAccount.getProvider()) @Messages("playauthenticate.link.account.question",newAccount) +} + +@main(Messages("playauthenticate.link.account.title")) { + +

@Messages("playauthenticate.link.account.title")

+

+ @form(routes.Account.doLink) { + + @if(acceptForm.hasGlobalErrors) { +

+ @acceptForm.globalError.message +

+ } + + @inputRadioGroup( + acceptForm("accept"), + options = Seq( + "true"-> Messages("playauthenticate.link.account.true"), + "false"->Messages("playauthenticate.link.account.false") + ), + '_label -> label, + '_showConstraints -> false + ) + + + } +

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/ask_merge.scala.html b/samples/scala/play-authenticate-usage/app/views/account/ask_merge.scala.html new file mode 100644 index 00000000..1f2ced44 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/ask_merge.scala.html @@ -0,0 +1,35 @@ +@(acceptForm: Form[Account.Accept], aUser: com.feth.play.module.pa.user.AuthUser, bUser: com.feth.play.module.pa.user.AuthUser) + +@import helper._ +@import helper.twitterBootstrap._ + +@label = { + @Messages("playauthenticate.merge.accounts.question",aUser,bUser) +} + +@main(Messages("playauthenticate.merge.accounts.title")) { + +

@Messages("playauthenticate.merge.accounts.title")

+

+ @form(routes.Account.doMerge) { + + @if(acceptForm.hasGlobalErrors) { +

+ @acceptForm.globalError.message +

+ } + + @inputRadioGroup( + acceptForm("accept"), + options = Seq( + "true"-> Messages("playauthenticate.merge.accounts.true"), + "false"->Messages("playauthenticate.merge.accounts.false") + ), + '_label -> label, + '_showConstraints -> false + ) + + + } +

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_de.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_de.scala.html new file mode 100644 index 00000000..34a3e7d8 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_de.scala.html @@ -0,0 +1,15 @@ +@(url: String, token: String, name: String, email: String) +Hey @name, +
+
+

+ du oder jemand anderes hat die Möglichkeit zum Zurücksetzen deines Passwortes genutzt.
+ Falls dies nicht du selbst oder deine Absicht war, kannst du diese E-Mail einfach ignorieren.
+

+

+ Falls du dein Passwort zurücksetzen möchtest, musst du nur diesem Link folgen. +

+

+ Grüße,
+ Das PlayAuthenticate-Team +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_de.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_de.scala.txt new file mode 100644 index 00000000..bb4612b1 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_de.scala.txt @@ -0,0 +1,12 @@ +@(url: String, token: String, name: String, email: String)Hey @name, + + +du oder jemand anderes hat die Möglichkeit zum Zurücksetzen deines Passwortes genutzt. +Falls dies nicht du selbst oder deine Absicht war, kannst du diese E-Mail einfach ignorieren. + +Falls du dein Passwort zurücksetzen möchtest, musst du nur diesem Link folgen: + +@url + +Grüße, +Das PlayAuthenticate-Team \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_en.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_en.scala.html new file mode 100644 index 00000000..d0a5a0e4 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_en.scala.html @@ -0,0 +1,15 @@ +@(url: String, token: String, name: String, email: String) +Howdy @name, +
+
+

+ You or someone else requested a password reset for your account.
+ If that was not you or your intention, just relax and ignore this email.
+

+

+ If you wish to reset your password, all you need to do is follow this link to reset your password. +

+

+ Cheers,
+ The PlayAuthenticate Team +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_en.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_en.scala.txt new file mode 100644 index 00000000..c5f9677c --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_en.scala.txt @@ -0,0 +1,11 @@ +@(url: String, token: String, name: String, email: String)Howdy @name, + + +You or someone else requested a password reset for your account. +If this was not you or your intention, just relax and ignore this email. + +If you wish to reset your password, all you need to do is follow this link to reset your password: +@url + +Cheers, +The PlayAuthenticate Team \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_es.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_es.scala.html new file mode 100644 index 00000000..d98750e6 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_es.scala.html @@ -0,0 +1,16 @@ +@(url: String, token: String, name: String, email: String) +Hola @name, +
+
+

+Alguien ha solicitado restablecer la contraseña de su cuenta.
+Si no ha sido Usted o si no ha sido esta su intención, relájese e ignore este email.
+

+

+Si lo que quiere es cambiar su contraseña, lo único que necesita hacer es seguir este enlace para restablecer su contraseña. +

+ +

+Atentamente,
+El equipo de PlayAuthenticate +

diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_es.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_es.scala.txt new file mode 100644 index 00000000..a33039b6 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_es.scala.txt @@ -0,0 +1,11 @@ +@(url: String, token: String, name: String, email: String)Hola @name, + + +Alguien ha solicitado restablecer la contraseña de su cuenta. +Si no ha sido Usted o si no ha sido esta su intención, relájese e ignore este email. + +Si lo que quiere es cambiar su contraseña, lo único que necesita hacer es seguir el siguiente enlace: +@url + +Atentamente, +El equipo de PlayAuthenticate diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pl.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pl.scala.html new file mode 100644 index 00000000..653ae59e --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pl.scala.html @@ -0,0 +1,15 @@ +@(url: String, token: String, name: String, email: String) +Cześć @name, +
+
+

+ Poproszono o zmianę hasła dla Twojego konta.
+ Jeśli to nie Ty, zrelaksuj się i zignoruj tę wiadomość.
+

+

+ Jeśli jednak naprawdę chcesz zmienić hasło skorzystaj z tego linku aby to zrobić. +

+

+ Pozdrawiamy,
+ Ekipa PlayAuthenticate +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pl.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pl.scala.txt new file mode 100644 index 00000000..5c032da0 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pl.scala.txt @@ -0,0 +1,11 @@ +@(url: String, token: String, name: String, email: String)Cześć @name, + + +Poproszono o zmianę hasła dla Twojego konta. +Jeśli to nie Ty, zrelaksuj się i zignoruj tę wiadomość. + +Jeśli jednak naprawdę chcesz zmienić hasło skorzystaj z tego linku aby to zrobić: +@url + +Pozdrawiamy, +Ekipa PlayAuthenticate \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pt.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pt.scala.html new file mode 100644 index 00000000..274a0906 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pt.scala.html @@ -0,0 +1,15 @@ +@(url: String, token: String, name: String, email: String) +Olá @name, +
+
+

+ Você ou alguém pediu uma nova palavra passe para a sua conta.
+ Se não foi você ou não foi sua intenção, pode ignorar esta mensagem.
+

+

+ Se deseja uma nova palavra passe, terá somente que seguir este endereço para criar uma nova palavra passe. +

+

+ Obrigado,
+ A equipa do PlayAuthenticate +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pt.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pt.scala.txt new file mode 100644 index 00000000..ec2b8c7b --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/password_reset_pt.scala.txt @@ -0,0 +1,11 @@ +@(url: String, token: String, name: String, email: String)Olá @name, + + +Você ou alguém pediu uma nova palavra passe para a sua conta. +Se não foi você ou não foi sua intenção, pode ignorar esta mensagem. + +Se deseja uma nova palavra passe, terá somente que seguir este endereço para criar uma nova palavra passe: +@url + +Obrigado, +A equipa do PlayAuthenticate \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_de.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_de.scala.html new file mode 100644 index 00000000..d8c89b19 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_de.scala.html @@ -0,0 +1,12 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Hey @name, +
+
+

+ um deine E-Mail-Adresse zu bestätigen, folge einfach diesem Link. +

+
+

+ Grüße,
+ Das PlayAuthenticate-Team +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_de.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_de.scala.txt new file mode 100644 index 00000000..11831840 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_de.scala.txt @@ -0,0 +1,9 @@ +@(verificationUrl: String, token: String, name: String, email: String)Hey @name, + + +um deine E-Mail-Adresse zu bestätigen, folge einfach diesem Link: + +@verificationUrl + +Grüße, +Das PlayAuthenticate-Team \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_en.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_en.scala.html new file mode 100644 index 00000000..6d7edba1 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_en.scala.html @@ -0,0 +1,12 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Howdy @name, +
+
+

+ To verify your e-mail address, now follow this link. +

+
+

+ Cheers,
+ The PlayAuthenticate Team +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_en.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_en.scala.txt new file mode 100644 index 00000000..26eae219 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_en.scala.txt @@ -0,0 +1,8 @@ +@(verificationUrl: String, token: String, name: String, email: String)Howdy @name, + + +To verify your e-mail address, follow this link now: +@verificationUrl + +Cheers, +The PlayAuthenticate Team \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_es.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_es.scala.html new file mode 100644 index 00000000..e4042d83 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_es.scala.html @@ -0,0 +1,12 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Hola @name, +
+
+

+ Para validar su email siga el siguiente enlace. +

+
+

+ Le saluda,
+ El equipo de PlayAuthenticate +

diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_es.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_es.scala.txt new file mode 100644 index 00000000..04793af6 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_es.scala.txt @@ -0,0 +1,8 @@ +@(verificationUrl: String, token: String, name: String, email: String)Hola @name, + + +Para validar su email siga el siguiente enlace: +@verificationUrl + +Le saluda, +El equipo de PlayAuthenticate. diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pl.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pl.scala.html new file mode 100644 index 00000000..da566b1b --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pl.scala.html @@ -0,0 +1,12 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Cześć @name, +
+
+

+ Aby zweryfikować konto, użyj ten link. +

+
+

+ Pozdrawiamy,
+ Ekipa PlayAuthenticate +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pl.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pl.scala.txt new file mode 100644 index 00000000..5dcf9b00 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pl.scala.txt @@ -0,0 +1,8 @@ +@(verificationUrl: String, token: String, name: String, email: String)Cześć @name, + + +Aby zweryfikować konto, użyj ten link +@verificationUrl + +Pozdrawiamy, +Ekipa PlayAuthenticate \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pt.scala.html b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pt.scala.html new file mode 100644 index 00000000..d3e09663 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pt.scala.html @@ -0,0 +1,12 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Olá @name, +
+
+

+ Para verificar o seu endereço de email, siga esta ligação. +

+
+

+ Obrigado,
+ A equipa do PlayAuthenticate +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pt.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pt.scala.txt new file mode 100644 index 00000000..6d380415 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/email/verify_email_pt.scala.txt @@ -0,0 +1,8 @@ +@(verificationUrl: String, token: String, name: String, email: String)Olá @name, + + +Para verificar o seu endereço de email, siga esta ligação agora: +@verificationUrl + +Obrigado, +A equipa do PlayAuthenticate \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/link.scala.html b/samples/scala/play-authenticate-usage/app/views/account/link.scala.html new file mode 100644 index 00000000..ad015506 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/link.scala.html @@ -0,0 +1,10 @@ + +@main(Messages("playauthenticate.link.account.title")) { + +

@Messages("playauthenticate.link.account.title")

+ +

+ @_providerPartial() +
+

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/password_change.scala.html b/samples/scala/play-authenticate-usage/app/views/account/password_change.scala.html new file mode 100644 index 00000000..bfe1c8d7 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/password_change.scala.html @@ -0,0 +1,23 @@ +@(changeForm: Form[controllers.Account.PasswordChange]) + +@import helper._ +@import helper.twitterBootstrap._ + +@main(Messages("playauthenticate.change.password.title")) { + +

@Messages("playauthenticate.change.password.title")

+

+ @form(routes.Account.doChangePassword) { + + @if(changeForm.hasGlobalErrors) { +

+ @changeForm.globalError.message +

+ } + + @_passwordPartial(changeForm) + + + } +

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_de.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_de.scala.html new file mode 100644 index 00000000..67f7cfc0 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_de.scala.html @@ -0,0 +1,14 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Hey @name, +
+
+

+ Du hast dich kürzlich bei PlayAuthenticate registriert.
+
+ Folge diesem Link um dein Konto jetzt zu aktivieren. +

+
+

+ Grüße,
+ Das PlayAuthenticate-Team +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_de.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_de.scala.txt new file mode 100644 index 00000000..fa24072f --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_de.scala.txt @@ -0,0 +1,11 @@ +@(verificationUrl: String, token: String, name: String, email: String)Hey @name, + + +Du hast dich kürzlich bei PlayAuthenticate registriert. + +Folge diesem Link um dein Konto jetzt zu aktivieren: + +@verificationUrl + +Grüße, +Das PlayAuthenticate-Team \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_en.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_en.scala.html new file mode 100644 index 00000000..86852648 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_en.scala.html @@ -0,0 +1,14 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Howdy @name, +
+
+

+ You recently signed up for PlayAuthenticate.
+
+ Follow this link to activate your account now. +

+
+

+ Cheers,
+ The PlayAuthenticate Team +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_en.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_en.scala.txt new file mode 100644 index 00000000..22c989f6 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_en.scala.txt @@ -0,0 +1,10 @@ +@(verificationUrl: String, token: String, name: String, email: String)Howdy @name, + + +You recently signed up for PlayAuthenticate. + +To activate your account, follow this link now: +@verificationUrl + +Cheers, +The PlayAuthenticate Team \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_es.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_es.scala.html new file mode 100644 index 00000000..2fc83c1d --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_es.scala.html @@ -0,0 +1,14 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Hola @name, +
+
+

+ Se acaba de apuntar a PlayAuthenticate.
+
+ Siga el siguiente enlace para activar su cuenta. +

+
+

+ Saludos,
+ El equipo de PlayAuthenticate +

diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_es.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_es.scala.txt new file mode 100644 index 00000000..d9eb4cb4 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_es.scala.txt @@ -0,0 +1,10 @@ +@(verificationUrl: String, token: String, name: String, email: String)Hola @name, + + +Se acaba de apuntar a PlayAuthenticate. + +Siga el siguiente enlace para activar su cuenta: +@verificationUrl + +Saludos, +El equipo de PlayAuthenticate. diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pl.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pl.scala.html new file mode 100644 index 00000000..270fae5c --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pl.scala.html @@ -0,0 +1,14 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Cześć @name, +
+
+

+ Twoje konto w PlayAuthenticate zostało utworzone.
+
+ Użyj ten link, aby je aktywować natychmiast. +

+
+

+ Pozdrawiamy,
+ Ekipa PlayAuthenticate +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pl.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pl.scala.txt new file mode 100644 index 00000000..dcafe321 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pl.scala.txt @@ -0,0 +1,10 @@ +@(verificationUrl: String, token: String, name: String, email: String)Cześć @name, + + +Twoje konto w PlayAuthenticate zostało utworzone. + +Aby je aktywować, użyj ten link +@verificationUrl + +Pozdrawiamy, +Ekipa PlayAuthenticate \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pt.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pt.scala.html new file mode 100644 index 00000000..522c3373 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pt.scala.html @@ -0,0 +1,14 @@ +@(verificationUrl: String, token: String, name: String, email: String) +Olá @name, +
+
+

+ Recentemente registou-se no PlayAuthenticate.
+
+ Siga esta ligação para activar a sua conta agora. +

+
+

+ Obrigado,
+ A equipa do PlayAuthenticate +

\ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pt.scala.txt b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pt.scala.txt new file mode 100644 index 00000000..03137c15 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/email/verify_email_pt.scala.txt @@ -0,0 +1,10 @@ +@(verificationUrl: String, token: String, name: String, email: String)Olá @name, + + +Recentemente registou-se no PlayAuthenticate. + +Siga esta ligação para activar a sua conta agora: +@verificationUrl + +Obrigado, +A equipa do PlayAuthenticate \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/exists.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/exists.scala.html new file mode 100644 index 00000000..57f73520 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/exists.scala.html @@ -0,0 +1,5 @@ + +@main(Messages("playauthenticate.user.exists.title")) { +

@Messages("playauthenticate.user.exists.title")

+

@Messages("playauthenticate.user.exists.message")

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/no_token_or_invalid.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/no_token_or_invalid.scala.html new file mode 100644 index 00000000..6c188da7 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/no_token_or_invalid.scala.html @@ -0,0 +1,5 @@ + +@main(Messages("playauthenticate.token.error.title")) { +

@Messages("playauthenticate.token.error.title")

+

@Messages("playauthenticate.token.error.message")

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/oAuthDenied.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/oAuthDenied.scala.html new file mode 100644 index 00000000..4b034c26 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/oAuthDenied.scala.html @@ -0,0 +1,12 @@ +@(providerKey: String) + +@main(Messages("playauthenticate.oauth.access.denied.title")) { + +

@Messages("playauthenticate.oauth.access.denied.title")

+

+ @Messages("playauthenticate.oauth.access.denied.explanation")
+

+

+ @Messages("playauthenticate.oauth.access.denied.alternative") @Messages("playauthenticate.oauth.access.denied.alternative.cta"). +

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/password_forgot.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/password_forgot.scala.html new file mode 100644 index 00000000..276a4e51 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/password_forgot.scala.html @@ -0,0 +1,23 @@ +@(emailForm: Form[providers.MyUsernamePasswordAuthProvider.MyIdentity]) + +@import helper._ +@import helper.twitterBootstrap._ + +@main(Messages("playauthenticate.password.forgot.title")) { + +

@Messages("playauthenticate.password.forgot.title")

+

+ @form(routes.Signup.doForgotPassword) { + + @if(emailForm.hasGlobalErrors) { +

+ @emailForm.globalError.message +

+ } + + @_emailPartial(emailForm) + + + } +

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/password_reset.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/password_reset.scala.html new file mode 100644 index 00000000..665fa3a0 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/password_reset.scala.html @@ -0,0 +1,32 @@ +@(resetForm: Form[controllers.Signup.PasswordReset]) + +@import helper._ +@import helper.twitterBootstrap._ + +@main(Messages("playauthenticate.password.reset.title")) { + +

@Messages("playauthenticate.password.reset.title")

+

+ @form(routes.Signup.doResetPassword) { + + @if(resetForm.hasGlobalErrors) { +

+ @resetForm.globalError.message +

+ } + + @input( + resetForm("token"), + '_label -> "", + '_showConstraints -> false + + ) { (id, name, value, args) => + + } + + @_passwordPartial(resetForm) + + + } +

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/signup/unverified.scala.html b/samples/scala/play-authenticate-usage/app/views/account/signup/unverified.scala.html new file mode 100644 index 00000000..91d90ead --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/signup/unverified.scala.html @@ -0,0 +1,11 @@ + +@main(Messages("playauthenticate.verify.email.title")) { + +

@Messages("playauthenticate.verify.email.title")

+

+ @Messages("playauthenticate.verify.email.requirement")
+ @Messages("playauthenticate.verify.email.cta") +
+ +

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/account/unverified.scala.html b/samples/scala/play-authenticate-usage/app/views/account/unverified.scala.html new file mode 100644 index 00000000..3e85eebd --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/account/unverified.scala.html @@ -0,0 +1,8 @@ + +@main(Messages("playauthenticate.verify.account.title")) { + +

@Messages("playauthenticate.verify.account.title")

+

+ @Messages("playauthenticate.verify.account.before") @Messages("playauthenticate.verify.account.first").
+

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/index.scala.html b/samples/scala/play-authenticate-usage/app/views/index.scala.html new file mode 100644 index 00000000..8aa4c6c9 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/index.scala.html @@ -0,0 +1,27 @@ + +@main(Messages("playauthenticate.index.title")) { + +
+

@Messages("playauthenticate.index.intro")

+

@Messages("playauthenticate.index.intro_2")
@Messages("playauthenticate.index.intro_3")

+
+ + +
+
+

@Messages("playauthenticate.index.heading")

+

Cupcake ipsum dolor sit amet. Pastry pie powder biscuit bear claw. Jelly-o chocolate bar sweet roll sugar plum chocolate. Biscuit brownie chupa chups macaroon ice cream halvah sugar plum oat cake ice cream.

+

@Messages("playauthenticate.index.details") »

+
+
+

Heading

+

Applicake macaroon caramels gummi bears pastry. Cake liquorice carrot cake chocolate lollipop dessert. Halvah fruitcake marshmallow pie gummi bears pie marzipan.

+

@Messages("playauthenticate.index.details") »

+
+
+

Heading

+

Wafer halvah jujubes lollipop liquorice jelly-o pastry. Pie halvah toffee. Candy canes donut sugar plum. Chocolate cake powder tart liquorice cotton candy pudding sweet.

+

@Messages("playauthenticate.index.details") »

+
+
+ } \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/login.scala.html b/samples/scala/play-authenticate-usage/app/views/login.scala.html new file mode 100644 index 00000000..1ca2f3fb --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/login.scala.html @@ -0,0 +1,56 @@ +@(loginForm: Form[_]) + +@import helper._ +@import helper.twitterBootstrap._ +@import com.feth.play.module.pa.views.html._ + +@main(Messages("playauthenticate.login.title"),"login") { + +
+
+

@Messages("playauthenticate.login.title")

+
+
+ +
+ +
+ @* Display proprietary login form *@ + @helper.form(routes.Application.doLogin) { + + @if(loginForm.hasGlobalErrors) { +

+ @loginForm.globalError.message +

+ } + + @_emailPartial(loginForm) + + @inputPassword( + loginForm("password"), + '_showConstraints -> false, + '_label -> Messages("playauthenticate.login.password.placeholder") + ) + +
+
+ @Messages("playauthenticate.login.forgot.password") + + } +
+ +
+ @Messages("playauthenticate.login.oauth") + @* Display list of available providers *@ + @_providerPartial(skipCurrent=false) + @providerAvailable("basic") { available: Boolean => + @if(available) { +
+ @Messages("playauthenticate.login.basic") + } + } +
+ +
+ +} diff --git a/samples/scala/play-authenticate-usage/app/views/main.scala.html b/samples/scala/play-authenticate-usage/app/views/main.scala.html new file mode 100644 index 00000000..4571805c --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/main.scala.html @@ -0,0 +1,103 @@ +@(title: String, nav: String = "")(content: Html) + +@import be.objectify.deadbolt.java.views.html._ +@import be.objectify.deadbolt.core.utils.TemplateUtils._ + + + + + @title + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ @if(flash.contains(Application.FLASH_ERROR_KEY)) { +
+ @flash().get(Application.FLASH_ERROR_KEY) +
+ } + @if(flash.contains(Application.FLASH_MESSAGE_KEY)) { +
+ @flash().get(Application.FLASH_MESSAGE_KEY) +
+ } + @content + +
+ + +
+ + + diff --git a/samples/scala/play-authenticate-usage/app/views/profile.scala.html b/samples/scala/play-authenticate-usage/app/views/profile.scala.html new file mode 100644 index 00000000..77c91eef --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/profile.scala.html @@ -0,0 +1,51 @@ +@(localUser: models.User = null) + +@import com.feth.play.module.pa.views.html._ + +@main(Messages("playauthenticate.profile.title"),"profile") { + +

@Messages("playauthenticate.profile.title")

+

+ Your name is @localUser.name and your email address is @if(!localUser.email) {<unknown>.} else { + @localUser.email. + + @if(!localUser.emailValidated && localUser.email) { + (unverified - click to verify) + } else { + (verified) + } + } +
+ @if(localUser.firstName && localUser.lastName) { + Your first name is @localUser.firstName and your last name is @localUser.lastName +
+ } + @defining(localUser.getProviders()) { providers => + @if(providers.size() > 0) { + @if(providers.size() ==1) { + @Messages("playauthenticate.profile.providers_one") + } else { + @Messages("playauthenticate.profile.providers_many",providers.size().toString()) + } + @for(p <- providers) { + @_providerIcon(p) + } +
+ } + } + +
+ @currentAuth() { auth => + @Messages("playauthenticate.profile.logged") @_providerIcon(auth.getProvider())
+ @if(auth.expires() != -1){ + @Messages("playauthenticate.profile.session", auth.getId(), Application.formatTimestamp(auth.expires())) + } else { + @Messages("playauthenticate.profile.session_endless", auth.getId()) + } + } +
+

+

+} diff --git a/samples/scala/play-authenticate-usage/app/views/restricted.scala.html b/samples/scala/play-authenticate-usage/app/views/restricted.scala.html new file mode 100644 index 00000000..2bc11742 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/restricted.scala.html @@ -0,0 +1,9 @@ +@(localUser: models.User = null) + +@main(Messages("playauthenticate.navigation.restricted"), "restricted") { + +

@Messages("playauthenticate.navigation.restricted")

+

+ @Messages("playauthenticate.restricted.secrets") +

+} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/app/views/signup.scala.html b/samples/scala/play-authenticate-usage/app/views/signup.scala.html new file mode 100644 index 00000000..10c2aaf7 --- /dev/null +++ b/samples/scala/play-authenticate-usage/app/views/signup.scala.html @@ -0,0 +1,47 @@ +@(signupForm: Form[_]) + +@import helper._ +@import helper.twitterBootstrap._ + +@main(Messages("playauthenticate.signup.title"),"signup") { + +
+
+

@Messages("playauthenticate.signup.title")

+
+
+ +
+ +
+ @* Display proprietary login form *@ + @helper.form(routes.Application.doSignup) { + + @if(signupForm.hasGlobalErrors) { +

+ @signupForm.globalError.message +

+ } + + @inputText( + signupForm("name"), + '_label -> Messages("playauthenticate.signup.name") + ) + + @_emailPartial(signupForm) + + @_passwordPartial(signupForm) + + + } +
+ +
+ @Messages("playauthenticate.signup.oauth") + @* Display list of available providers *@ + @_providerPartial(skipCurrent=false) +
+ +
+ +} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/build.sbt b/samples/scala/play-authenticate-usage/build.sbt new file mode 100644 index 00000000..b62cbf05 --- /dev/null +++ b/samples/scala/play-authenticate-usage/build.sbt @@ -0,0 +1,41 @@ +import play.PlayJava + +name := "play-authenticate-usage" + +scalaVersion := "2.11.1" + +version := "1.0-SNAPSHOT" + +val appDependencies = Seq( + "be.objectify" %% "deadbolt-java" % "2.3.0-RC1", + // Comment the next line for local development of the Play Authentication core: + "com.feth" %% "play-authenticate" % "0.6.5-SNAPSHOT", + "postgresql" % "postgresql" % "9.1-901-1.jdbc4", + javaCore, + cache, + javaWs, + javaJdbc, + javaEbean +) + +resolvers ++= Seq( + "Apache" at "http://repo1.maven.org/maven2/", + "jBCrypt Repository" at "http://repo1.maven.org/maven2/org/", + "play-easymail (release)" at "http://joscha.github.io/play-easymail/repo/releases/", + "play-easymail (snapshot)" at "http://joscha.github.io/play-easymail/repo/snapshots/", + Resolver.url("Objectify Play Repository", url("http://schaloner.github.io/releases/"))(Resolver.ivyStylePatterns), + "play-authenticate (release)" at "http://joscha.github.io/play-authenticate/repo/releases/", + "play-authenticate (snapshot)" at "http://joscha.github.io/play-authenticate/repo/snapshots/" +) + +// Uncomment the next line for local development of the Play Authenticate core: +//lazy val playAuthenticate = project.in(file("modules/play-authenticate")).enablePlugins(PlayJava) + +lazy val root = project.in(file(".")) + .enablePlugins(PlayJava) + .settings( + libraryDependencies ++= appDependencies + ) + // Uncomment the next lines for local development of the Play Authenticate core: + //.dependsOn(playAuthenticate) + //.aggregate(playAuthenticate) diff --git a/samples/scala/play-authenticate-usage/conf/application.conf b/samples/scala/play-authenticate-usage/conf/application.conf new file mode 100644 index 00000000..6e6a8223 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/application.conf @@ -0,0 +1,71 @@ +# This is the main configuration file for the application. +# ~~~~~ + +# Secret key +# ~~~~~ +# The secret key is used to secure cryptographics functions. +# If you deploy your application to several instances be sure to use the same key! +application.secret="y]Z5;`T0=F3mAda1lW[r5jFWCw9stMiBnShjPU;59l7cwA9LX1abrprOgTP/VCDQ" + +# The application languages +# ~~~~~ +application.langs="en,de,pl,fr,es,ja" + +# Global object class +# ~~~~~ +# Define the Global object class for this application. +# Default to Global in the root package. +application.global=Global + +# Router +# ~~~~~ +# Define the Router object to use for this application. +# Default to Routes in the root package. +# application.routers=my.application.Routes + +# Database configuration +# ~~~~~ +# You can declare as many datasources as you want. +# By convention, the default datasource is named `default` +# +db.default.driver=org.h2.Driver +db.default.url="jdbc:h2:mem:play" +# db.default.user=sa +# db.default.password= +# +# You can expose this datasource via JNDI if needed (Useful for JPA) +# db.default.jndiName=DefaultDS + +# Evolutions +# ~~~~~ +# You can disable evolutions if needed +# evolutionplugin=disabled + +# Ebean configuration +# ~~~~~ +# You can declare as many Ebean servers as you want. +# By convention, the default server is named `default` +# +ebean.default="models.*" + +# Logger +# ~~~~~ +# You can also configure logback (http://logback.qos.ch/), by providing a logger.xml file in the conf directory . + +# Root logger: +logger.root=ERROR + +# Logger used by the framework: +logger.play=INFO + +# Logger provided to your application: +logger.application=DEBUG + +# Deadbolt +include "play-authenticate/deadbolt.conf" + +# SMTP +include "play-authenticate/smtp.conf" + +# And play authenticate +include "play-authenticate/mine.conf" diff --git a/samples/scala/play-authenticate-usage/conf/messages.de b/samples/scala/play-authenticate-usage/conf/messages.de new file mode 100644 index 00000000..adf39467 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/messages.de @@ -0,0 +1,150 @@ +# Override default Play's validation messages + +# --- Constraints +constraint.required=Obligatorisch +constraint.min=Minimaler Wert: {0} +constraint.max=Maximaler Wert: {0} +constraint.minLength=Minimale Länge: {0} +constraint.maxLength=Maximale Länge: {0} +constraint.email=E-Mail + +# --- Formats +format.date=Datum (''{0}'') +format.numeric=Numerisch +format.real=Reelle Zahl + +# --- Errors +error.invalid=Wert is unzulässig +error.required=Dieses Feld ist obligatorisch +error.number=Numerischer Wert erwartet +error.real=Reelle Zahl erwartet +error.min=Muss größer oder gleich {0} sein +error.max=Muss kleiner oder gleich {0} sein +error.minLength=Die minimale Länge beträgt {0} +error.maxLength=Die maximale Länge beträgt {0} +error.email=Valide E-Mail-Adresse erforderlich +error.pattern=Muss dem Muster {0} genügen + +### --- play-authenticate START + +playauthenticate.accounts.link.success=Das Konto wurde erfolgreich verknüpft. +playauthenticate.accounts.merge.success=Die Konten wurden erfolgreich zusammengeführt. + +playauthenticate.verify_email.error.already_validated=Deine E-Mail-Adresse wurde bereits verifiziert. +playauthenticate.verify_email.error.set_email_first=Du musst zuerst eine E-Mail-Adresse definieren. +playauthenticate.verify_email.message.instructions_sent=Instruktionen zur Bestätigung deiner E-Mail-Adresse wurden an {0} gesendet. +playauthenticate.verify_email.success=E-Mail-Adresse ({0}) wurde erfolgreich verifiziert. + +playauthenticate.reset_password.message.instructions_sent=Instruktionen zum Zurücksetzen deines Passwortes wurden an {0} versandt. +playauthenticate.reset_password.message.email_not_verified=Deine E-Mail-Adresse wurde noch nicht verifiziert. Instruktionen um deine E-Mail-Adresse zu verifizieren wurden versendet. Versuche danach nochmals dein Passwort zurückzusetzen. +playauthenticate.reset_password.message.no_password_account=Dein Benutzer wurde für die Verwendung eines Passwort-basierten Zugangs noch nicht aktiviert. +playauthenticate.reset_password.message.success.auto_login=Dein Passwort wurde erfolgreich zurückgesetzt. +playauthenticate.reset_password.message.success.manual_login=Dein Passwort wurde erfolgreich zurückgesetzt. Bitte melde dich jetzt mit deinem neuen Passwort an. + +playauthenticate.change_password.error.passwords_not_same=Die Passwörter stimmen nicht überein. +playauthenticate.change_password.success=Das Passwort wurde erfolgreich geändert. + +playauthenticate.password.signup.error.passwords_not_same=Die Passwörter stimmen nicht überein. +playauthenticate.password.login.unknown_user_or_pw=Der Benutzer wurde nicht gefunden oder das Passwort stimmt nicht überein. + +playauthenticate.password.verify_signup.subject=PlayAuthenticate: Vervollständige deine Anmeldung +playauthenticate.password.verify_email.subject=PlayAuthenticate: E-Mail-Adresse bestätigen +playauthenticate.password.reset_email.subject=PlayAuthenticate: Anleitung zum Passwortzurücksetzen + +# play-authenticate: Additional translations + +playauthenticate.login.email.placeholder=Deine E-Mail-Adresse +playauthenticate.login.password.placeholder=Wähle ein Passwort +playauthenticate.login.password.repeat=Wiederhole das gewählte Passwort +playauthenticate.login.title=Anmeldung +playauthenticate.login.password.placeholder=Passwort +playauthenticate.login.now=Jetzt anmelden +playauthenticate.login.forgot.password=Passwort vergessen? +playauthenticate.login.oauth=oder melde dich mit einem der folgenden Dienste an: +playauthenticate.login.basic=oder versuch es mit HTTP basic auth (als example/secret) + +playauthenticate.signup.title=Registrierung +playauthenticate.signup.name=Dein Name +playauthenticate.signup.now=Jetzt registrieren +playauthenticate.signup.oauth=oder registriere dich mit einem der folgenden Dienste: + +playauthenticate.verify.account.title=Verifikation der E-Mail-Adresse erforderlich +playauthenticate.verify.account.before=Bevor du ein Passwort vergeben kannst, +playauthenticate.verify.account.first=musst du zuerst deine E-Mail-Adresse verifizieren + +playauthenticate.change.password.title=Ändere dein Passwort hier +playauthenticate.change.password.cta=Mein Passwort ändern + +playauthenticate.merge.accounts.title=Konten zusammenführen +playauthenticate.merge.accounts.question=Möchtest du dein aktuelles Konto ({0}) mit diesem zusammenführen: {1}? +playauthenticate.merge.accounts.true=Ja, diese Konten zusammenführen +playauthenticate.merge.accounts.false=Nein, meine aktuelle Sizung beenden und mit dem neuen Benutzer anmelden +playauthenticate.merge.accounts.ok=OK + +playauthenticate.link.account.title=Konto verknüpfen +playauthenticate.link.account.question=Konto ({0}) mit deinem Benutzer verknüpfen? +playauthenticate.link.account.true=Ja, dieses Konto mit meinem Benutzer verknüpfen +playauthenticate.link.account.false=Nein, abmelden und einen neuen Benutzer mit diesem Konto erstellen +playauthenticate.link.account.ok=OK + +# play-authenticate: Signup folder translations + +playauthenticate.verify.email.title=E-Mail-Adresse bestätigen +playauthenticate.verify.email.requirement=Du musst deine E-Mail-Adresse bestätigen, bevor du PlayAuthenticate nutzen kannst. +playauthenticate.verify.email.cta=Eine E-Mail wurde zur registrierten E-Mail-Adresse versandt. Bitte öffne sie und klicke auf den enthaltenen Link, um deinen Account zu aktivieren. + +playauthenticate.password.reset.title=Passwort zurücksetzen +playauthenticate.password.reset.cta=Passwort zurücksetzen + +playauthenticate.password.forgot.title=Passwort vergessen +playauthenticate.password.forgot.cta=Informationen zum Zurücksetzen versenden + +playauthenticate.oauth.access.denied.title=OAuth-Zugriff abgelehnt +playauthenticate.oauth.access.denied.explanation=Wenn du PlayAuthenticate mit OAuth nutzen möchtest, musst du die Verbindung akzeptieren. +playauthenticate.oauth.access.denied.alternative=Falls du dies lieber nicht tun möchtest, kannst du dich auch +playauthenticate.oauth.access.denied.alternative.cta=mit Benutzername und Passwort registrieren + +playauthenticate.token.error.title=Token-Fehler +playauthenticate.token.error.message=Der Token ist entweder abgelaufen oder existiert nicht. + +playauthenticate.user.exists.title=Benutzer vorhanden +playauthenticate.user.exists.message=Dieser Benutzer existiert bereits. + +# play-authenticate: Navigation +playauthenticate.navigation.profile=Profil +playauthenticate.navigation.link_more=Mehr Zugänge verknüpfen +playauthenticate.navigation.logout=Abmelden +playauthenticate.navigation.login=Anmelden +playauthenticate.navigation.home=Startseite +playauthenticate.navigation.restricted=Geschützte Seite +playauthenticate.navigation.signup=Registrieren + +# play-authenticate: Handler +playauthenticate.handler.loginfirst=Du musst dich zuerst anmelden um ''{0}'' anzuzeigen + + +# play-authenticate: Profile +playauthenticate.profile.title=Benutzerprofil +playauthenticate.profile.mail=Dein Name lautet {0} und deine E-Mail-Adresse ist {1}! +playauthenticate.profile.unverified=unverifiziert - Klicke um zu bestätigen +playauthenticate.profile.verified=verifiziert +playauthenticate.profile.providers_many=Es sind {0} Konten mit deinem Benutzer verknüpft: +playauthenticate.profile.providers_one=Es ist ein Konto mit deinem Benutzer verknüpft: +playauthenticate.profile.logged=Du bist momentan eingeloggt mit: +playauthenticate.profile.session=Deine Benutzer-Identifikation ist {0} und deine Sitzung läuft {1} ab +playauthenticate.profile.session_endless=Deine Benutzer-Identifikation ist {0} und deine Sitzung läuft nie ab +playauthenticate.profile.password_change=Ändere/setze ein Passwort für deinen Benutzer + +# play-authenticate - sample: Index page +playauthenticate.index.title=Willkommen bei PlayAuthenticate +playauthenticate.index.intro=PlayAuthenticate Beispiel-Applikation +playauthenticate.index.intro_2=Dies ist eine Blaupause für eine einfache Applikation mit Authentifikation. +playauthenticate.index.intro_3=Schau dir die Navigation oben an, um einfache Beispielseiten inklusive der unterstützten Authentifikationsmethoden zu sehen. +playauthenticate.index.heading=Überschrift +playauthenticate.index.details=Details anzeigen + +# play-authenticate - sample: Restricted page +playauthenticate.restricted.secrets=Überall Geheimnisse! + + +### --- play-authenticate END \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/conf/messages.en b/samples/scala/play-authenticate-usage/conf/messages.en new file mode 100644 index 00000000..6008386b --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/messages.en @@ -0,0 +1,150 @@ +# Override default Play's validation messages + +# --- Constraints +constraint.required=Required +constraint.min=Minimum value: {0} +constraint.max=Maximum value: {0} +constraint.minLength=Minimum length: {0} +constraint.maxLength=Maximum length: {0} +constraint.email=Email + +# --- Formats +format.date=Date (''{0}'') +format.numeric=Numeric +format.real=Real + +# --- Errors +error.invalid=Invalid value +error.required=This field is required +error.number=Numeric value expected +error.real=Real number value expected +error.min=Must be greater or equal to {0} +error.max=Must be less or equal to {0} +error.minLength=Minimum length is {0} +error.maxLength=Maximum length is {0} +error.email=Valid email required +error.pattern=Must satisfy {0} + +### --- play-authenticate START + +# play-authenticate: Initial translations + +playauthenticate.accounts.link.success=Account linked successfully +playauthenticate.accounts.merge.success=Accounts merged successfully + +playauthenticate.verify_email.error.already_validated=Your e-mail has already been validated. +playauthenticate.verify_email.error.set_email_first=You need to set an e-mail address first. +playauthenticate.verify_email.message.instructions_sent=Instructions on how to verify your e-mail address have been sent to {0}. +playauthenticate.verify_email.success=E-mail address ({0}) successfully verified. + +playauthenticate.reset_password.message.instructions_sent=Instructions on how to reset your password have been sent to {0}. +playauthenticate.reset_password.message.email_not_verified=Your account has not been verified, yet. An e-mail including instructions on how to verify it has been sent out. Retry resetting your password afterwards. +playauthenticate.reset_password.message.no_password_account=Your user has not yet been set up for password usage. +playauthenticate.reset_password.message.success.auto_login=Your password has been reset. +playauthenticate.reset_password.message.success.manual_login=Your password has been reset. Please now log in using your new password. + +playauthenticate.change_password.error.passwords_not_same=Passwords do not match. +playauthenticate.change_password.success=Password has been changed successfully. + +playauthenticate.password.signup.error.passwords_not_same=Passwords do not match. +playauthenticate.password.login.unknown_user_or_pw=Unknown user or password. + +playauthenticate.password.verify_signup.subject=PlayAuthenticate: Complete your signup +playauthenticate.password.verify_email.subject=PlayAuthenticate: Confirm your e-mail address +playauthenticate.password.reset_email.subject=PlayAuthenticate: How to reset your password + +# play-authenticate: Additional translations + +playauthenticate.login.email.placeholder=Your e-mail address +playauthenticate.login.password.placeholder=Choose a password +playauthenticate.login.password.repeat=Repeat chosen password +playauthenticate.login.title=Login +playauthenticate.login.password.placeholder=Password +playauthenticate.login.now=Login now +playauthenticate.login.forgot.password=Forgot your password? +playauthenticate.login.oauth=or log in using one of the following providers: +playauthenticate.login.basic=or try HTTP basic auth (as example/secret) + +playauthenticate.signup.title=Signup +playauthenticate.signup.name=Your name +playauthenticate.signup.now=Sign up now +playauthenticate.signup.oauth=or sign up using one of the following providers: + +playauthenticate.verify.account.title=E-mail verification required +playauthenticate.verify.account.before=Before setting a password, you need to +playauthenticate.verify.account.first=first verify your e-mail address + +playauthenticate.change.password.title=Change your password here +playauthenticate.change.password.cta=Change my password + +playauthenticate.merge.accounts.title=Merge accounts +playauthenticate.merge.accounts.question=Do you want to merge your current account ({0}) with this account: {1}? +playauthenticate.merge.accounts.true=Yes, merge these two accounts +playauthenticate.merge.accounts.false=No, exit my current session and log in as a new user +playauthenticate.merge.accounts.ok=OK + +playauthenticate.link.account.title=Link account +playauthenticate.link.account.question=Link ({0}) with your user? +playauthenticate.link.account.true=Yes, link this account +playauthenticate.link.account.false=No, log out and create a new user with this account +playauthenticate.link.account.ok=OK + +# play-authenticate: Signup folder translations + +playauthenticate.verify.email.title=Verify your e-mail +playauthenticate.verify.email.requirement=Before you can use PlayAuthenticate, you first need to verify your e-mail address. +playauthenticate.verify.email.cta=An e-mail has been sent to the registered address. Please follow the embedded link to activate your account. + +playauthenticate.password.reset.title=Reset password +playauthenticate.password.reset.cta=Reset my password + +playauthenticate.password.forgot.title=Forgot password +playauthenticate.password.forgot.cta=Send reset instructions + +playauthenticate.oauth.access.denied.title=OAuth access denied +playauthenticate.oauth.access.denied.explanation=If you want to use PlayAuthenticate with OAuth, you must accept the connection. +playauthenticate.oauth.access.denied.alternative=If you rather not like to do this, you can also +playauthenticate.oauth.access.denied.alternative.cta=sign up with a username and password instead + +playauthenticate.token.error.title=Token error +playauthenticate.token.error.message=The given token has either expired or does not exist. + +playauthenticate.user.exists.title=User exists +playauthenticate.user.exists.message=This user already exists. + +# play-authenticate: Navigation +playauthenticate.navigation.profile=Profile +playauthenticate.navigation.link_more=Link more providers +playauthenticate.navigation.logout=Sign out +playauthenticate.navigation.login=Log in +playauthenticate.navigation.home=Home +playauthenticate.navigation.restricted=Restricted page +playauthenticate.navigation.signup=Sign up + +# play-authenticate: Handler +playauthenticate.handler.loginfirst=You need to log in first, to view ''{0}'' + +# play-authenticate: Profile +playauthenticate.profile.title=User profile +playauthenticate.profile.mail=Your name is {0} and your email address is {1}! +playauthenticate.profile.unverified=unverified - click to verify +playauthenticate.profile.verified=verified +playauthenticate.profile.providers_many=There are {0} providers linked with your account: +playauthenticate.profile.providers_one = There is one provider linked with your account: +playauthenticate.profile.logged=You are currently logged in with: +playauthenticate.profile.session=Your user ID is {0} and your session will expire on {1} +playauthenticate.profile.session_endless=Your user ID is {0} and your session will not expire, as it is endless +playauthenticate.profile.password_change=Change/set a password for your account + +# play-authenticate - sample: Index page +playauthenticate.index.title=Welcome to Play Authenticate +playauthenticate.index.intro=Play Authenticate sample app +playauthenticate.index.intro_2=This is a template for a simple application with authentication. +playauthenticate.index.intro_3=Check the main navigation above for simple page examples including supported authentication features. +playauthenticate.index.heading=Heading +playauthenticate.index.details=View details + +# play-authenticate - sample: Restricted page +playauthenticate.restricted.secrets=Secrets, everywhere! + +### --- play-authenticate END diff --git a/samples/scala/play-authenticate-usage/conf/messages.es b/samples/scala/play-authenticate-usage/conf/messages.es new file mode 100644 index 00000000..432b105c --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/messages.es @@ -0,0 +1,148 @@ +# Override default Play's validation messages + +# --- Constraints +constraint.required=Obligatorio +constraint.min=Valor mínimo: {0} +constraint.max=Valor máximo: {0} +constraint.minLength=Longitud mínima: {0} +constraint.maxLength=Longitud máxima: {0} +constraint.email=Email + +# --- Formats +format.date=Date (''{0}'') +format.numeric=Numérico +format.real=Real + +# --- Errors +error.invalid=Valor incorrecto +error.required=Este campo es obligatorio +error.number=Se esperaba un valor numérico +error.real=Se esperaba un numero real +error.min=Debe ser mayor o igual que {0} +error.max=Debe ser menor o igual que {0} +error.minLength=La longitud mínima es de {0} +error.maxLength=La longitud máxima es de {0} +error.email=Se requiere un email válido +error.pattern=Debe satisfacer {0} + +### --- play-authenticate START + +# play-authenticate: Initial translations + +playauthenticate.accounts.link.success=Cuenta enlazada correctamente +playauthenticate.accounts.merge.success=Cuentas unificadas correctamente + +playauthenticate.verify_email.error.already_validated=Su email ya ha sido validado +playauthenticate.verify_email.error.set_email_first=Primero debe dar de alta un email. +playauthenticate.verify_email.message.instructions_sent=Las instrucciones para validar su cuenta han sido enviadas a {0}. +playauthenticate.verify_email.success=La dirección de email ({0}) ha sido verificada correctamente. + +playauthenticate.reset_password.message.instructions_sent=Las instrucciones para restablecer su contraseña han sido enviadas a {0}. +playauthenticate.reset_password.message.email_not_verified=Su cuenta aún no ha sido validada. Se ha enviado un email incluyedo instrucciones para su validación. Intente restablecer la contraseña una vez lo haya recibido. +playauthenticate.reset_password.message.no_password_account=Su usuario todavía no ha sido configurado para utilizar contraseña. +playauthenticate.reset_password.message.success.auto_login=Su contraseña ha sido restablecida. +playauthenticate.reset_password.message.success.manual_login=Su contraseña ha sido restablecida. Intente volver a entrar utilizando su nueva contraseña. + +playauthenticate.change_password.error.passwords_not_same=Las contraseñas no coinciden. +playauthenticate.change_password.success=La contraseña ha sido cambiada correctamente. + +playauthenticate.password.signup.error.passwords_not_same=Las contraseñas no coinciden. +playauthenticate.password.login.unknown_user_or_pw=Usuario o contraseña incorrectos. + +playauthenticate.password.verify_signup.subject=PlayAuthenticate: Complete su registro +playauthenticate.password.verify_email.subject=PlayAuthenticate: Confirme su dirección de email +playauthenticate.password.reset_email.subject=PlayAuthenticate: Cómo restablecer su contraseña + +# play-authenticate: Additional translations + +playauthenticate.login.email.placeholder=Su dirección de email +playauthenticate.login.password.placeholder=Elija una contraseña +playauthenticate.login.password.repeat=Repita la contraseña elegida +playauthenticate.login.title=Entrar +playauthenticate.login.password.placeholder=Contraseña +playauthenticate.login.now=Entrar +playauthenticate.login.forgot.password=¿Olvidó su contraseña? +playauthenticate.login.oauth=entre usando su cuenta con alguno de los siguientes proveedores: + +playauthenticate.signup.title=Registrarse +playauthenticate.signup.name=Su nombre +playauthenticate.signup.now=Regístrese +playauthenticate.signup.oauth=regístrese usando su cuenta con alguno de los siguientes proveedores: + +playauthenticate.verify.account.title=Es necesario validar su email +playauthenticate.verify.account.before=Antes de configurar una contraseña +playauthenticate.verify.account.first=valide su email + +playauthenticate.change.password.title=Cambio de contraseña +playauthenticate.change.password.cta=Cambiar mi contraseña + +playauthenticate.merge.accounts.title=Unir cuentas +playauthenticate.merge.accounts.question=¿Desea unir su cuenta ({0}) con su otra cuenta: {1}? +playauthenticate.merge.accounts.true=Sí, ¡une estas dos cuentas! +playauthenticate.merge.accounts.false=No, quiero abandonar esta sesión y entrar como otro usuario. +playauthenticate.merge.accounts.ok=OK + +playauthenticate.link.account.title=Enlazar cuenta +playauthenticate.link.account.question=¿Enlazar ({0}) con su usuario? +playauthenticate.link.account.true=Sí, ¡enlaza esta cuenta! +playauthenticate.link.account.false=No, salir y crear un nuevo usuario con esta cuenta +playauthenticate.link.account.ok=OK + +# play-authenticate: Signup folder translations + +playauthenticate.verify.email.title=Verifique su email +playauthenticate.verify.email.requirement=Antes de usar PlayAuthenticate, debe validar su email. +playauthenticate.verify.email.cta=Se le ha enviado un email a la dirección registrada. Por favor, siga el link de este email para activar su cuenta. +playauthenticate.password.reset.title=Restablecer contraseña +playauthenticate.password.reset.cta=Restablecer mi contraseña + +playauthenticate.password.forgot.title=Contraseña olvidada +playauthenticate.password.forgot.cta=Enviar instrucciones para restablecer la contraseña + +playauthenticate.oauth.access.denied.title=Acceso denegado por OAuth +playauthenticate.oauth.access.denied.explanation=Si quiere usar PlayAuthenticate con OAuth, debe aceptar la conexión. +playauthenticate.oauth.access.denied.alternative=Si prefiere no hacerlo, puede también +playauthenticate.oauth.access.denied.alternative.cta=registrarse con un usuario y una contraseña. + +playauthenticate.token.error.title=Error de token +playauthenticate.token.error.message=El token ha caducado o no existe. + +playauthenticate.user.exists.title=El usuario existe +playauthenticate.user.exists.message=Otro usario ya está dado de alta con este identificador. + +# play-authenticate: Navigation +playauthenticate.navigation.profile=Perfil +playauthenticate.navigation.link_more=Enlazar más proveedores +playauthenticate.navigation.logout=Salir +playauthenticate.navigation.login=Entrar +playauthenticate.navigation.home=Inicio +playauthenticate.navigation.restricted=Página restringida +playauthenticate.navigation.signup=Dárse de alta + +# play-authenticate: Handler +playauthenticate.handler.loginfirst=Para ver ''{0}'', debe darse primero de alta. + +# play-authenticate: Profile +playauthenticate.profile.title=Perfil de usuario +playauthenticate.profile.mail=Su nombre es {0} y su dirección de mail es {1}! +playauthenticate.profile.unverified=sin validar - haga click para validar +playauthenticate.profile.verified=validada +playauthenticate.profile.providers_many=Hay {0} proveedores enlazados con su cuenta: +playauthenticate.profile.providers_one = Hay un proveedor enlazado con su cuenta: +playauthenticate.profile.logged=Ha entrado con: +playauthenticate.profile.session=Su ID de usuario es {0}. Su sesión expirará el {1}. +playauthenticate.profile.session_endless=Su ID de usuario es {0}. Su sesión no expirará nunca porque no tiene caducidad. +playauthenticate.profile.password_change=Cambie/establezca una contraseña para su cuenta + +# play-authenticate - sample: Index page +playauthenticate.index.title=Bienvenido Play Authenticate +playauthenticate.index.intro=Aplicación de ejemplo de Play Authenticate +playauthenticate.index.intro_2=Esto es una plantilla para una sencilla aplicación con autentificación y autorización +playauthenticate.index.intro_3=Mire la barra de navegación superior para ver ejemplos sencillos incluyendo las características soportadas de autentificación. +playauthenticate.index.heading=Cabecera +playauthenticate.index.details=Ver detalles + +# play-authenticate - sample: Restricted page +playauthenticate.restricted.secrets=¡Secretos y más secretos! + +### --- play-authenticate END diff --git a/samples/scala/play-authenticate-usage/conf/messages.fr b/samples/scala/play-authenticate-usage/conf/messages.fr new file mode 100644 index 00000000..78168aa1 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/messages.fr @@ -0,0 +1,149 @@ +# Override default Play's validation messages + +# --- Constraints +constraint.required=Obligatoire +constraint.min=Valeur minimale: {0} +constraint.max=Valeur maximale: {0} +constraint.minLength=Longueur minimale: {0} +constraint.maxLength=Longueur maximale: {0} +constraint.email=Email + +# --- Formats +format.date=Date (''{0}'') +format.numeric=Numérique +format.real=Réel + +# --- Errors +error.invalid=Valeur non autorisée +error.required=Champ obligatoire +error.number=Seul les valeurs numériques sont autorisées +error.real=Seul les valeurs réelles sont autorisées +error.min=Doit être plus grand ou égal à {0} +error.max=Doit être plus petit ou égal à 0} +error.minLength=Longueur minimale: {0} +error.maxLength=Longueur maximale: {0} +error.email=Un email valide est obligatoire +error.pattern=Doit satisfaire: {0} + +### --- play-authenticate START + +# play-authenticate: Initial translations + +playauthenticate.accounts.link.success=Comptes liés avec succès +playauthenticate.accounts.merge.success=Comptes unifiés avec succès + +playauthenticate.verify_email.error.already_validated=Votre email a déjà été validé. +playauthenticate.verify_email.error.set_email_first=Vous devez d'abord fournir un email. +playauthenticate.verify_email.message.instructions_sent=Les instructions pour valider votre email ont été envoyé à l'adresse {0}. +playauthenticate.verify_email.success=L'adresse E-mail ({0}) a été validée avec succès. + +playauthenticate.reset_password.message.instructions_sent=Les instructions pour changer votre mot de passe ont été envoyées à l'adresse: {0}. +playauthenticate.reset_password.message.email_not_verified=Votre email doit d'abord être vérifié, des instructions ont été envoyées. Réessayez ensuite. +playauthenticate.reset_password.message.no_password_account=Votre utilisateur n'est pas configuré pour utiliser un mot de passe. +playauthenticate.reset_password.message.success.auto_login=Votre mot de passe a été changé. +playauthenticate.reset_password.message.success.manual_login=Votre mot de passe a été changé. Veillez vous connecter avec votre nouveau mot de passe. + +playauthenticate.change_password.error.passwords_not_same=Les mots de passe ne correspondent pas. +playauthenticate.change_password.success=Mot de passe changé avec succès. + +playauthenticate.password.signup.error.passwords_not_same=Les mots de passe ne correspondent pas. +playauthenticate.password.login.unknown_user_or_pw=Utilisateur et mot de passe inconnus. + +playauthenticate.password.verify_signup.subject=PlayAuthenticate: Finaliser votre enregistrement +playauthenticate.password.verify_email.subject=PlayAuthenticate: Confirmer votre email +playauthenticate.password.reset_email.subject=PlayAuthenticate: Comment changer votre mot de passe. + +# play-authenticate: Additional translations + +playauthenticate.login.email.placeholder=Votre adresse email +playauthenticate.login.password.placeholder=Choisir un mot de passe +playauthenticate.login.password.repeat=Réitérer votre mot de passe +playauthenticate.login.title=Login +playauthenticate.login.password.placeholder=Mot de passe +playauthenticate.login.now=Se connecter maintenant +playauthenticate.login.forgot.password=Mot de passe oublié? +playauthenticate.login.oauth=ou connectez-vous avec un de ces fournisseurs: + +playauthenticate.signup.title=Enregistrement +playauthenticate.signup.name=Votre nom +playauthenticate.signup.now=S'enregistrer maintenant +playauthenticate.signup.oauth=ou enregistrez-vous avec un de ces fournisseurs: + +playauthenticate.verify.account.title=Vérification par email obligatoire +playauthenticate.verify.account.before=Avant de spécifier un mot de passe, vous devez +playauthenticate.verify.account.first=d'abord vérifier votre email + +playauthenticate.change.password.title=Changer votre mot de passe ici +playauthenticate.change.password.cta=Changer votre mot de passe + +playauthenticate.merge.accounts.title=Unifier des comptes +playauthenticate.merge.accounts.question=Voulez-vous unifier le compte ({0}) avec le compte: {1}? +playauthenticate.merge.accounts.true=Oui, unifier les deux comptes +playauthenticate.merge.accounts.false=Non, quitter la session et se connecter avec un autre compte +playauthenticate.merge.accounts.ok=OK + +playauthenticate.link.account.title=Lier les comptes +playauthenticate.link.account.question=Lier ({0}) avec votre utilisateur? +playauthenticate.link.account.true=Oui, lier ce compte +playauthenticate.link.account.false=Non, quitter la session et créer un nouveau compte +playauthenticate.link.account.ok=OK + +# play-authenticate: Signup folder translations + +playauthenticate.verify.email.title=Verifier votre e-mail +playauthenticate.verify.email.requirement=Avant d'utiliser PlayAuthenticate, vous devez d'abord vérifier votre email. +playauthenticate.verify.email.cta=Un email a été envoyé à votre adresse avec des instructions pour vous connecter. + +playauthenticate.password.reset.title=Changer votre mot de passe +playauthenticate.password.reset.cta=Changer votre mot de passe + +playauthenticate.password.forgot.title=Mot de passe oublié +playauthenticate.password.forgot.cta=Envoyer les instructions pour changer le mot de passe + +playauthenticate.oauth.access.denied.title=Accès OAuth refusé +playauthenticate.oauth.access.denied.explanation=Si vous voulez utiliser PlayAuthenticate avec OAuth, vous devez accepter la connexion. +playauthenticate.oauth.access.denied.alternative=Si vous ne préférez pas accepter la connexion, vous pouvez toujours +playauthenticate.oauth.access.denied.alternative.cta=vous enregistrer avec un nouveau compte. + +playauthenticate.token.error.title=Erreur de token +playauthenticate.token.error.message=Le token reçu est soit trop vieux, soit il n'existe pas. + +playauthenticate.user.exists.title=L'utilisateur existe déjà +playauthenticate.user.exists.message=Cet utilisateur existe déjà. + +# play-authenticate: Navigation +playauthenticate.navigation.profile=Profile +playauthenticate.navigation.link_more=Lier d'autres fournisseurs +playauthenticate.navigation.logout=Se Déconnecter +playauthenticate.navigation.login=Se Connecter +playauthenticate.navigation.home=Page Principale +playauthenticate.navigation.restricted=Page Protégée +playauthenticate.navigation.signup=S'enregister + +# play-authenticate: Handler +playauthenticate.handler.loginfirst=Vous devez vous connecter pour accéder à: ''{0}'' + +# play-authenticate: Profile +playauthenticate.profile.title=Profile d'utilisateur +playauthenticate.profile.mail=Votre nom est {0} et votre adresse email {1}! +playauthenticate.profile.unverified=non vérifiée - cliquer pour vérifier +playauthenticate.profile.verified=vérifiée +playauthenticate.profile.providers_many=Il y a {0} fournisseurs liés à ce compte: +playauthenticate.profile.providers_one =Il y a un fournisseur lié à ce compte: +playauthenticate.profile.logged=Vous êtes connecté avec: +playauthenticate.profile.session=Votre ID d'utilisateur est {0} et votre session se termine le {1} +playauthenticate.profile.session_endless=Votre ID d'utilisateur est {0} et votre session ne se terminera jamais +playauthenticate.profile.password_change=Changer le mot de passe de votre compte + +# play-authenticate - sample: Index page +playauthenticate.index.title=Bienvenu sur Play Authenticate +playauthenticate.index.intro=Play Authenticate démo +playauthenticate.index.intro_2=Ceci est un modèle d'application avec authentification. +playauthenticate.index.intro_3=Essayez la barre de navigation pour voir les fonctions d'authentification. +playauthenticate.index.heading=Entête +playauthenticate.index.details=Voir les détails + +# play-authenticate - sample: Restricted page +playauthenticate.restricted.secrets=Ils nous cachent la vérité! + +### --- play-authenticate END diff --git a/samples/scala/play-authenticate-usage/conf/messages.ja b/samples/scala/play-authenticate-usage/conf/messages.ja new file mode 100644 index 00000000..8079cf02 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/messages.ja @@ -0,0 +1,149 @@ +# Override default Play's validation messages + +# --- Constraints +constraint.required=必須 +constraint.min=最小値: {0} +constraint.max=最大値: {0} +constraint.minLength=最短文字数: {0} +constraint.maxLength=最長文字数: {0} +constraint.email=電子メール + +# --- Formats +format.date=日付 (''{0}'') +format.numeric=整数 +format.real=実数 + +# --- Errors +error.invalid=不正な値です +error.required=このフィールドは必須です +error.number=整数値を入力してください +error.real=実数を入力してください +error.min=値は {0} 以上でなければなりません +error.max=値は {0} 以下でなければなりません +error.minLength=文字列は最短 {0} 文字です +error.maxLength=文字列は最長 {0} 文字です +error.email=正しい電子メールアドレスにしてください +error.pattern={0} を満たす必要があります。 + +### --- play-authenticate START + +# play-authenticate: Initial translations + +playauthenticate.accounts.link.success=アカウントは正しく紐付けられました +playauthenticate.accounts.merge.success=アカウントは正しくマージされました + +playauthenticate.verify_email.error.already_validated=電子メールアドレスはすでに確認済です。 +playauthenticate.verify_email.error.set_email_first=最初に電子メールアドレスを登録する必要があります。 +playauthenticate.verify_email.message.instructions_sent=電子メールアドレスの確認方法は {0} に送信されました。 +playauthenticate.verify_email.success=電子メールアドレス ({0}) は正しく確認されました。 + +playauthenticate.reset_password.message.instructions_sent=パスワードのリセット方法は {0} に送信されました。 +playauthenticate.reset_password.message.email_not_verified=アカウントが確認されていません。確認方法が記載されたメールは送信済です。確認後パスワードのリセットを行ってください。 +playauthenticate.reset_password.message.no_password_account=あなたのユーザーアカウントはパスワードを使用するように設定されていません。 +playauthenticate.reset_password.message.success.auto_login=パスワードはリセットされました。 +playauthenticate.reset_password.message.success.manual_login=パスハードはリセットされました。新しいパスワードでログインしてください。 + +playauthenticate.change_password.error.passwords_not_same=パスワードが一致しません。 +playauthenticate.change_password.success=パスハードは正常に変更されました。 + +playauthenticate.password.signup.error.passwords_not_same=パスワードが一致しません。 +playauthenticate.password.login.unknown_user_or_pw=不明なユーザー名かパスワードです。 + +playauthenticate.password.verify_signup.subject=PlayAuthenticate: サインアップ完了 +playauthenticate.password.verify_email.subject=PlayAuthenticate: 電子メールアドレス確認 +playauthenticate.password.reset_email.subject=PlayAuthenticate: パスワードリセットの方法 + +# play-authenticate: Additional translations + +playauthenticate.login.email.placeholder=お使いの電子メールアドレス +playauthenticate.login.password.placeholder=パスワードを入力 +playauthenticate.login.password.repeat=再度パスワードを入力 +playauthenticate.login.title=ログイン +playauthenticate.login.password.placeholder=パスワード +playauthenticate.login.now=ログイン完了 +playauthenticate.login.forgot.password=パスワードをお忘れですか? +playauthenticate.login.oauth=または以下のプロバイダーからログイン: + +playauthenticate.signup.title=サインアップ +playauthenticate.signup.name=お名前 +playauthenticate.signup.now=今すぐサインアップ +playauthenticate.signup.oauth=または以下のプロバイダーからサインアップ: + +playauthenticate.verify.account.title=電子メールによる確認が必要 +playauthenticate.verify.account.before=パスワードを設定する前に、 +playauthenticate.verify.account.first=電子メールアドレスの確認が必要です + +playauthenticate.change.password.title=ここでパスワードの変更 +playauthenticate.change.password.cta=パスワードを変更 + +playauthenticate.merge.accounts.title=アカウントのマージ +playauthenticate.merge.accounts.question=今のアカウント ({0}) をアカウント {1} とマージしますか? +playauthenticate.merge.accounts.true=はい、二つのアカウントをマージします +playauthenticate.merge.accounts.false=いいえ、今のセッションを抜けて新たにログインします +playauthenticate.merge.accounts.ok=OK + +playauthenticate.link.account.title=アカウントの紐付け +playauthenticate.link.account.question=({0}) を自分のアカウントと紐付けますか? +playauthenticate.link.account.true=はい、アカウントを紐付けします +playauthenticate.link.account.false=いいえ、ログアウトしてこのアカウントに対応する別のユーザーを作ります +playauthenticate.link.account.ok=OK + +# play-authenticate: Signup folder translations + +playauthenticate.verify.email.title=電子メールアドレスの確認 +playauthenticate.verify.email.requirement=PlayAuthentificateを利用する前に、まずは電子メールアドレスを確認する必要があります。 +playauthenticate.verify.email.cta=登録されたアドレスにメールが送られます。アカウントを有効にするためにメール内のリンクをクリックしてください。 + +playauthenticate.password.reset.title=パスワードのリセット +playauthenticate.password.reset.cta=パスワードをリセットする + +playauthenticate.password.forgot.title=パスワードを忘れた +playauthenticate.password.forgot.cta=パスワードリセットの手順を送付する + +playauthenticate.oauth.access.denied.title=OAuthアクセスが未許可 +playauthenticate.oauth.access.denied.explanation=PlayAuthenticateをOAuthで使いたい場合は、接続を許可する必要があります。 +playauthenticate.oauth.access.denied.alternative=そのようにしたくない場合は、代わりに +playauthenticate.oauth.access.denied.alternative.cta=ユーザー名とパスワードで登録することもできます。 + +playauthenticate.token.error.title=トークンエラー +playauthenticate.token.error.message=与えられたトークンは失効しているか存在しません。 + +playauthenticate.user.exists.title=重複したユーザー +playauthenticate.user.exists.message=このユーザーはすでに存在します。 + +# play-authenticate: Navigation +playauthenticate.navigation.profile=プロフィール +playauthenticate.navigation.link_more=ほかのプロバイダーと紐付ける +playauthenticate.navigation.logout=サインアウト +playauthenticate.navigation.login=ログイン +playauthenticate.navigation.home=ホーム +playauthenticate.navigation.restricted=制限されたページ +playauthenticate.navigation.signup=サインアップ + +# play-authenticate: Handler +playauthenticate.handler.loginfirst=''{0}'' を見るにはまずログインが必要です。 + +# play-authenticate: Profile +playauthenticate.profile.title=ユーザープロフィール +playauthenticate.profile.mail=あなたのお名前は {0} でメールアドレスは {1} です! +playauthenticate.profile.unverified=未確認 - 確認を押してください +playauthenticate.profile.verified=確認済 +playauthenticate.profile.providers_many={0} 個のプロバイダーがアカウントに紐付いています: +playauthenticate.profile.providers_one = 1 個のプロバイダーがアカウントに紐付いています: +playauthenticate.profile.logged=現在次の手段でログインしています: +playauthenticate.profile.session=あなたのユーザーIDは {0} でセッションは {1} に失効します +playauthenticate.profile.session_endless=あなたのユーザーIDは {0} でセッションは永遠に失効しません +playauthenticate.profile.password_change=パスワードの変更/設定 + +# play-authenticate - sample: Index page +playauthenticate.index.title=Play Authenticate へようこそ! +playauthenticate.index.intro=Play Authenticate サンプルアプリ +playauthenticate.index.intro_2=これは認証機能を持つシンプルなアプリケーションです。 +playauthenticate.index.intro_3=上にあるメインナビゲーションでサポートされた認証機能をお試しください。 +playauthenticate.index.heading=タイトル +playauthenticate.index.details=詳細を見る + +# play-authenticate - sample: Restricted page +playauthenticate.restricted.secrets=ふふ、秘密はどこにでもあるのですよ! + +### --- play-authenticate END diff --git a/samples/scala/play-authenticate-usage/conf/messages.pl b/samples/scala/play-authenticate-usage/conf/messages.pl new file mode 100644 index 00000000..834760cf --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/messages.pl @@ -0,0 +1,149 @@ +# Override default Play's validation messages + +# --- Constraints +constraint.required=Wymagane +constraint.min=Minimalna wartość: {0} +constraint.max=Maksymalna wartość: {0} +constraint.minLength=Minimalna długość: {0} +constraint.maxLength=Maksymalna długość: {0} +constraint.email=Email + +# --- Formats +format.date=Data (''{0}'') +format.numeric=Numeryczny +format.real=Real + +# --- Errors +error.invalid=Niepoprawna wartość +error.required=To pole jest wymagane +error.number=Wymagana wartość numeryczna +error.real=Real number value expected +error.min=Musi być większe lub równe niż {0} +error.max=Musi być mniejsze lub równe niż {0} +error.minLength=Minimalna długość {0} +error.maxLength=Maksymalna długość {0} +error.email=Wymagany poprawny adres e-mail +error.pattern=Must satisfy {0} + +### --- play-authenticate START + +# play-authenticate: Initial translations + +playauthenticate.accounts.link.success=Konto został podłączone +playauthenticate.accounts.merge.success=Konta zostały złączone + +playauthenticate.verify_email.error.already_validated=Twój adres został już zweryfikowany. +playauthenticate.verify_email.error.set_email_first=Najpierw musisz podać adres e-mail. +playauthenticate.verify_email.message.instructions_sent=Instrukcje dotyczące weryfikacji adresu zostały wysłane na adres {0}. +playauthenticate.verify_email.success=Adres e-mail ({0}) został poprawnie zweryfikowany. + +playauthenticate.reset_password.message.instructions_sent=Instrukcje dotyczące przywracania hasła zostały wysłane na adres {0}. +playauthenticate.reset_password.message.email_not_verified=Twoje konto nie zostało jeszcze zweryfikowane. Na wskazany adres zostały wysłane instrukcje dotyczące weryfikacji. Dopiero po weryfikacji spróbuj przywrócić hasło w razie potrzeby. +playauthenticate.reset_password.message.no_password_account=Dla tego konta nie ustawiono jeszcze możliwości logowania za pomocą hasła. +playauthenticate.reset_password.message.success.auto_login=Twoje hasło zostało przywrócone. +playauthenticate.reset_password.message.success.manual_login=Twoje hasło zostało przywrócone. Zaloguj się ponownie z użyciem nowego hasła. + +playauthenticate.change_password.error.passwords_not_same=Hasła nie są takie same. +playauthenticate.change_password.success=Hasło zostało zmienione. + +playauthenticate.password.signup.error.passwords_not_same=Hasła nie są takie same. +playauthenticate.password.login.unknown_user_or_pw=Nieznany użytkownik lub złe hasło. + +playauthenticate.password.verify_signup.subject=PlayAuthenticate: Zakończ rejestrację +playauthenticate.password.verify_email.subject=PlayAuthenticate: Potwierdź adres e-mail +playauthenticate.password.reset_email.subject=PlayAuthenticate: Jak ustalić nowe hasło + +# play-authenticate: Additional translations + +playauthenticate.login.email.placeholder=Twój adres e-mail +playauthenticate.login.password.placeholder=Podaj hasło +playauthenticate.login.password.repeat=Powtórz hasło +playauthenticate.login.title=Logowanie +playauthenticate.login.password.placeholder=Hasło +playauthenticate.login.now=Zaloguj się +playauthenticate.login.forgot.password=Nie pamiętasz hasła? +playauthenticate.login.oauth=lub zaloguj się z innym dostawcą: + +playauthenticate.signup.title=Rejestracja +playauthenticate.signup.name=Imię i nazwisko +playauthenticate.signup.now=Zarejestruj się +playauthenticate.signup.oauth=lub zarejestruj się z innym dostawcą: + +playauthenticate.verify.account.title=Wymagana weryfikacja adresu e-mail +playauthenticate.verify.account.before=Zanim ustawisz nowe hasło +playauthenticate.verify.account.first=musisz zweryfikować swój adres e-mail. + +playauthenticate.change.password.title=Zmień hasło +playauthenticate.change.password.cta=Zmień moje hasło + +playauthenticate.merge.accounts.title=Złącz konta +playauthenticate.merge.accounts.question=Czy chcesz połączyć aktualne konto ({0}) z kontem: {1}? +playauthenticate.merge.accounts.true=Tak, połącz oba konta +playauthenticate.merge.accounts.false=Nie, opuść bieżącą sesję i zaloguj się jako nowy użytkownik +playauthenticate.merge.accounts.ok=OK + +playauthenticate.link.account.title=Dołącz konto +playauthenticate.link.account.question=Czy chcesz dołączyć konto ({0}) do swojego aktualnego konta użytkownika? +playauthenticate.link.account.true=Tak, dołącz to konto +playauthenticate.link.account.false=Nie, wyloguj mnie i utwórz nowe konto użytkownika +playauthenticate.link.account.ok=OK + +# play-authenticate: Signup folder translations + +playauthenticate.verify.email.title=Potwierdź adres e-mail +playauthenticate.verify.email.requirement=Musisz potwierdzić swój adres e-mail, aby korzytać z PlayAuthenticate +playauthenticate.verify.email.cta=Na wskazany adres została przesłana informacja. Skorzystaj z dołączonego do niej linku aby aktywować konto. + +playauthenticate.password.reset.title=Przywróć hasło +playauthenticate.password.reset.cta=Przywróć moje hasło + +playauthenticate.password.forgot.title=Nie pamiętam hasła +playauthenticate.password.forgot.cta=Prześlij instrukcję dot. przywracania hasła + +playauthenticate.oauth.access.denied.title=Dostęp OAuth zabroniony +playauthenticate.oauth.access.denied.explanation=Jeśli chcesz używać PlayAuthenticate za pomocą OAuth, musisz zaakceptować połączenie. +playauthenticate.oauth.access.denied.alternative=Jeśli wolisz tego nie robić możesz również +playauthenticate.oauth.access.denied.alternative.cta=zarejestrować się podając nazwę użytkownika i hasło + +playauthenticate.token.error.title=Błąd tokena +playauthenticate.token.error.message=Podany token stracił ważność lub nie istnieje. + +playauthenticate.user.exists.title=Użytkownik istnieje +playauthenticate.user.exists.message=Ten użytkownik już istnieje. + +# play-authenticate: Navigation +playauthenticate.navigation.profile=Profil +playauthenticate.navigation.link_more=Dołącz więcej dostawców +playauthenticate.navigation.logout=Wyloguj się +playauthenticate.navigation.login=Zaloguj się +playauthenticate.navigation.home=Strona główna +playauthenticate.navigation.restricted=Strona zastrzeżona +playauthenticate.navigation.signup=Zarejestruj się + +# play-authenticate: Handler +playauthenticate.handler.loginfirst=Musisz się zalogować, aby uzyskać dostęp do strony ''{0}'' + +# play-authenticate: Profile +playauthenticate.profile.title=Profil użytkownika +playauthenticate.profile.mail=Nazywasz się {0} a twój e-mail to {1}! +playauthenticate.profile.unverified=Niezweryfikowany - kliknij +playauthenticate.profile.verified=zweryfikowany +playauthenticate.profile.providers_many=Dostawcy podłączeni do Twojego konta ({0}): +playauthenticate.profile.providers_one = Jedyny dostawca podłączony do Twojego konta: +playauthenticate.profile.logged=Do obecnego zalogowania użyto: +playauthenticate.profile.session=ID tego konta to {0} a jego sesja wygaśnie {1} +playauthenticate.profile.session_endless=ID tego konta to {0}, jego sesja nie wygasa automatycznie +playauthenticate.profile.password_change=Zmień lub ustaw hasło dla tego konta + +# play-authenticate - przykład: Index page +playauthenticate.index.title=Witaj w Play Authenticate +playauthenticate.index.intro=Przykład Play Authenticate +playauthenticate.index.intro_2=Oto szablon prostej aplikacji wykorzystującej Play Authenticate. +playauthenticate.index.intro_3=Skorzystaj z powyższej nawigacji aby przetestować działanie autentykacji. +playauthenticate.index.heading=Nagłówek +playauthenticate.index.details=Szczegóły + +# play-authenticate - przykład: Restricted page +playauthenticate.restricted.secrets=Tajemnice, tajemnice, tajemnice... Wszędzie tajemnice! + +### --- play-authenticate END \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/conf/messages.pt b/samples/scala/play-authenticate-usage/conf/messages.pt new file mode 100644 index 00000000..8b68f084 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/messages.pt @@ -0,0 +1,149 @@ +# Override default Play's validation messages + +# --- Constraints +constraint.required=Necessário +constraint.min=Valor mínimo: {0} +constraint.max=Valor máximo: {0} +constraint.minLength=Comprimento mínimo: {0} +constraint.maxLength=Comprimento máximo: {0} +constraint.email=Endereço de email + +# --- Formats +format.date=Data (''{0}'') +format.numeric=Numérico +format.real=Real + +# --- Errors +error.invalid=Valor inválido +error.required=Este campo é necessário +error.number=Valor numérico esperado +error.real=Valor real esperado +error.min=Tem que ser maior ou igual a {0} +error.max=Tem que ser menor ou igual a {0} +error.minLength=O comprimento mínimo é {0} +error.maxLength=O comprimento máximo é {0} +error.email=á necessário email válido +error.pattern=Tem que satisfazer {0} + +### --- play-authenticate START + +# play-authenticate: Initial translations + +playauthenticate.accounts.link.success=Contas ligadas com sucesso +playauthenticate.accounts.merge.success=Contas fundidads com sucesso + +playauthenticate.verify_email.error.already_validated=O seu endereço de email já foi validado. +playauthenticate.verify_email.error.set_email_first=Precisa de introduzir um novo endereço de email primeiro. +playauthenticate.verify_email.message.instructions_sent=Instruções sobre como verificar o seu endereço de email foram enviadas para {0}. +playauthenticate.verify_email.success=O endereço de email ({0}) foi verificado com sucesso. + +playauthenticate.reset_password.message.instructions_sent=Instruções sobre como criar uma nova palavra passe foram enviadas para {0}. +playauthenticate.reset_password.message.email_not_verified=A sua conta não foi verificada ainda. Uma mensagem de email com instruções de verificaáão foi enviada. Actualize a palavra passe mais tarde. +playauthenticate.reset_password.message.no_password_account=O utilizador ainda não configurou uma palavra passe. +playauthenticate.reset_password.message.success.auto_login=A sua palavra passe foi actualizada. +playauthenticate.reset_password.message.success.manual_login=A sua palavra passe foi actualizada. Por favor, autentique-se com a nova palavra passe. + +playauthenticate.change_password.error.passwords_not_same=Palavras passe não correspondem. +playauthenticate.change_password.success=Palavra passe alterada com sucesso. + +playauthenticate.password.signup.error.passwords_not_same=Palavras passe não correspondem. +playauthenticate.password.login.unknown_user_or_pw=Utilizador ou palavra passe desconhecido/a. + +playauthenticate.password.verify_signup.subject=PlayAuthenticate: Complete o seu registo +playauthenticate.password.verify_email.subject=PlayAuthenticate: Confirme o seu endereço de email +playauthenticate.password.reset_email.subject=PlayAuthenticate: Como actualizar a palavra passe + +# play-authenticate: Additional translations + +playauthenticate.login.email.placeholder=O seu endereço de email +playauthenticate.login.password.placeholder=Escolha uma palavra passe +playauthenticate.login.password.repeat=Repita a palavra passe +playauthenticate.login.title=Autenticar +playauthenticate.login.password.placeholder=Palavra passe +playauthenticate.login.now=Autenticar agora +playauthenticate.login.forgot.password=Esqueceu a palavra passe? +playauthenticate.login.oauth=ou autentique-se utilizando um dos seguintes serviços: + +playauthenticate.signup.title=Registar +playauthenticate.signup.name=O seu nome +playauthenticate.signup.now=Registe-se agora +playauthenticate.signup.oauth=ou registe-se utilizando um dos seguintes serviços: + +playauthenticate.verify.account.title=á necessário verificar o endereço de email +playauthenticate.verify.account.before=Antes de criar uma nova palavra passe, precisa +playauthenticate.verify.account.first=verificar endereço de email. + +playauthenticate.change.password.title=Altere palavra passe aqui +playauthenticate.change.password.cta=Alterar minha palavra passe + +playauthenticate.merge.accounts.title=Fundir contas +playauthenticate.merge.accounts.question=Deseja fundir esta conta ({0}) com esta conta: {1}? +playauthenticate.merge.accounts.true=Sim, quero fundir as duas contas. +playauthenticate.merge.accounts.false=Não, quero terminar a sessão actual e autenticar-me como novo utilizador. +playauthenticate.merge.accounts.ok=OK + +playauthenticate.link.account.title=Ligar contas +playauthenticate.link.account.question=Ligar ({0}) com o utilizador? +playauthenticate.link.account.true=Sim, quero ligar a esta conta. +playauthenticate.link.account.false=Não, quero sair e criar um novo utilizador com esta conta. +playauthenticate.link.account.ok=OK + +# play-authenticate: Signup folder translations + +playauthenticate.verify.email.title=Verifique o seu endereço de email +playauthenticate.verify.email.requirement=Antes de usar o PlayAuthenticate, terá que verificar o seu endereço de email. +playauthenticate.verify.email.cta=Foi enviada uma mensagem para o endereço de email registado. Por favor, siga a ligação indicada para activar a sua conta.. + +playauthenticate.password.reset.title=Actualizar palavra passe +playauthenticate.password.reset.cta=Actualizar a minha palavra passe + +playauthenticate.password.forgot.title=Esqueci-me da palavra passe +playauthenticate.password.forgot.cta=Enviar instruções para reestabelecer palavra passe + +playauthenticate.oauth.access.denied.title=Acesso negado ao OAuth +playauthenticate.oauth.access.denied.explanation=Se quiser utilizador o PlayAuthenticate com OAuth, terá que aceitar a ligação. +playauthenticate.oauth.access.denied.alternative=Se não quiser, poderá alternativamente +playauthenticate.oauth.access.denied.alternative.cta=autenticar-se com utilizador e palavra passe + +playauthenticate.token.error.title=Erro no "token" +playauthenticate.token.error.message=O "token" fornecido expirou ou não existe. + +playauthenticate.user.exists.title=Utilizador existente. +playauthenticate.user.exists.message=Este utilizador já existe. + +# play-authenticate: Navigation +playauthenticate.navigation.profile=Perfil +playauthenticate.navigation.link_more=Ligar mais serviços +playauthenticate.navigation.logout=Sair +playauthenticate.navigation.login=Autenticar +playauthenticate.navigation.home=Home +playauthenticate.navigation.restricted=Página restrita +playauthenticate.navigation.signup=Registar + +# play-authenticate: Handler +playauthenticate.handler.loginfirst=Precisa de autenticar-se para ver ''{0}'' + +# play-authenticate: Profile +playauthenticate.profile.title=Perfil de utilizador +playauthenticate.profile.mail=O seu nome á {0} e o seu endereço de email é {1}! +playauthenticate.profile.unverified=não verificado - clique para verificar +playauthenticate.profile.verified=verificado +playauthenticate.profile.providers_many=Há {0} serviços ligados á sua conta: +playauthenticate.profile.providers_one = Não há serviços ligados á sua conta: +playauthenticate.profile.logged=Está actualmente autenticado com: +playauthenticate.profile.session=O seu ID de utilzador é {0} e a sua sessão irá experirar em {1} +playauthenticate.profile.session_endless=O seu ID de utilzador é {0} e a sua sessão não irá experirar, porque não tem fim +playauthenticate.profile.password_change=Alterar/criar palavra passe para esta conta + +# play-authenticate - sample: Index page +playauthenticate.index.title=Bem-vindo ao Play Authenticate +playauthenticate.index.intro=Play Authenticate aplicação exemplo +playauthenticate.index.intro_2=This is a template for a simple application with authentication. +playauthenticate.index.intro_3=Check the main navigation above for simple page examples including supported authentication features. +playauthenticate.index.heading=Cabeçalho +playauthenticate.index.details=Ver detalhes + +# play-authenticate - sample: Restricted page +playauthenticate.restricted.secrets=Segredos, por todo o lado! + +### --- play-authenticate END diff --git a/samples/scala/play-authenticate-usage/conf/play-authenticate/deadbolt.conf b/samples/scala/play-authenticate-usage/conf/play-authenticate/deadbolt.conf new file mode 100644 index 00000000..dba4edf5 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/play-authenticate/deadbolt.conf @@ -0,0 +1,8 @@ +# ------- Deadbolt ------- +deadbolt { + java { + handler=security.MyDeadboltHandler, + # cache-user is set to false, otherwise it's not possible to mix deadbolt handler that do and don't have users in the template examples + cache-user=true + } +} \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/conf/play-authenticate/mine.conf b/samples/scala/play-authenticate-usage/conf/play-authenticate/mine.conf new file mode 100644 index 00000000..638f6c7a --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/play-authenticate/mine.conf @@ -0,0 +1,296 @@ +##################################################################################### +# +# My play-authenticate settings +# +##################################################################################### + +play-authenticate { + + # Settings for the password-based authentication provider + # if you are not using it, you can remove this portion of the config file + password { + mail { + verificationLink { + # Whether the verification link will be HTTPS + secure=false + } + passwordResetLink { + # Whether the password reset link will be HTTPS + secure=false + } + from { + # Mailing from address + email="you@gmail.com" + + # Mailing name + name=Play Authenticate + } + # Pause between email jobs (in seconds) + delay=1 + } + # Whether to directly log in after the password reset (true) + # or send the user to the login page (false) + loginAfterPasswordReset=true + } + + # Settings for the http basic auth provider + # if you are not using it (and you shouldn't), you can remove this portion + # of the config file + basic { + realm=Play_Authenticate + } + + # Settings for the spnego auth provider + # if you are not using it, you can remove this portion of the config file + spnego { + realm=EXAMPLE.COM + kdc="192.168.1.1" + } + + # Settings for the foursquare-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the Foursquare provider from conf/play.plugins + foursquare { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Foursquare credentials + # These are mandatory for using OAuth and need to be provided by you, + # if you want to use foursquare as an authentication provider. + # Get the credentials here: https://de.foursquare.com/oauth/ + # Remove leading '#' after entering + # clientId= + # clientSecret= + } + + # Settings for the twitter-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the Twitter provider from conf/play.plugins + twitter { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Twitter credentials + # These are mandatory for using OAuth and need to be provided by you, + # if you want to use twitter as an authentication provider. + # Get the credentials here: https://dev.twitter.com/docs/auth/oauth + # Remove leading '#' after entering + # consumerKey= + # consumerSecret= + + } + + # Settings for the linkedin-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the Linkedin provider from conf/play.plugins + linkedin { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Linkedin credentials + # These are mandatory for using OAuth and need to be provided by you, + # if you want to use linkedin as an authentication provider. + # Get the credentials here: http://developer.linkedin.com/ + # Remove leading '#' after entering + # The consumer key is called "API key" by linkedIn + # consumerKey= + # The consumer secret is called "Secret key" by linkedIn + # consumerSecret= + + } + + # Settings for the facebook-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the facebook provider from conf/play.plugins + facebook { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Facebook credentials + # These are mandatory for using OAuth and need to be provided by you, + # if you want to use facebook as an authentication provider. + # Get them here: https://developers.facebook.com/apps + # Remove leading '#' after entering + # clientId= + # clientSecret= + } + + # Settings for the google-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the Google provider from conf/play.plugins + google { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Google credentials + # These are mandatory for using OAuth and need to be provided by you, + # if you want to use Google as an authentication provider. + # Get them here: https://code.google.com/apis/console + # Remove leading '#' after entering + # clientId= + # clientSecret= + } + + # Settings for the VK-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the VK provider from conf/play.plugins + vk { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # VK credentials + # These are mandatory for using OAuth and need to be provided by you, + # if you want to use VK.com as an authentication provider. + # Get them here: http://vk.com/editapp?act=create + # Called 'Application ID' and 'Secure key' + # Remove leading '#' after entering + # clientId= + # clientSecret= + } + + # Settings for the OpenID-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the OpenID provider from conf/play.plugins + openid { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + } + + # Settings for the XING-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the XING provider from conf/play.plugins + xing { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # XING credentials + # Get them here: https://dev.xing.com/ + # Remove leading '#' after entering + # consumerKey= + # consumerSecret= + } + + # Settings for the Untappd-based authentication provider + # if you are not using it, you can remove this portion of the config file + # and remove the Untappd provider from conf/play.plugins + untappd { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Untappd credentials + # Get them here: https://untappd.com/api/ + # Remove leading '#' after entering + # clientId= + # clientSecret= + } + + # The Pocket settings + pocket { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Pocket credentials + # Get them here: http://getpocket.com/developer/apps/new + # Remove leading '#' after entering + # consumerKey= + } + + # The Github settings + github { + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # Read about available scopes here: http://developer.github.com/v3/oauth/#scopes + # scope="user,public_repo" + + # Github credentials + # Get them here: https://github.com/settings/applications/new + # Remove leading '#' after entering: + # clientId= + # clientSecret= + } + + eventbrite{ + redirectUri { + # Whether the redirect URI scheme should be HTTP or HTTPS (HTTP by default) + secure=false + + # You can use this setting to override the automatic detection + # of the host used for the redirect URI (helpful if your service is running behind a CDN for example) + # host=yourdomain.com + } + + # eventbrite credentials + # Get them here: http://developer.eventbrite.com/ + # Redirect URL should be something like: http://yourdomain.com/authenticate/eventbrite + # clientId= + # clientSecret= + } + +} diff --git a/samples/scala/play-authenticate-usage/conf/play-authenticate/smtp.conf b/samples/scala/play-authenticate-usage/conf/play-authenticate/smtp.conf new file mode 100644 index 00000000..7d46aec2 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/play-authenticate/smtp.conf @@ -0,0 +1,27 @@ +# SMTP mailer settings +smtp { + # TODO: Disable this in production + mock=true + # SMTP server + # (mandatory) + # defaults to gmail + host=smtp.gmail.com + + # SMTP port + # defaults to 25 + port=587 + + # Use SSL + # for GMail, this should be set to true + ssl=true + + # authentication user + # Optional, comment this line if no auth + # defaults to no auth + user="you@gmail.com" + + # authentication password + # Optional, comment this line to leave password blank + # defaults to no password + password=password +} diff --git a/samples/scala/play-authenticate-usage/conf/play.plugins b/samples/scala/play-authenticate-usage/conf/play.plugins new file mode 100644 index 00000000..793226c5 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/play.plugins @@ -0,0 +1,18 @@ +1500:com.typesafe.plugin.CommonsMailerPlugin +10000:be.objectify.deadbolt.java.DeadboltPlugin +10005:service.MyUserServicePlugin +#10010:com.feth.play.module.pa.providers.oauth2.google.GoogleAuthProvider +#10020:com.feth.play.module.pa.providers.oauth2.facebook.FacebookAuthProvider +#10030:com.feth.play.module.pa.providers.oauth2.foursquare.FoursquareAuthProvider +10040:providers.MyUsernamePasswordAuthProvider +10050:com.feth.play.module.pa.providers.openid.OpenIdAuthProvider +#10060:com.feth.play.module.pa.providers.oauth1.twitter.TwitterAuthProvider +#10070:com.feth.play.module.pa.providers.oauth1.linkedin.LinkedinAuthProvider +#10080:com.feth.play.module.pa.providers.oauth2.vk.VkAuthProvider +#10090:com.feth.play.module.pa.providers.oauth1.xing.XingAuthProvider +#10100:com.feth.play.module.pa.providers.oauth2.untappd.UntappdAuthProvider +#10110:com.feth.play.module.pa.providers.oauth2.pocket.PocketAuthProvider +#10120:com.feth.play.module.pa.providers.oauth2.github.GithubAuthProvider +10130:providers.MyStupidBasicAuthProvider +#10140:com.feth.play.module.pa.providers.wwwauth.negotiate.SpnegoAuthProvider +#10150:com.feth.play.module.pa.providers.oauth2.eventbrite.EventBriteAuthProvider diff --git a/samples/scala/play-authenticate-usage/conf/routes b/samples/scala/play-authenticate-usage/conf/routes new file mode 100644 index 00000000..05714e37 --- /dev/null +++ b/samples/scala/play-authenticate-usage/conf/routes @@ -0,0 +1,47 @@ +# Routes +# This file defines all application routes (Higher priority routes first) +# ~~~~ + +# Home page +GET / controllers.Application.index +GET /restricted controllers.Application.restricted +GET /assets/javascript/routes.js controllers.Application.jsRoutes + +GET /profile controllers.Application.profile + +GET /login controllers.Application.login +POST /login controllers.Application.doLogin + +GET /logout com.feth.play.module.pa.controllers.Authenticate.logout +GET /authenticate/:provider com.feth.play.module.pa.controllers.Authenticate.authenticate(provider: String) + +GET /signup controllers.Application.signup +POST /signup controllers.Application.doSignup + +GET /accounts/unverified controllers.Signup.unverified +GET /authenticate/:provider/denied controllers.Signup.oAuthDenied(provider: String) + +GET /accounts/verify/:token controllers.Signup.verify(token: String) +GET /accounts/exists controllers.Signup.exists + +GET /accounts/password/reset/:token controllers.Signup.resetPassword(token: String) +POST /accounts/password/reset controllers.Signup.doResetPassword + +GET /accounts/password/change controllers.Account.changePassword +POST /accounts/password/change controllers.Account.doChangePassword + +GET /accounts/verify controllers.Account.verifyEmail + +GET /accounts/add controllers.Account.link + +GET /accounts/link controllers.Account.askLink +POST /accounts/link controllers.Account.doLink + +GET /accounts/merge controllers.Account.askMerge +POST /accounts/merge controllers.Account.doMerge + +GET /login/password/forgot controllers.Signup.forgotPassword(email: String ?= "") +POST /login/password/forgot controllers.Signup.doForgotPassword + +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.at(path="/public", file) diff --git a/samples/scala/play-authenticate-usage/modules/play-authenticate b/samples/scala/play-authenticate-usage/modules/play-authenticate new file mode 100644 index 00000000..38f4746c --- /dev/null +++ b/samples/scala/play-authenticate-usage/modules/play-authenticate @@ -0,0 +1 @@ +../../../../code/ \ No newline at end of file diff --git a/samples/scala/play-authenticate-usage/project/build.properties b/samples/scala/play-authenticate-usage/project/build.properties new file mode 100644 index 00000000..be6c454f --- /dev/null +++ b/samples/scala/play-authenticate-usage/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.5 diff --git a/samples/scala/play-authenticate-usage/project/plugins.sbt b/samples/scala/play-authenticate-usage/project/plugins.sbt new file mode 100644 index 00000000..25f2dd0d --- /dev/null +++ b/samples/scala/play-authenticate-usage/project/plugins.sbt @@ -0,0 +1,8 @@ +// Comment to get more information during initialization +logLevel := Level.Warn + +// The Typesafe repository +resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" + +// Use the Play sbt plugin for Play projects +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % Option(System.getProperty("play.version")).getOrElse("2.3.2")) diff --git a/samples/scala/play-authenticate-usage/public/css/bootstrap.css b/samples/scala/play-authenticate-usage/public/css/bootstrap.css new file mode 100644 index 00000000..93531cad --- /dev/null +++ b/samples/scala/play-authenticate-usage/public/css/bootstrap.css @@ -0,0 +1,4914 @@ +/*! + * Bootstrap v2.0.4 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + line-height: 18px; + color: #333333; + background-color: #ffffff; +} +a { + color: #0088cc; + text-decoration: none; +} +a:hover { + color: #005580; + text-decoration: underline; +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + margin-left: 20px; +} +.container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.span12 { + width: 940px; +} +.span11 { + width: 860px; +} +.span10 { + width: 780px; +} +.span9 { + width: 700px; +} +.span8 { + width: 620px; +} +.span7 { + width: 540px; +} +.span6 { + width: 460px; +} +.span5 { + width: 380px; +} +.span4 { + width: 300px; +} +.span3 { + width: 220px; +} +.span2 { + width: 140px; +} +.span1 { + width: 60px; +} +.offset12 { + margin-left: 980px; +} +.offset11 { + margin-left: 900px; +} +.offset10 { + margin-left: 820px; +} +.offset9 { + margin-left: 740px; +} +.offset8 { + margin-left: 660px; +} +.offset7 { + margin-left: 580px; +} +.offset6 { + margin-left: 500px; +} +.offset5 { + margin-left: 420px; +} +.offset4 { + margin-left: 340px; +} +.offset3 { + margin-left: 260px; +} +.offset2 { + margin-left: 180px; +} +.offset1 { + margin-left: 100px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; +} +.row-fluid:after { + clear: both; +} +.row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.127659574%; + *margin-left: 2.0744680846382977%; +} +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid .span12 { + width: 99.99999998999999%; + *width: 99.94680850063828%; +} +.row-fluid .span11 { + width: 91.489361693%; + *width: 91.4361702036383%; +} +.row-fluid .span10 { + width: 82.97872339599999%; + *width: 82.92553190663828%; +} +.row-fluid .span9 { + width: 74.468085099%; + *width: 74.4148936096383%; +} +.row-fluid .span8 { + width: 65.95744680199999%; + *width: 65.90425531263828%; +} +.row-fluid .span7 { + width: 57.446808505%; + *width: 57.3936170156383%; +} +.row-fluid .span6 { + width: 48.93617020799999%; + *width: 48.88297871863829%; +} +.row-fluid .span5 { + width: 40.425531911%; + *width: 40.3723404216383%; +} +.row-fluid .span4 { + width: 31.914893614%; + *width: 31.8617021246383%; +} +.row-fluid .span3 { + width: 23.404255317%; + *width: 23.3510638276383%; +} +.row-fluid .span2 { + width: 14.89361702%; + *width: 14.8404255306383%; +} +.row-fluid .span1 { + width: 6.382978723%; + *width: 6.329787233638298%; +} +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; +} +.container:after { + clear: both; +} +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 9px; +} +p small { + font-size: 11px; + color: #999999; +} +.lead { + margin-bottom: 18px; + font-size: 20px; + font-weight: 200; + line-height: 27px; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + font-family: inherit; + font-weight: bold; + color: inherit; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + color: #999999; +} +h1 { + font-size: 30px; + line-height: 36px; +} +h1 small { + font-size: 18px; +} +h2 { + font-size: 24px; + line-height: 36px; +} +h2 small { + font-size: 18px; +} +h3 { + font-size: 18px; + line-height: 27px; +} +h3 small { + font-size: 14px; +} +h4, +h5, +h6 { + line-height: 18px; +} +h4 { + font-size: 14px; +} +h4 small { + font-size: 12px; +} +h5 { + font-size: 12px; +} +h6 { + font-size: 11px; + color: #999999; + text-transform: uppercase; +} +.page-header { + padding-bottom: 17px; + margin: 18px 0; + border-bottom: 1px solid #eeeeee; +} +.page-header h1 { + line-height: 1; +} +ul, +ol { + padding: 0; + margin: 0 0 9px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: 18px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +dl { + margin-bottom: 18px; +} +dt, +dd { + line-height: 18px; +} +dt { + font-weight: bold; + line-height: 17px; +} +dd { + margin-left: 9px; +} +.dl-horizontal dt { + float: left; + width: 120px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 130px; +} +hr { + margin: 18px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +.muted { + color: #999999; +} +abbr[title] { + cursor: help; + border-bottom: 1px dotted #999999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 18px; + border-left: 5px solid #eeeeee; +} +blockquote p { + margin-bottom: 0; + font-size: 16px; + font-weight: 300; + line-height: 22.5px; +} +blockquote small { + display: block; + line-height: 18px; + color: #999999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 18px; + font-style: normal; + line-height: 18px; +} +small { + font-size: 100%; +} +cite { + font-style: normal; +} +code, +pre { + padding: 0 3px 2px; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 9px; + font-size: 12.025px; + line-height: 18px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +pre.prettyprint { + margin-bottom: 18px; +} +pre code { + padding: 0; + color: inherit; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.label, +.badge { + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; +} +.label { + padding: 1px 4px 2px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding: 1px 9px 2px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +a.label:hover, +a.badge:hover { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #b94a48; +} +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #468847; +} +.label-success[href], +.badge-success[href] { + background-color: #356635; +} +.label-info, +.badge-info { + background-color: #3a87ad; +} +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 18px; +} +.table th, +.table td { + padding: 8px; + line-height: 18px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #dddddd; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapsed; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child th:first-child, +.table-bordered tbody:first-child tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} +.table-bordered thead:first-child tr:first-child th:last-child, +.table-bordered tbody:first-child tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} +.table-bordered thead:last-child tr:last-child th:first-child, +.table-bordered tbody:last-child tr:last-child td:first-child { + -webkit-border-radius: 0 0 0 4px; + -moz-border-radius: 0 0 0 4px; + border-radius: 0 0 0 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} +.table-bordered thead:last-child tr:last-child th:last-child, +.table-bordered tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} +.table-striped tbody tr:nth-child(odd) td, +.table-striped tbody tr:nth-child(odd) th { + background-color: #f9f9f9; +} +.table tbody tr:hover td, +.table tbody tr:hover th { + background-color: #f5f5f5; +} +table .span1 { + float: none; + width: 44px; + margin-left: 0; +} +table .span2 { + float: none; + width: 124px; + margin-left: 0; +} +table .span3 { + float: none; + width: 204px; + margin-left: 0; +} +table .span4 { + float: none; + width: 284px; + margin-left: 0; +} +table .span5 { + float: none; + width: 364px; + margin-left: 0; +} +table .span6 { + float: none; + width: 444px; + margin-left: 0; +} +table .span7 { + float: none; + width: 524px; + margin-left: 0; +} +table .span8 { + float: none; + width: 604px; + margin-left: 0; +} +table .span9 { + float: none; + width: 684px; + margin-left: 0; +} +table .span10 { + float: none; + width: 764px; + margin-left: 0; +} +table .span11 { + float: none; + width: 844px; + margin-left: 0; +} +table .span12 { + float: none; + width: 924px; + margin-left: 0; +} +table .span13 { + float: none; + width: 1004px; + margin-left: 0; +} +table .span14 { + float: none; + width: 1084px; + margin-left: 0; +} +table .span15 { + float: none; + width: 1164px; + margin-left: 0; +} +table .span16 { + float: none; + width: 1244px; + margin-left: 0; +} +table .span17 { + float: none; + width: 1324px; + margin-left: 0; +} +table .span18 { + float: none; + width: 1404px; + margin-left: 0; +} +table .span19 { + float: none; + width: 1484px; + margin-left: 0; +} +table .span20 { + float: none; + width: 1564px; + margin-left: 0; +} +table .span21 { + float: none; + width: 1644px; + margin-left: 0; +} +table .span22 { + float: none; + width: 1724px; + margin-left: 0; +} +table .span23 { + float: none; + width: 1804px; + margin-left: 0; +} +table .span24 { + float: none; + width: 1884px; + margin-left: 0; +} +form { + margin: 0 0 18px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 27px; + font-size: 19.5px; + line-height: 36px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 13.5px; + color: #999999; +} +label, +input, +button, +select, +textarea { + font-size: 13px; + font-weight: normal; + line-height: 18px; +} +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 18px; + padding: 4px; + margin-bottom: 9px; + font-size: 13px; + line-height: 18px; + color: #555555; +} +input, +textarea { + width: 210px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -ms-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); +} +input[type="radio"], +input[type="checkbox"] { + margin: 3px 0; + *margin-top: 0; + /* IE7 */ + + line-height: normal; + cursor: pointer; +} +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +.uneditable-textarea { + width: auto; + height: auto; +} +select, +input[type="file"] { + height: 28px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 28px; +} +select { + width: 220px; + border: 1px solid #bbb; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.radio, +.checkbox { + min-height: 18px; + padding-left: 18px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -18px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +input.span12, textarea.span12, .uneditable-input.span12 { + width: 930px; +} +input.span11, textarea.span11, .uneditable-input.span11 { + width: 850px; +} +input.span10, textarea.span10, .uneditable-input.span10 { + width: 770px; +} +input.span9, textarea.span9, .uneditable-input.span9 { + width: 690px; +} +input.span8, textarea.span8, .uneditable-input.span8 { + width: 610px; +} +input.span7, textarea.span7, .uneditable-input.span7 { + width: 530px; +} +input.span6, textarea.span6, .uneditable-input.span6 { + width: 450px; +} +input.span5, textarea.span5, .uneditable-input.span5 { + width: 370px; +} +input.span4, textarea.span4, .uneditable-input.span4 { + width: 290px; +} +input.span3, textarea.span3, .uneditable-input.span3 { + width: 210px; +} +input.span2, textarea.span2, .uneditable-input.span2 { + width: 130px; +} +input.span1, textarea.span1, .uneditable-input.span1 { + width: 50px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; + border-color: #ddd; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning > label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; + border-color: #c09853; +} +.control-group.warning .checkbox:focus, +.control-group.warning .radio:focus, +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: 0 0 6px #dbc59e; + -moz-box-shadow: 0 0 6px #dbc59e; + box-shadow: 0 0 6px #dbc59e; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} +.control-group.error > label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; + border-color: #b94a48; +} +.control-group.error .checkbox:focus, +.control-group.error .radio:focus, +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: 0 0 6px #d59392; + -moz-box-shadow: 0 0 6px #d59392; + box-shadow: 0 0 6px #d59392; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} +.control-group.success > label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; + border-color: #468847; +} +.control-group.success .checkbox:focus, +.control-group.success .radio:focus, +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: 0 0 6px #7aba7b; + -moz-box-shadow: 0 0 6px #7aba7b; + box-shadow: 0 0 6px #7aba7b; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} +input:focus:required:invalid, +textarea:focus:required:invalid, +select:focus:required:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:required:invalid:focus, +textarea:focus:required:invalid:focus, +select:focus:required:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +.form-actions { + padding: 17px 20px 18px; + margin-top: 18px; + margin-bottom: 18px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; +} +.form-actions:after { + clear: both; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; + cursor: not-allowed; + background-color: #ffffff; + border-color: #eee; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} +:-moz-placeholder { + color: #999999; +} +:-ms-input-placeholder { + color: #999999; +} +::-webkit-input-placeholder { + color: #999999; +} +.help-block, +.help-inline { + color: #555555; +} +.help-block { + display: block; + margin-bottom: 9px; +} +.help-inline { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-prepend, +.input-append { + margin-bottom: 5px; +} +.input-prepend input, +.input-append input, +.input-prepend select, +.input-append select, +.input-prepend .uneditable-input, +.input-append .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: middle; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend input:focus, +.input-append input:focus, +.input-prepend select:focus, +.input-append select:focus, +.input-prepend .uneditable-input:focus, +.input-append .uneditable-input:focus { + z-index: 2; +} +.input-prepend .uneditable-input, +.input-append .uneditable-input { + border-left-color: #ccc; +} +.input-prepend .add-on, +.input-append .add-on { + display: inline-block; + width: auto; + height: 18px; + min-width: 16px; + padding: 4px 5px; + font-weight: normal; + line-height: 18px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + vertical-align: middle; + background-color: #eeeeee; + border: 1px solid #ccc; +} +.input-prepend .add-on, +.input-append .add-on, +.input-prepend .btn, +.input-append .btn { + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend .active, +.input-append .active { + background-color: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .uneditable-input { + border-right-color: #ccc; + border-left-color: #eee; +} +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 14px; + -moz-border-radius: 14px; + border-radius: 14px; +} +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-bottom: 0; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 9px; +} +legend + .control-group { + margin-top: 18px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 18px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 140px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 160px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 160px; +} +.form-horizontal .help-block { + margin-top: 9px; + margin-bottom: 0; +} +.form-horizontal .form-actions { + padding-left: 160px; +} +.btn { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + padding: 4px 10px 4px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + *line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(top, #ffffff, #e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e6e6e6; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #cccccc; + *border: 0; + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +.btn:active, +.btn.active { + background-color: #cccccc \9; +} +.btn:first-child { + *margin-left: 0; +} +.btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + /* Buttons in IE7 don't get borders, so darken on hover */ + + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -ms-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-color: #e6e6e6; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-large [class^="icon-"] { + margin-top: 1px; +} +.btn-small { + padding: 5px 9px; + font-size: 11px; + line-height: 16px; +} +.btn-small [class^="icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 2px 6px; + font-size: 11px; + line-height: 14px; +} +.btn-primary, +.btn-primary:hover, +.btn-warning, +.btn-warning:hover, +.btn-danger, +.btn-danger:hover, +.btn-success, +.btn-success:hover, +.btn-info, +.btn-info:hover, +.btn-inverse, +.btn-inverse:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} +.btn { + border-color: #ccc; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn-primary { + background-color: #0074cc; + background-image: -moz-linear-gradient(top, #0088cc, #0055cc); + background-image: -ms-linear-gradient(top, #0088cc, #0055cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0055cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0055cc); + background-image: -o-linear-gradient(top, #0088cc, #0055cc); + background-image: linear-gradient(top, #0088cc, #0055cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0055cc', GradientType=0); + border-color: #0055cc #0055cc #003580; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #0055cc; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + background-color: #0055cc; + *background-color: #004ab3; +} +.btn-primary:active, +.btn-primary.active { + background-color: #004099 \9; +} +.btn-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -ms-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(top, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0); + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #f89406; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + background-color: #f89406; + *background-color: #df8505; +} +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} +.btn-danger { + background-color: #da4f49; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -ms-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(top, #ee5f5b, #bd362f); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0); + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #bd362f; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + background-color: #bd362f; + *background-color: #a9302a; +} +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} +.btn-success { + background-color: #5bb75b; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -ms-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(top, #62c462, #51a351); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0); + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #51a351; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + background-color: #51a351; + *background-color: #499249; +} +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} +.btn-info { + background-color: #49afcd; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -ms-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(top, #5bc0de, #2f96b4); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0); + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #2f96b4; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + background-color: #2f96b4; + *background-color: #2a85a0; +} +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} +.btn-inverse { + background-color: #414141; + background-image: -moz-linear-gradient(top, #555555, #222222); + background-image: -ms-linear-gradient(top, #555555, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222)); + background-image: -webkit-linear-gradient(top, #555555, #222222); + background-image: -o-linear-gradient(top, #555555, #222222); + background-image: linear-gradient(top, #555555, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#222222', GradientType=0); + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #222222; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + background-color: #222222; + *background-color: #151515; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} +button.btn, +input[type="submit"].btn { + *padding-top: 2px; + *padding-bottom: 2px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} +[class^="icon-"]:last-child, +[class*=" icon-"]:last-child { + *margin-left: 0; +} +.icon-white { + background-image: url("../img/glyphicons-halflings-white.png"); +} +.icon-glass { + background-position: 0 0; +} +.icon-music { + background-position: -24px 0; +} +.icon-search { + background-position: -48px 0; +} +.icon-envelope { + background-position: -72px 0; +} +.icon-heart { + background-position: -96px 0; +} +.icon-star { + background-position: -120px 0; +} +.icon-star-empty { + background-position: -144px 0; +} +.icon-user { + background-position: -168px 0; +} +.icon-film { + background-position: -192px 0; +} +.icon-th-large { + background-position: -216px 0; +} +.icon-th { + background-position: -240px 0; +} +.icon-th-list { + background-position: -264px 0; +} +.icon-ok { + background-position: -288px 0; +} +.icon-remove { + background-position: -312px 0; +} +.icon-zoom-in { + background-position: -336px 0; +} +.icon-zoom-out { + background-position: -360px 0; +} +.icon-off { + background-position: -384px 0; +} +.icon-signal { + background-position: -408px 0; +} +.icon-cog { + background-position: -432px 0; +} +.icon-trash { + background-position: -456px 0; +} +.icon-home { + background-position: 0 -24px; +} +.icon-file { + background-position: -24px -24px; +} +.icon-time { + background-position: -48px -24px; +} +.icon-road { + background-position: -72px -24px; +} +.icon-download-alt { + background-position: -96px -24px; +} +.icon-download { + background-position: -120px -24px; +} +.icon-upload { + background-position: -144px -24px; +} +.icon-inbox { + background-position: -168px -24px; +} +.icon-play-circle { + background-position: -192px -24px; +} +.icon-repeat { + background-position: -216px -24px; +} +.icon-refresh { + background-position: -240px -24px; +} +.icon-list-alt { + background-position: -264px -24px; +} +.icon-lock { + background-position: -287px -24px; +} +.icon-flag { + background-position: -312px -24px; +} +.icon-headphones { + background-position: -336px -24px; +} +.icon-volume-off { + background-position: -360px -24px; +} +.icon-volume-down { + background-position: -384px -24px; +} +.icon-volume-up { + background-position: -408px -24px; +} +.icon-qrcode { + background-position: -432px -24px; +} +.icon-barcode { + background-position: -456px -24px; +} +.icon-tag { + background-position: 0 -48px; +} +.icon-tags { + background-position: -25px -48px; +} +.icon-book { + background-position: -48px -48px; +} +.icon-bookmark { + background-position: -72px -48px; +} +.icon-print { + background-position: -96px -48px; +} +.icon-camera { + background-position: -120px -48px; +} +.icon-font { + background-position: -144px -48px; +} +.icon-bold { + background-position: -167px -48px; +} +.icon-italic { + background-position: -192px -48px; +} +.icon-text-height { + background-position: -216px -48px; +} +.icon-text-width { + background-position: -240px -48px; +} +.icon-align-left { + background-position: -264px -48px; +} +.icon-align-center { + background-position: -288px -48px; +} +.icon-align-right { + background-position: -312px -48px; +} +.icon-align-justify { + background-position: -336px -48px; +} +.icon-list { + background-position: -360px -48px; +} +.icon-indent-left { + background-position: -384px -48px; +} +.icon-indent-right { + background-position: -408px -48px; +} +.icon-facetime-video { + background-position: -432px -48px; +} +.icon-picture { + background-position: -456px -48px; +} +.icon-pencil { + background-position: 0 -72px; +} +.icon-map-marker { + background-position: -24px -72px; +} +.icon-adjust { + background-position: -48px -72px; +} +.icon-tint { + background-position: -72px -72px; +} +.icon-edit { + background-position: -96px -72px; +} +.icon-share { + background-position: -120px -72px; +} +.icon-check { + background-position: -144px -72px; +} +.icon-move { + background-position: -168px -72px; +} +.icon-step-backward { + background-position: -192px -72px; +} +.icon-fast-backward { + background-position: -216px -72px; +} +.icon-backward { + background-position: -240px -72px; +} +.icon-play { + background-position: -264px -72px; +} +.icon-pause { + background-position: -288px -72px; +} +.icon-stop { + background-position: -312px -72px; +} +.icon-forward { + background-position: -336px -72px; +} +.icon-fast-forward { + background-position: -360px -72px; +} +.icon-step-forward { + background-position: -384px -72px; +} +.icon-eject { + background-position: -408px -72px; +} +.icon-chevron-left { + background-position: -432px -72px; +} +.icon-chevron-right { + background-position: -456px -72px; +} +.icon-plus-sign { + background-position: 0 -96px; +} +.icon-minus-sign { + background-position: -24px -96px; +} +.icon-remove-sign { + background-position: -48px -96px; +} +.icon-ok-sign { + background-position: -72px -96px; +} +.icon-question-sign { + background-position: -96px -96px; +} +.icon-info-sign { + background-position: -120px -96px; +} +.icon-screenshot { + background-position: -144px -96px; +} +.icon-remove-circle { + background-position: -168px -96px; +} +.icon-ok-circle { + background-position: -192px -96px; +} +.icon-ban-circle { + background-position: -216px -96px; +} +.icon-arrow-left { + background-position: -240px -96px; +} +.icon-arrow-right { + background-position: -264px -96px; +} +.icon-arrow-up { + background-position: -289px -96px; +} +.icon-arrow-down { + background-position: -312px -96px; +} +.icon-share-alt { + background-position: -336px -96px; +} +.icon-resize-full { + background-position: -360px -96px; +} +.icon-resize-small { + background-position: -384px -96px; +} +.icon-plus { + background-position: -408px -96px; +} +.icon-minus { + background-position: -433px -96px; +} +.icon-asterisk { + background-position: -456px -96px; +} +.icon-exclamation-sign { + background-position: 0 -120px; +} +.icon-gift { + background-position: -24px -120px; +} +.icon-leaf { + background-position: -48px -120px; +} +.icon-fire { + background-position: -72px -120px; +} +.icon-eye-open { + background-position: -96px -120px; +} +.icon-eye-close { + background-position: -120px -120px; +} +.icon-warning-sign { + background-position: -144px -120px; +} +.icon-plane { + background-position: -168px -120px; +} +.icon-calendar { + background-position: -192px -120px; +} +.icon-random { + background-position: -216px -120px; +} +.icon-comment { + background-position: -240px -120px; +} +.icon-magnet { + background-position: -264px -120px; +} +.icon-chevron-up { + background-position: -288px -120px; +} +.icon-chevron-down { + background-position: -313px -119px; +} +.icon-retweet { + background-position: -336px -120px; +} +.icon-shopping-cart { + background-position: -360px -120px; +} +.icon-folder-close { + background-position: -384px -120px; +} +.icon-folder-open { + background-position: -408px -120px; +} +.icon-resize-vertical { + background-position: -432px -119px; +} +.icon-resize-horizontal { + background-position: -456px -118px; +} +.icon-hdd { + background-position: 0 -144px; +} +.icon-bullhorn { + background-position: -24px -144px; +} +.icon-bell { + background-position: -48px -144px; +} +.icon-certificate { + background-position: -72px -144px; +} +.icon-thumbs-up { + background-position: -96px -144px; +} +.icon-thumbs-down { + background-position: -120px -144px; +} +.icon-hand-right { + background-position: -144px -144px; +} +.icon-hand-left { + background-position: -168px -144px; +} +.icon-hand-up { + background-position: -192px -144px; +} +.icon-hand-down { + background-position: -216px -144px; +} +.icon-circle-arrow-right { + background-position: -240px -144px; +} +.icon-circle-arrow-left { + background-position: -264px -144px; +} +.icon-circle-arrow-up { + background-position: -288px -144px; +} +.icon-circle-arrow-down { + background-position: -312px -144px; +} +.icon-globe { + background-position: -336px -144px; +} +.icon-wrench { + background-position: -360px -144px; +} +.icon-tasks { + background-position: -384px -144px; +} +.icon-filter { + background-position: -408px -144px; +} +.icon-briefcase { + background-position: -432px -144px; +} +.icon-fullscreen { + background-position: -456px -144px; +} +.btn-group { + position: relative; + *zoom: 1; + *margin-left: .3em; +} +.btn-group:before, +.btn-group:after { + display: table; + content: ""; +} +.btn-group:after { + clear: both; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + margin-top: 9px; + margin-bottom: 9px; +} +.btn-toolbar .btn-group { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} +.btn-group > .btn { + position: relative; + float: left; + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 4px; + *padding-bottom: 4px; +} +.btn-group > .btn-mini.dropdown-toggle { + padding-left: 5px; + padding-right: 5px; +} +.btn-group > .btn-small.dropdown-toggle { + *padding-top: 4px; + *padding-bottom: 4px; +} +.btn-group > .btn-large.dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0055cc; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} +.btn .caret { + margin-top: 7px; + margin-left: 0; +} +.btn:hover .caret, +.open.btn-group .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.btn-mini .caret { + margin-top: 5px; +} +.btn-small .caret { + margin-top: 6px; +} +.btn-large .caret { + margin-top: 6px; + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.dropup .btn-large .caret { + border-bottom: 5px solid #000000; + border-top: 0; +} +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 0.75; + filter: alpha(opacity=75); +} +.nav { + margin-left: 0; + margin-bottom: 18px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover { + text-decoration: none; + background-color: #eeeeee; +} +.nav > .pull-right { + float: right; +} +.nav .nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 18px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} +.nav-list [class^="icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + content: ""; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover { + color: #555555; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover { + color: #ffffff; + background-color: #0088cc; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.nav-tabs.nav-stacked > li > a:hover { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.nav-tabs .dropdown-toggle .caret, +.nav-pills .dropdown-toggle .caret { + border-top-color: #0088cc; + border-bottom-color: #0088cc; + margin-top: 6px; +} +.nav-tabs .dropdown-toggle:hover .caret, +.nav-pills .dropdown-toggle:hover .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} +.nav-tabs .active .dropdown-toggle .caret, +.nav-pills .active .dropdown-toggle .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} +.nav > .dropdown.active > a:hover { + color: #000000; + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover { + border-color: #999999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below > .nav-tabs > li > a:hover { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left > .nav-tabs > li > a:hover { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right > .nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} +.navbar { + *position: relative; + *z-index: 2; + overflow: visible; + margin-bottom: 18px; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #2c2c2c; + background-image: -moz-linear-gradient(top, #333333, #222222); + background-image: -ms-linear-gradient(top, #333333, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222)); + background-image: -webkit-linear-gradient(top, #333333, #222222); + background-image: -o-linear-gradient(top, #333333, #222222); + background-image: linear-gradient(top, #333333, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; +} +.navbar { + color: #999999; +} +.navbar .brand:hover { + text-decoration: none; +} +.navbar .brand { + float: left; + display: block; + padding: 8px 20px 12px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + line-height: 1; + color: #999999; +} +.navbar .navbar-text { + margin-bottom: 0; + line-height: 40px; +} +.navbar .navbar-link { + color: #999999; +} +.navbar .navbar-link:hover { + color: #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn { + margin: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 6px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 6px; + margin-bottom: 0; +} +.navbar-search .search-query { + padding: 4px 9px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + color: #ffffff; + background-color: #626262; + border: 1px solid #151515; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; +} +.navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} +.navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} +.navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} +.navbar-search .search-query:focus, +.navbar-search .search-query.focused { + padding: 5px 10px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + outline: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; +} +.navbar .nav > li { + display: block; + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 9px 10px 11px; + line-height: 19px; + color: #999999; + text-decoration: none; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.navbar .btn { + display: inline-block; + padding: 4px 10px 4px; + margin: 5px 5px 6px; + line-height: 18px; +} +.navbar .btn-group { + margin: 0; + padding: 5px 5px 6px; +} +.navbar .nav > li > a:hover { + background-color: transparent; + color: #ffffff; + text-decoration: none; +} +.navbar .nav .active > a, +.navbar .nav .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: #222222; +} +.navbar .divider-vertical { + height: 40px; + width: 1px; + margin: 0 9px; + overflow: hidden; + background-color: #222222; + border-right: 1px solid #333333; +} +.navbar .nav.pull-right { + margin-left: 10px; + margin-right: 0; +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + background-color: #2c2c2c; + background-image: -moz-linear-gradient(top, #333333, #222222); + background-image: -ms-linear-gradient(top, #333333, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222)); + background-image: -webkit-linear-gradient(top, #333333, #222222); + background-image: -o-linear-gradient(top, #333333, #222222); + background-image: linear-gradient(top, #333333, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #222222; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + background-color: #222222; + *background-color: #151515; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #080808 \9; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .dropdown-menu:after { + border-top: 6px solid #ffffff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown .dropdown-toggle .caret, +.navbar .nav li.dropdown.open .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar .nav li.dropdown.active .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: transparent; +} +.navbar .nav li.dropdown.active > .dropdown-toggle:hover { + color: #ffffff; +} +.navbar .pull-right .dropdown-menu, +.navbar .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right .dropdown-menu:before, +.navbar .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right .dropdown-menu:after, +.navbar .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.breadcrumb { + padding: 7px 14px; + margin: 0 0 18px; + list-style: none; + background-color: #fbfbfb; + background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5)); + background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -o-linear-gradient(top, #ffffff, #f5f5f5); + background-image: linear-gradient(top, #ffffff, #f5f5f5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0); + border: 1px solid #ddd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} +.breadcrumb li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + text-shadow: 0 1px 0 #ffffff; +} +.breadcrumb .divider { + padding: 0 5px; + color: #999999; +} +.breadcrumb .active a { + color: #333333; +} +.pagination { + height: 36px; + margin: 18px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.pagination li { + display: inline; +} +.pagination a { + float: left; + padding: 0 14px; + line-height: 34px; + text-decoration: none; + border: 1px solid #ddd; + border-left-width: 0; +} +.pagination a:hover, +.pagination .active a { + background-color: #f5f5f5; +} +.pagination .active a { + color: #999999; + cursor: default; +} +.pagination .disabled span, +.pagination .disabled a, +.pagination .disabled a:hover { + color: #999999; + background-color: transparent; + cursor: default; +} +.pagination li:first-child a { + border-left-width: 1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.pagination li:last-child a { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pager { + margin-left: 0; + margin-bottom: 18px; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager a { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next a { + float: right; +} +.pager .previous a { + float: left; +} +.pager .disabled a, +.pager .disabled a:hover { + color: #999999; + background-color: #fff; + cursor: default; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 18px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 1; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); +} +a.thumbnail:hover { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + color: #c09853; +} +.alert-heading { + color: inherit; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #468847; +} +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #eed3d7; + color: #b94a48; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #3a87ad; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 18px; + margin-bottom: 18px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -ms-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(top, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.progress .bar { + width: 0%; + height: 18px; + color: #ffffff; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -ms-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(top, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -ms-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(top, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); +} +.progress-danger.progress-striped .bar { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-success .bar { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -ms-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(top, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); +} +.progress-success.progress-striped .bar { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-info .bar { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(top, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); +} +.progress-info.progress-striped .bar { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-warning .bar { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -ms-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(top, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0); +} +.progress-warning.progress-striped .bar { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit p { + font-size: 18px; + font-weight: 200; + line-height: 27px; + color: inherit; +} +.tooltip { + position: absolute; + z-index: 1020; + display: block; + visibility: visible; + padding: 5px; + font-size: 11px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -2px; +} +.tooltip.right { + margin-left: 2px; +} +.tooltip.bottom { + margin-top: 2px; +} +.tooltip.left { + margin-left: -2px; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + padding: 5px; +} +.popover.top { + margin-top: -5px; +} +.popover.right { + margin-left: 5px; +} +.popover.bottom { + margin-top: 5px; +} +.popover.left { + margin-left: -5px; +} +.popover.top .arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.popover.right .arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.popover.bottom .arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.popover.left .arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.popover .arrow { + position: absolute; + width: 0; + height: 0; +} +.popover-inner { + padding: 3px; + width: 280px; + overflow: hidden; + background: #000000; + background: rgba(0, 0, 0, 0.8); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); +} +.popover-title { + padding: 9px 15px; + line-height: 1; + background-color: #f5f5f5; + border-bottom: 1px solid #eee; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.popover-content { + padding: 14px; + background-color: #ffffff; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.popover-content p, +.popover-content ul, +.popover-content ol { + margin-bottom: 0; +} +.modal-open .dropdown-menu { + z-index: 2050; +} +.modal-open .dropdown.open { + *z-index: 2050; +} +.modal-open .popover { + z-index: 2060; +} +.modal-open .tooltip { + z-index: 2070; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal { + position: fixed; + top: 50%; + left: 50%; + z-index: 1050; + overflow: auto; + width: 560px; + margin: -250px 0 0 -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + /* IE6-7 */ + + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -ms-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +.modal.fade.in { + top: 50%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-body { + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; + opacity: 0.3; + filter: alpha(opacity=30); +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown:hover .caret, +.open .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 4px 0; + margin: 1px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.dropdown-menu a { + display: block; + padding: 3px 15px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #333333; + white-space: nowrap; +} +.dropdown-menu li > a:hover, +.dropdown-menu .active > a, +.dropdown-menu .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: #0088cc; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: "\2191"; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.typeahead { + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion { + margin-bottom: 18px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 18px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -ms-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel .item > img { + display: block; + line-height: 1; +} +.carousel .active, +.carousel .next, +.carousel .prev { + display: block; +} +.carousel .active { + left: 0; +} +.carousel .next, +.carousel .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel .next { + left: 100%; +} +.carousel .prev { + left: -100%; +} +.carousel .next.left, +.carousel .prev.right { + left: 0; +} +.carousel .active.left { + left: -100%; +} +.carousel .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 10px 15px 5px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #eee; + border: 1px solid rgba(0, 0, 0, 0.05); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -ms-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -ms-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.collapse.in { + height: auto; +} +.hidden { + display: none; + visibility: hidden; +} +.visible-phone { + display: none !important; +} +.visible-tablet { + display: none !important; +} +.hidden-desktop { + display: none !important; +} +@media (max-width: 767px) { + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 979px) { + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } +} +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 18px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-group > label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-left: 10px; + padding-right: 10px; + } + .modal { + position: absolute; + top: 10px; + left: 10px; + right: 10px; + width: auto; + margin: 0; + } + .modal.fade.in { + top: auto; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} +@media (max-width: 767px) { + body { + padding-left: 20px; + padding-right: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + margin-left: -20px; + margin-right: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + clear: none; + width: auto; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + [class*="span"], + .row-fluid [class*="span"] { + float: none; + display: block; + width: auto; + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } +} +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + margin-left: 20px; + } + .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.762430939%; + *margin-left: 2.709239449638298%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .span12 { + width: 99.999999993%; + *width: 99.9468085036383%; + } + .row-fluid .span11 { + width: 91.436464082%; + *width: 91.38327259263829%; + } + .row-fluid .span10 { + width: 82.87292817100001%; + *width: 82.8197366816383%; + } + .row-fluid .span9 { + width: 74.30939226%; + *width: 74.25620077063829%; + } + .row-fluid .span8 { + width: 65.74585634900001%; + *width: 65.6926648596383%; + } + .row-fluid .span7 { + width: 57.182320438000005%; + *width: 57.129128948638304%; + } + .row-fluid .span6 { + width: 48.618784527%; + *width: 48.5655930376383%; + } + .row-fluid .span5 { + width: 40.055248616%; + *width: 40.0020571266383%; + } + .row-fluid .span4 { + width: 31.491712705%; + *width: 31.4385212156383%; + } + .row-fluid .span3 { + width: 22.928176794%; + *width: 22.874985304638297%; + } + .row-fluid .span2 { + width: 14.364640883%; + *width: 14.311449393638298%; + } + .row-fluid .span1 { + width: 5.801104972%; + *width: 5.747913482638298%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + input.span12, textarea.span12, .uneditable-input.span12 { + width: 714px; + } + input.span11, textarea.span11, .uneditable-input.span11 { + width: 652px; + } + input.span10, textarea.span10, .uneditable-input.span10 { + width: 590px; + } + input.span9, textarea.span9, .uneditable-input.span9 { + width: 528px; + } + input.span8, textarea.span8, .uneditable-input.span8 { + width: 466px; + } + input.span7, textarea.span7, .uneditable-input.span7 { + width: 404px; + } + input.span6, textarea.span6, .uneditable-input.span6 { + width: 342px; + } + input.span5, textarea.span5, .uneditable-input.span5 { + width: 280px; + } + input.span4, textarea.span4, .uneditable-input.span4 { + width: 218px; + } + input.span3, textarea.span3, .uneditable-input.span3 { + width: 156px; + } + input.span2, textarea.span2, .uneditable-input.span2 { + width: 94px; + } + input.span1, textarea.span1, .uneditable-input.span1 { + width: 32px; + } +} +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + margin-left: 30px; + } + .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.564102564%; + *margin-left: 2.510911074638298%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145300001%; + *width: 91.3997999636383%; + } + .row-fluid .span10 { + width: 82.905982906%; + *width: 82.8527914166383%; + } + .row-fluid .span9 { + width: 74.358974359%; + *width: 74.30578286963829%; + } + .row-fluid .span8 { + width: 65.81196581200001%; + *width: 65.7587743226383%; + } + .row-fluid .span7 { + width: 57.264957265%; + *width: 57.2117657756383%; + } + .row-fluid .span6 { + width: 48.717948718%; + *width: 48.6647572286383%; + } + .row-fluid .span5 { + width: 40.170940171000005%; + *width: 40.117748681638304%; + } + .row-fluid .span4 { + width: 31.623931624%; + *width: 31.5707401346383%; + } + .row-fluid .span3 { + width: 23.076923077%; + *width: 23.0237315876383%; + } + .row-fluid .span2 { + width: 14.529914530000001%; + *width: 14.4767230406383%; + } + .row-fluid .span1 { + width: 5.982905983%; + *width: 5.929714493638298%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + input.span12, textarea.span12, .uneditable-input.span12 { + width: 1160px; + } + input.span11, textarea.span11, .uneditable-input.span11 { + width: 1060px; + } + input.span10, textarea.span10, .uneditable-input.span10 { + width: 960px; + } + input.span9, textarea.span9, .uneditable-input.span9 { + width: 860px; + } + input.span8, textarea.span8, .uneditable-input.span8 { + width: 760px; + } + input.span7, textarea.span7, .uneditable-input.span7 { + width: 660px; + } + input.span6, textarea.span6, .uneditable-input.span6 { + width: 560px; + } + input.span5, textarea.span5, .uneditable-input.span5 { + width: 460px; + } + input.span4, textarea.span4, .uneditable-input.span4 { + width: 360px; + } + input.span3, textarea.span3, .uneditable-input.span3 { + width: 260px; + } + input.span2, textarea.span2, .uneditable-input.span2 { + width: 160px; + } + input.span1, textarea.span1, .uneditable-input.span1 { + width: 60px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 18px; + } + .navbar-fixed-bottom { + margin-top: 18px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-left: 10px; + padding-right: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 9px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #999999; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 6px 15px; + font-weight: bold; + color: #999999; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .dropdown-menu a:hover { + background-color: #222222; + } + .nav-collapse.in .btn-group { + margin-top: 5px; + padding: 0; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + float: none; + display: block; + max-width: none; + margin: 0 15px; + padding: 0; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 9px 15px; + margin: 9px 0; + border-top: 1px solid #222222; + border-bottom: 1px solid #222222; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + -moz-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); + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + overflow: hidden; + height: 0; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-left: 10px; + padding-right: 10px; + } +} +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/samples/scala/play-authenticate-usage/public/css/bootstrap.min.css b/samples/scala/play-authenticate-usage/public/css/bootstrap.min.css new file mode 100644 index 00000000..f0b9523c --- /dev/null +++ b/samples/scala/play-authenticate-usage/public/css/bootstrap.min.css @@ -0,0 +1,727 @@ +/*! + * Bootstrap v2.0.4 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";} +.clearfix:after{clear:both;} +.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;} +.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} +article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;} +audio,canvas,video{display:inline-block;*display:inline;*zoom:1;} +audio:not([controls]){display:none;} +html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;} +a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +a:hover,a:active{outline:0;} +sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;} +sup{top:-0.5em;} +sub{bottom:-0.25em;} +img{max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic;} +#map_canvas img{max-width:none;} +button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;} +button,input{*overflow:visible;line-height:normal;} +button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;} +button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;} +input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield;} +input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;} +textarea{overflow:auto;vertical-align:top;} +body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333333;background-color:#ffffff;} +a{color:#0088cc;text-decoration:none;} +a:hover{color:#005580;text-decoration:underline;} +.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} +.row:after{clear:both;} +[class*="span"]{float:left;margin-left:20px;} +.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.span12{width:940px;} +.span11{width:860px;} +.span10{width:780px;} +.span9{width:700px;} +.span8{width:620px;} +.span7{width:540px;} +.span6{width:460px;} +.span5{width:380px;} +.span4{width:300px;} +.span3{width:220px;} +.span2{width:140px;} +.span1{width:60px;} +.offset12{margin-left:980px;} +.offset11{margin-left:900px;} +.offset10{margin-left:820px;} +.offset9{margin-left:740px;} +.offset8{margin-left:660px;} +.offset7{margin-left:580px;} +.offset6{margin-left:500px;} +.offset5{margin-left:420px;} +.offset4{margin-left:340px;} +.offset3{margin-left:260px;} +.offset2{margin-left:180px;} +.offset1{margin-left:100px;} +.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} +.row-fluid:after{clear:both;} +.row-fluid [class*="span"]{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574%;*margin-left:2.0744680846382977%;} +.row-fluid [class*="span"]:first-child{margin-left:0;} +.row-fluid .span12{width:99.99999998999999%;*width:99.94680850063828%;} +.row-fluid .span11{width:91.489361693%;*width:91.4361702036383%;} +.row-fluid .span10{width:82.97872339599999%;*width:82.92553190663828%;} +.row-fluid .span9{width:74.468085099%;*width:74.4148936096383%;} +.row-fluid .span8{width:65.95744680199999%;*width:65.90425531263828%;} +.row-fluid .span7{width:57.446808505%;*width:57.3936170156383%;} +.row-fluid .span6{width:48.93617020799999%;*width:48.88297871863829%;} +.row-fluid .span5{width:40.425531911%;*width:40.3723404216383%;} +.row-fluid .span4{width:31.914893614%;*width:31.8617021246383%;} +.row-fluid .span3{width:23.404255317%;*width:23.3510638276383%;} +.row-fluid .span2{width:14.89361702%;*width:14.8404255306383%;} +.row-fluid .span1{width:6.382978723%;*width:6.329787233638298%;} +.container{margin-right:auto;margin-left:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";} +.container:after{clear:both;} +.container-fluid{padding-right:20px;padding-left:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";} +.container-fluid:after{clear:both;} +p{margin:0 0 9px;}p small{font-size:11px;color:#999999;} +.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px;} +h1,h2,h3,h4,h5,h6{margin:0;font-family:inherit;font-weight:bold;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999999;} +h1{font-size:30px;line-height:36px;}h1 small{font-size:18px;} +h2{font-size:24px;line-height:36px;}h2 small{font-size:18px;} +h3{font-size:18px;line-height:27px;}h3 small{font-size:14px;} +h4,h5,h6{line-height:18px;} +h4{font-size:14px;}h4 small{font-size:12px;} +h5{font-size:12px;} +h6{font-size:11px;color:#999999;text-transform:uppercase;} +.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eeeeee;} +.page-header h1{line-height:1;} +ul,ol{padding:0;margin:0 0 9px 25px;} +ul ul,ul ol,ol ol,ol ul{margin-bottom:0;} +ul{list-style:disc;} +ol{list-style:decimal;} +li{line-height:18px;} +ul.unstyled,ol.unstyled{margin-left:0;list-style:none;} +dl{margin-bottom:18px;} +dt,dd{line-height:18px;} +dt{font-weight:bold;line-height:17px;} +dd{margin-left:9px;} +.dl-horizontal dt{float:left;width:120px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;} +.dl-horizontal dd{margin-left:130px;} +hr{margin:18px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;} +strong{font-weight:bold;} +em{font-style:italic;} +.muted{color:#999999;} +abbr[title]{cursor:help;border-bottom:1px dotted #999999;} +abbr.initialism{font-size:90%;text-transform:uppercase;} +blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px;} +blockquote small{display:block;line-height:18px;color:#999999;}blockquote small:before{content:'\2014 \00A0';} +blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;} +q:before,q:after,blockquote:before,blockquote:after{content:"";} +address{display:block;margin-bottom:18px;font-style:normal;line-height:18px;} +small{font-size:100%;} +cite{font-style:normal;} +code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:12px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;} +pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12.025px;line-height:18px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}pre.prettyprint{margin-bottom:18px;} +pre code{padding:0;color:inherit;background-color:transparent;border:0;} +.pre-scrollable{max-height:340px;overflow-y:scroll;} +.label,.badge{font-size:10.998px;font-weight:bold;line-height:14px;color:#ffffff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;} +.label{padding:1px 4px 2px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.badge{padding:1px 9px 2px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;} +a.label:hover,a.badge:hover{color:#ffffff;text-decoration:none;cursor:pointer;} +.label-important,.badge-important{background-color:#b94a48;} +.label-important[href],.badge-important[href]{background-color:#953b39;} +.label-warning,.badge-warning{background-color:#f89406;} +.label-warning[href],.badge-warning[href]{background-color:#c67605;} +.label-success,.badge-success{background-color:#468847;} +.label-success[href],.badge-success[href]{background-color:#356635;} +.label-info,.badge-info{background-color:#3a87ad;} +.label-info[href],.badge-info[href]{background-color:#2d6987;} +.label-inverse,.badge-inverse{background-color:#333333;} +.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a;} +table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0;} +.table{width:100%;margin-bottom:18px;}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #dddddd;} +.table th{font-weight:bold;} +.table thead th{vertical-align:bottom;} +.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0;} +.table tbody+tbody{border-top:2px solid #dddddd;} +.table-condensed th,.table-condensed td{padding:4px 5px;} +.table-bordered{border:1px solid #dddddd;border-collapse:separate;*border-collapse:collapsed;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th,.table-bordered td{border-left:1px solid #dddddd;} +.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;} +.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px;} +.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px;} +.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;} +.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;} +.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;} +.table tbody tr:hover td,.table tbody tr:hover th{background-color:#f5f5f5;} +table .span1{float:none;width:44px;margin-left:0;} +table .span2{float:none;width:124px;margin-left:0;} +table .span3{float:none;width:204px;margin-left:0;} +table .span4{float:none;width:284px;margin-left:0;} +table .span5{float:none;width:364px;margin-left:0;} +table .span6{float:none;width:444px;margin-left:0;} +table .span7{float:none;width:524px;margin-left:0;} +table .span8{float:none;width:604px;margin-left:0;} +table .span9{float:none;width:684px;margin-left:0;} +table .span10{float:none;width:764px;margin-left:0;} +table .span11{float:none;width:844px;margin-left:0;} +table .span12{float:none;width:924px;margin-left:0;} +table .span13{float:none;width:1004px;margin-left:0;} +table .span14{float:none;width:1084px;margin-left:0;} +table .span15{float:none;width:1164px;margin-left:0;} +table .span16{float:none;width:1244px;margin-left:0;} +table .span17{float:none;width:1324px;margin-left:0;} +table .span18{float:none;width:1404px;margin-left:0;} +table .span19{float:none;width:1484px;margin-left:0;} +table .span20{float:none;width:1564px;margin-left:0;} +table .span21{float:none;width:1644px;margin-left:0;} +table .span22{float:none;width:1724px;margin-left:0;} +table .span23{float:none;width:1804px;margin-left:0;} +table .span24{float:none;width:1884px;margin-left:0;} +form{margin:0 0 18px;} +fieldset{padding:0;margin:0;border:0;} +legend{display:block;width:100%;padding:0;margin-bottom:27px;font-size:19.5px;line-height:36px;color:#333333;border:0;border-bottom:1px solid #e5e5e5;}legend small{font-size:13.5px;color:#999999;} +label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:18px;} +input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;} +label{display:block;margin-bottom:5px;} +select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:18px;padding:4px;margin-bottom:9px;font-size:13px;line-height:18px;color:#555555;} +input,textarea{width:210px;} +textarea{height:auto;} +textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#ffffff;border:1px solid #cccccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-ms-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s;}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82, 168, 236, 0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);} +input[type="radio"],input[type="checkbox"]{margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;} +input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto;} +.uneditable-textarea{width:auto;height:auto;} +select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px;} +select{width:220px;border:1px solid #bbb;} +select[multiple],select[size]{height:auto;} +select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.radio,.checkbox{min-height:18px;padding-left:18px;} +.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px;} +.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;} +.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;} +.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;} +.input-mini{width:60px;} +.input-small{width:90px;} +.input-medium{width:150px;} +.input-large{width:210px;} +.input-xlarge{width:270px;} +.input-xxlarge{width:530px;} +input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0;} +.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block;} +input,textarea,.uneditable-input{margin-left:0;} +input.span12, textarea.span12, .uneditable-input.span12{width:930px;} +input.span11, textarea.span11, .uneditable-input.span11{width:850px;} +input.span10, textarea.span10, .uneditable-input.span10{width:770px;} +input.span9, textarea.span9, .uneditable-input.span9{width:690px;} +input.span8, textarea.span8, .uneditable-input.span8{width:610px;} +input.span7, textarea.span7, .uneditable-input.span7{width:530px;} +input.span6, textarea.span6, .uneditable-input.span6{width:450px;} +input.span5, textarea.span5, .uneditable-input.span5{width:370px;} +input.span4, textarea.span4, .uneditable-input.span4{width:290px;} +input.span3, textarea.span3, .uneditable-input.span3{width:210px;} +input.span2, textarea.span2, .uneditable-input.span2{width:130px;} +input.span1, textarea.span1, .uneditable-input.span1{width:50px;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;border-color:#ddd;} +input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent;} +.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;} +.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853;}.control-group.warning .checkbox:focus,.control-group.warning .radio:focus,.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:0 0 6px #dbc59e;-moz-box-shadow:0 0 6px #dbc59e;box-shadow:0 0 6px #dbc59e;} +.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} +.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} +.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48;}.control-group.error .checkbox:focus,.control-group.error .radio:focus,.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:0 0 6px #d59392;-moz-box-shadow:0 0 6px #d59392;box-shadow:0 0 6px #d59392;} +.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} +.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} +.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847;}.control-group.success .checkbox:focus,.control-group.success .radio:focus,.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:0 0 6px #7aba7b;-moz-box-shadow:0 0 6px #7aba7b;box-shadow:0 0 6px #7aba7b;} +.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} +input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} +.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";} +.form-actions:after{clear:both;} +.uneditable-input{overflow:hidden;white-space:nowrap;cursor:not-allowed;background-color:#ffffff;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);} +:-moz-placeholder{color:#999999;} +:-ms-input-placeholder{color:#999999;} +::-webkit-input-placeholder{color:#999999;} +.help-block,.help-inline{color:#555555;} +.help-block{display:block;margin-bottom:9px;} +.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;} +.input-prepend,.input-append{margin-bottom:5px;}.input-prepend input,.input-append input,.input-prepend select,.input-append select,.input-prepend .uneditable-input,.input-append .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:middle;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}.input-prepend input:focus,.input-append input:focus,.input-prepend select:focus,.input-append select:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus{z-index:2;} +.input-prepend .uneditable-input,.input-append .uneditable-input{border-left-color:#ccc;} +.input-prepend .add-on,.input-append .add-on{display:inline-block;width:auto;height:18px;min-width:16px;padding:4px 5px;font-weight:normal;line-height:18px;text-align:center;text-shadow:0 1px 0 #ffffff;vertical-align:middle;background-color:#eeeeee;border:1px solid #ccc;} +.input-prepend .add-on,.input-append .add-on,.input-prepend .btn,.input-append .btn{margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-prepend .active,.input-append .active{background-color:#a9dba9;border-color:#46a546;} +.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;} +.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-append .uneditable-input{border-right-color:#ccc;border-left-color:#eee;} +.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:14px;-moz-border-radius:14px;border-radius:14px;} +.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;} +.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;} +.form-search label,.form-inline label{display:inline-block;} +.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;} +.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;} +.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0;} +.control-group{margin-bottom:9px;} +legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate;} +.form-horizontal .control-group{margin-bottom:18px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";} +.form-horizontal .control-group:after{clear:both;} +.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right;} +.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:160px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:160px;} +.form-horizontal .help-block{margin-top:9px;margin-bottom:0;} +.form-horizontal .form-actions{padding-left:160px;} +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 10px 4px;margin-bottom:0;font-size:13px;line-height:18px;*line-height:20px;color:#333333;text-align:center;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-ms-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(top, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #cccccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{background-color:#e6e6e6;*background-color:#d9d9d9;} +.btn:active,.btn.active{background-color:#cccccc \9;} +.btn:first-child{*margin-left:0;} +.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-ms-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} +.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.btn-large [class^="icon-"]{margin-top:1px;} +.btn-small{padding:5px 9px;font-size:11px;line-height:16px;} +.btn-small [class^="icon-"]{margin-top:-1px;} +.btn-mini{padding:2px 6px;font-size:11px;line-height:14px;} +.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover,.btn-inverse,.btn-inverse:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);} +.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);} +.btn{border-color:#ccc;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);} +.btn-primary{background-color:#0074cc;background-image:-moz-linear-gradient(top, #0088cc, #0055cc);background-image:-ms-linear-gradient(top, #0088cc, #0055cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0055cc));background-image:-webkit-linear-gradient(top, #0088cc, #0055cc);background-image:-o-linear-gradient(top, #0088cc, #0055cc);background-image:linear-gradient(top, #0088cc, #0055cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0055cc', GradientType=0);border-color:#0055cc #0055cc #003580;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0055cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{background-color:#0055cc;*background-color:#004ab3;} +.btn-primary:active,.btn-primary.active{background-color:#004099 \9;} +.btn-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{background-color:#f89406;*background-color:#df8505;} +.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} +.btn-danger{background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-ms-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(top, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{background-color:#bd362f;*background-color:#a9302a;} +.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} +.btn-success{background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-ms-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(top, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{background-color:#51a351;*background-color:#499249;} +.btn-success:active,.btn-success.active{background-color:#408140 \9;} +.btn-info{background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-ms-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(top, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{background-color:#2f96b4;*background-color:#2a85a0;} +.btn-info:active,.btn-info.active{background-color:#24748c \9;} +.btn-inverse{background-color:#414141;background-image:-moz-linear-gradient(top, #555555, #222222);background-image:-ms-linear-gradient(top, #555555, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222));background-image:-webkit-linear-gradient(top, #555555, #222222);background-image:-o-linear-gradient(top, #555555, #222222);background-image:linear-gradient(top, #555555, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{background-color:#222222;*background-color:#151515;} +.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;} +button.btn,input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;} +button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;} +button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;} +button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;} +[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;}[class^="icon-"]:last-child,[class*=" icon-"]:last-child{*margin-left:0;} +.icon-white{background-image:url("../img/glyphicons-halflings-white.png");} +.icon-glass{background-position:0 0;} +.icon-music{background-position:-24px 0;} +.icon-search{background-position:-48px 0;} +.icon-envelope{background-position:-72px 0;} +.icon-heart{background-position:-96px 0;} +.icon-star{background-position:-120px 0;} +.icon-star-empty{background-position:-144px 0;} +.icon-user{background-position:-168px 0;} +.icon-film{background-position:-192px 0;} +.icon-th-large{background-position:-216px 0;} +.icon-th{background-position:-240px 0;} +.icon-th-list{background-position:-264px 0;} +.icon-ok{background-position:-288px 0;} +.icon-remove{background-position:-312px 0;} +.icon-zoom-in{background-position:-336px 0;} +.icon-zoom-out{background-position:-360px 0;} +.icon-off{background-position:-384px 0;} +.icon-signal{background-position:-408px 0;} +.icon-cog{background-position:-432px 0;} +.icon-trash{background-position:-456px 0;} +.icon-home{background-position:0 -24px;} +.icon-file{background-position:-24px -24px;} +.icon-time{background-position:-48px -24px;} +.icon-road{background-position:-72px -24px;} +.icon-download-alt{background-position:-96px -24px;} +.icon-download{background-position:-120px -24px;} +.icon-upload{background-position:-144px -24px;} +.icon-inbox{background-position:-168px -24px;} +.icon-play-circle{background-position:-192px -24px;} +.icon-repeat{background-position:-216px -24px;} +.icon-refresh{background-position:-240px -24px;} +.icon-list-alt{background-position:-264px -24px;} +.icon-lock{background-position:-287px -24px;} +.icon-flag{background-position:-312px -24px;} +.icon-headphones{background-position:-336px -24px;} +.icon-volume-off{background-position:-360px -24px;} +.icon-volume-down{background-position:-384px -24px;} +.icon-volume-up{background-position:-408px -24px;} +.icon-qrcode{background-position:-432px -24px;} +.icon-barcode{background-position:-456px -24px;} +.icon-tag{background-position:0 -48px;} +.icon-tags{background-position:-25px -48px;} +.icon-book{background-position:-48px -48px;} +.icon-bookmark{background-position:-72px -48px;} +.icon-print{background-position:-96px -48px;} +.icon-camera{background-position:-120px -48px;} +.icon-font{background-position:-144px -48px;} +.icon-bold{background-position:-167px -48px;} +.icon-italic{background-position:-192px -48px;} +.icon-text-height{background-position:-216px -48px;} +.icon-text-width{background-position:-240px -48px;} +.icon-align-left{background-position:-264px -48px;} +.icon-align-center{background-position:-288px -48px;} +.icon-align-right{background-position:-312px -48px;} +.icon-align-justify{background-position:-336px -48px;} +.icon-list{background-position:-360px -48px;} +.icon-indent-left{background-position:-384px -48px;} +.icon-indent-right{background-position:-408px -48px;} +.icon-facetime-video{background-position:-432px -48px;} +.icon-picture{background-position:-456px -48px;} +.icon-pencil{background-position:0 -72px;} +.icon-map-marker{background-position:-24px -72px;} +.icon-adjust{background-position:-48px -72px;} +.icon-tint{background-position:-72px -72px;} +.icon-edit{background-position:-96px -72px;} +.icon-share{background-position:-120px -72px;} +.icon-check{background-position:-144px -72px;} +.icon-move{background-position:-168px -72px;} +.icon-step-backward{background-position:-192px -72px;} +.icon-fast-backward{background-position:-216px -72px;} +.icon-backward{background-position:-240px -72px;} +.icon-play{background-position:-264px -72px;} +.icon-pause{background-position:-288px -72px;} +.icon-stop{background-position:-312px -72px;} +.icon-forward{background-position:-336px -72px;} +.icon-fast-forward{background-position:-360px -72px;} +.icon-step-forward{background-position:-384px -72px;} +.icon-eject{background-position:-408px -72px;} +.icon-chevron-left{background-position:-432px -72px;} +.icon-chevron-right{background-position:-456px -72px;} +.icon-plus-sign{background-position:0 -96px;} +.icon-minus-sign{background-position:-24px -96px;} +.icon-remove-sign{background-position:-48px -96px;} +.icon-ok-sign{background-position:-72px -96px;} +.icon-question-sign{background-position:-96px -96px;} +.icon-info-sign{background-position:-120px -96px;} +.icon-screenshot{background-position:-144px -96px;} +.icon-remove-circle{background-position:-168px -96px;} +.icon-ok-circle{background-position:-192px -96px;} +.icon-ban-circle{background-position:-216px -96px;} +.icon-arrow-left{background-position:-240px -96px;} +.icon-arrow-right{background-position:-264px -96px;} +.icon-arrow-up{background-position:-289px -96px;} +.icon-arrow-down{background-position:-312px -96px;} +.icon-share-alt{background-position:-336px -96px;} +.icon-resize-full{background-position:-360px -96px;} +.icon-resize-small{background-position:-384px -96px;} +.icon-plus{background-position:-408px -96px;} +.icon-minus{background-position:-433px -96px;} +.icon-asterisk{background-position:-456px -96px;} +.icon-exclamation-sign{background-position:0 -120px;} +.icon-gift{background-position:-24px -120px;} +.icon-leaf{background-position:-48px -120px;} +.icon-fire{background-position:-72px -120px;} +.icon-eye-open{background-position:-96px -120px;} +.icon-eye-close{background-position:-120px -120px;} +.icon-warning-sign{background-position:-144px -120px;} +.icon-plane{background-position:-168px -120px;} +.icon-calendar{background-position:-192px -120px;} +.icon-random{background-position:-216px -120px;} +.icon-comment{background-position:-240px -120px;} +.icon-magnet{background-position:-264px -120px;} +.icon-chevron-up{background-position:-288px -120px;} +.icon-chevron-down{background-position:-313px -119px;} +.icon-retweet{background-position:-336px -120px;} +.icon-shopping-cart{background-position:-360px -120px;} +.icon-folder-close{background-position:-384px -120px;} +.icon-folder-open{background-position:-408px -120px;} +.icon-resize-vertical{background-position:-432px -119px;} +.icon-resize-horizontal{background-position:-456px -118px;} +.icon-hdd{background-position:0 -144px;} +.icon-bullhorn{background-position:-24px -144px;} +.icon-bell{background-position:-48px -144px;} +.icon-certificate{background-position:-72px -144px;} +.icon-thumbs-up{background-position:-96px -144px;} +.icon-thumbs-down{background-position:-120px -144px;} +.icon-hand-right{background-position:-144px -144px;} +.icon-hand-left{background-position:-168px -144px;} +.icon-hand-up{background-position:-192px -144px;} +.icon-hand-down{background-position:-216px -144px;} +.icon-circle-arrow-right{background-position:-240px -144px;} +.icon-circle-arrow-left{background-position:-264px -144px;} +.icon-circle-arrow-up{background-position:-288px -144px;} +.icon-circle-arrow-down{background-position:-312px -144px;} +.icon-globe{background-position:-336px -144px;} +.icon-wrench{background-position:-360px -144px;} +.icon-tasks{background-position:-384px -144px;} +.icon-filter{background-position:-408px -144px;} +.icon-briefcase{background-position:-432px -144px;} +.icon-fullscreen{background-position:-456px -144px;} +.btn-group{position:relative;*zoom:1;*margin-left:.3em;}.btn-group:before,.btn-group:after{display:table;content:"";} +.btn-group:after{clear:both;} +.btn-group:first-child{*margin-left:0;} +.btn-group+.btn-group{margin-left:5px;} +.btn-toolbar{margin-top:9px;margin-bottom:9px;}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1;} +.btn-group>.btn{position:relative;float:left;margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2;} +.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;} +.btn-group>.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:4px;*padding-bottom:4px;} +.btn-group>.btn-mini.dropdown-toggle{padding-left:5px;padding-right:5px;} +.btn-group>.btn-small.dropdown-toggle{*padding-top:4px;*padding-bottom:4px;} +.btn-group>.btn-large.dropdown-toggle{padding-left:12px;padding-right:12px;} +.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;} +.btn-group.open .btn-primary.dropdown-toggle{background-color:#0055cc;} +.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406;} +.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f;} +.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351;} +.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4;} +.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;} +.btn .caret{margin-top:7px;margin-left:0;} +.btn:hover .caret,.open.btn-group .caret{opacity:1;filter:alpha(opacity=100);} +.btn-mini .caret{margin-top:5px;} +.btn-small .caret{margin-top:6px;} +.btn-large .caret{margin-top:6px;border-left-width:5px;border-right-width:5px;border-top-width:5px;} +.dropup .btn-large .caret{border-bottom:5px solid #000000;border-top:0;} +.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:0.75;filter:alpha(opacity=75);} +.nav{margin-left:0;margin-bottom:18px;list-style:none;} +.nav>li>a{display:block;} +.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} +.nav>.pull-right{float:right;} +.nav .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:18px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;} +.nav li+.nav-header{margin-top:9px;} +.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;} +.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} +.nav-list>li>a{padding:3px 15px;} +.nav-list>.active>a,.nav-list>.active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;} +.nav-list [class^="icon-"]{margin-right:2px;} +.nav-list .divider{*width:100%;height:1px;margin:8px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";} +.nav-tabs:after,.nav-pills:after{clear:both;} +.nav-tabs>li,.nav-pills>li{float:left;} +.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} +.nav-tabs{border-bottom:1px solid #ddd;} +.nav-tabs>li{margin-bottom:-1px;} +.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:18px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#0088cc;} +.nav-stacked>li{float:none;} +.nav-stacked>li>a{margin-right:0;} +.nav-tabs.nav-stacked{border-bottom:0;} +.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} +.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} +.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;} +.nav-pills.nav-stacked>li>a{margin-bottom:3px;} +.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;} +.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;} +.nav-pills .dropdown-menu{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;} +.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;} +.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret{border-top-color:#333333;border-bottom-color:#333333;} +.nav>.dropdown.active>a:hover{color:#000000;cursor:pointer;} +.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;} +.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);} +.tabs-stacked .open>a:hover{border-color:#999999;} +.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";} +.tabbable:after{clear:both;} +.tab-content{overflow:auto;} +.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0;} +.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;} +.tab-content>.active,.pill-content>.active{display:block;} +.tabs-below>.nav-tabs{border-top:1px solid #ddd;} +.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0;} +.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below>.nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;} +.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd;} +.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none;} +.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;} +.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;} +.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.tabs-left>.nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;} +.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;} +.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;} +.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.tabs-right>.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;} +.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} +.navbar{*position:relative;*z-index:2;overflow:visible;margin-bottom:18px;} +.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1);} +.navbar .container{width:auto;} +.nav-collapse.collapse{height:auto;} +.navbar{color:#999999;}.navbar .brand:hover{text-decoration:none;} +.navbar .brand{float:left;display:block;padding:8px 20px 12px;margin-left:-20px;font-size:20px;font-weight:200;line-height:1;color:#999999;} +.navbar .navbar-text{margin-bottom:0;line-height:40px;} +.navbar .navbar-link{color:#999999;}.navbar .navbar-link:hover{color:#ffffff;} +.navbar .btn,.navbar .btn-group{margin-top:5px;} +.navbar .btn-group .btn{margin:0;} +.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";} +.navbar-form:after{clear:both;} +.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;} +.navbar-form input,.navbar-form select{display:inline-block;margin-bottom:0;} +.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;} +.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;} +.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0;}.navbar-search .search-query{padding:4px 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#ffffff;background-color:#626262;border:1px solid #151515;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.navbar-search .search-query:-moz-placeholder{color:#cccccc;} +.navbar-search .search-query:-ms-input-placeholder{color:#cccccc;} +.navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;} +.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;} +.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;} +.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.navbar-fixed-top{top:0;} +.navbar-fixed-bottom{bottom:0;} +.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} +.navbar .nav.pull-right{float:right;} +.navbar .nav>li{display:block;float:left;} +.navbar .nav>li>a{float:none;padding:9px 10px 11px;line-height:19px;color:#999999;text-decoration:none;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);} +.navbar .btn{display:inline-block;padding:4px 10px 4px;margin:5px 5px 6px;line-height:18px;} +.navbar .btn-group{margin:0;padding:5px 5px 6px;} +.navbar .nav>li>a:hover{background-color:transparent;color:#ffffff;text-decoration:none;} +.navbar .nav .active>a,.navbar .nav .active>a:hover{color:#ffffff;text-decoration:none;background-color:#222222;} +.navbar .divider-vertical{height:40px;width:1px;margin:0 9px;overflow:hidden;background-color:#222222;border-right:1px solid #333333;} +.navbar .nav.pull-right{margin-left:10px;margin-right:0;} +.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{background-color:#222222;*background-color:#151515;} +.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#080808 \9;} +.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);} +.btn-navbar .icon-bar+.icon-bar{margin-top:3px;} +.navbar .dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;} +.navbar .dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;} +.navbar-fixed-bottom .dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;} +.navbar-fixed-bottom .dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;} +.navbar .nav li.dropdown .dropdown-toggle .caret,.navbar .nav li.dropdown.open .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.navbar .nav li.dropdown.active .caret{opacity:1;filter:alpha(opacity=100);} +.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:transparent;} +.navbar .nav li.dropdown.active>.dropdown-toggle:hover{color:#ffffff;} +.navbar .pull-right .dropdown-menu,.navbar .dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right .dropdown-menu:before,.navbar .dropdown-menu.pull-right:before{left:auto;right:12px;} +.navbar .pull-right .dropdown-menu:after,.navbar .dropdown-menu.pull-right:after{left:auto;right:13px;} +.breadcrumb{padding:7px 14px;margin:0 0 18px;list-style:none;background-color:#fbfbfb;background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);background-image:linear-gradient(top, #ffffff, #f5f5f5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#999999;} +.breadcrumb .active a{color:#333333;} +.pagination{height:36px;margin:18px 0;} +.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} +.pagination li{display:inline;} +.pagination a{float:left;padding:0 14px;line-height:34px;text-decoration:none;border:1px solid #ddd;border-left-width:0;} +.pagination a:hover,.pagination .active a{background-color:#f5f5f5;} +.pagination .active a{color:#999999;cursor:default;} +.pagination .disabled span,.pagination .disabled a,.pagination .disabled a:hover{color:#999999;background-color:transparent;cursor:default;} +.pagination li:first-child a{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.pagination li:last-child a{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.pagination-centered{text-align:center;} +.pagination-right{text-align:right;} +.pager{margin-left:0;margin-bottom:18px;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";} +.pager:after{clear:both;} +.pager li{display:inline;} +.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.pager a:hover{text-decoration:none;background-color:#f5f5f5;} +.pager .next a{float:right;} +.pager .previous a{float:left;} +.pager .disabled a,.pager .disabled a:hover{color:#999999;background-color:#fff;cursor:default;} +.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";} +.thumbnails:after{clear:both;} +.row-fluid .thumbnails{margin-left:0;} +.thumbnails>li{float:left;margin-bottom:18px;margin-left:20px;} +.thumbnail{display:block;padding:4px;line-height:1;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);} +a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} +.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;} +.thumbnail .caption{padding:9px;} +.alert{padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;} +.alert-heading{color:inherit;} +.alert .close{position:relative;top:-2px;right:-21px;line-height:18px;} +.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;} +.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;} +.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;} +.alert-block{padding-top:14px;padding-bottom:14px;} +.alert-block>p,.alert-block>ul{margin-bottom:0;} +.alert-block p+p{margin-top:5px;} +@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:18px;margin-bottom:18px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-ms-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(top, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.progress .bar{width:0%;height:18px;color:#ffffff;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-ms-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(top, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-ms-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} +.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;} +.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;} +.progress-danger .bar{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);} +.progress-danger.progress-striped .bar{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-success .bar{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-ms-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(top, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);} +.progress-success.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-info .bar{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(top, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);} +.progress-info.progress-striped .bar{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-warning .bar{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);} +.progress-warning.progress-striped .bar{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.hero-unit{padding:60px;margin-bottom:30px;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;} +.hero-unit p{font-size:18px;font-weight:200;line-height:27px;color:inherit;} +.tooltip{position:absolute;z-index:1020;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);} +.tooltip.top{margin-top:-2px;} +.tooltip.right{margin-left:2px;} +.tooltip.bottom{margin-top:2px;} +.tooltip.left{margin-left:-2px;} +.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} +.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} +.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} +.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.tooltip-arrow{position:absolute;width:0;height:0;} +.popover{position:absolute;top:0;left:0;z-index:1010;display:none;padding:5px;}.popover.top{margin-top:-5px;} +.popover.right{margin-left:5px;} +.popover.bottom{margin-top:5px;} +.popover.left{margin-left:-5px;} +.popover.top .arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} +.popover.bottom .arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} +.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} +.popover .arrow{position:absolute;width:0;height:0;} +.popover-inner{padding:3px;width:280px;overflow:hidden;background:#000000;background:rgba(0, 0, 0, 0.8);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);} +.popover-title{padding:9px 15px;line-height:1;background-color:#f5f5f5;border-bottom:1px solid #eee;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;} +.popover-content{padding:14px;background-color:#ffffff;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} +.modal-open .dropdown-menu{z-index:2050;} +.modal-open .dropdown.open{*z-index:2050;} +.modal-open .popover{z-index:2060;} +.modal-open .tooltip{z-index:2070;} +.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;} +.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);} +.modal{position:fixed;top:50%;left:50%;z-index:1050;overflow:auto;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-ms-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} +.modal.fade.in{top:50%;} +.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;} +.modal-body{overflow-y:auto;max-height:400px;padding:15px;} +.modal-form{margin-bottom:0;} +.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";} +.modal-footer:after{clear:both;} +.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;} +.modal-footer .btn-group .btn+.btn{margin-left:-1px;} +.dropup,.dropdown{position:relative;} +.dropdown-toggle{*margin-bottom:-3px;} +.dropdown-toggle:active,.open .dropdown-toggle{outline:0;} +.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";opacity:0.3;filter:alpha(opacity=30);} +.dropdown .caret{margin-top:8px;margin-left:2px;} +.dropdown:hover .caret,.open .caret{opacity:1;filter:alpha(opacity=100);} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:4px 0;margin:1px 0 0;list-style:none;background-color:#ffffff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;} +.dropdown-menu .divider{*width:100%;height:1px;margin:8px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.dropdown-menu a{display:block;padding:3px 15px;clear:both;font-weight:normal;line-height:18px;color:#333333;white-space:nowrap;} +.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#ffffff;text-decoration:none;background-color:#0088cc;} +.open{*z-index:1000;}.open >.dropdown-menu{display:block;} +.pull-right>.dropdown-menu{right:0;left:auto;} +.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"\2191";} +.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;} +.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion{margin-bottom:18px;} +.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion-heading{border-bottom:0;} +.accordion-heading .accordion-toggle{display:block;padding:8px 15px;} +.accordion-toggle{cursor:pointer;} +.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;} +.carousel{position:relative;margin-bottom:18px;line-height:1;} +.carousel-inner{overflow:hidden;width:100%;position:relative;} +.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-ms-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;} +.carousel .item>img{display:block;line-height:1;} +.carousel .active,.carousel .next,.carousel .prev{display:block;} +.carousel .active{left:0;} +.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;} +.carousel .next{left:100%;} +.carousel .prev{left:-100%;} +.carousel .next.left,.carousel .prev.right{left:0;} +.carousel .active.left{left:-100%;} +.carousel .active.right{left:100%;} +.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;} +.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);} +.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:10px 15px 5px;background:#333333;background:rgba(0, 0, 0, 0.75);} +.carousel-caption h4,.carousel-caption p{color:#ffffff;} +.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} +.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);} +button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.invisible{visibility:hidden;} +.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-ms-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;}.fade.in{opacity:1;} +.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-ms-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;} +.hidden{display:none;visibility:hidden;} +.visible-phone{display:none !important;} +.visible-tablet{display:none !important;} +.hidden-desktop{display:none !important;} +@media (max-width:767px){.visible-phone{display:inherit !important;} .hidden-phone{display:none !important;} .hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;}}@media (min-width:768px) and (max-width:979px){.visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;} .hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:18px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .modal{position:absolute;top:10px;left:10px;right:10px;width:auto;margin:0;}.modal.fade.in{top:auto;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} [class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:auto;margin-left:0;} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} .input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:20px;} .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.762430939%;*margin-left:2.709239449638298%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .span12{width:99.999999993%;*width:99.9468085036383%;} .row-fluid .span11{width:91.436464082%;*width:91.38327259263829%;} .row-fluid .span10{width:82.87292817100001%;*width:82.8197366816383%;} .row-fluid .span9{width:74.30939226%;*width:74.25620077063829%;} .row-fluid .span8{width:65.74585634900001%;*width:65.6926648596383%;} .row-fluid .span7{width:57.182320438000005%;*width:57.129128948638304%;} .row-fluid .span6{width:48.618784527%;*width:48.5655930376383%;} .row-fluid .span5{width:40.055248616%;*width:40.0020571266383%;} .row-fluid .span4{width:31.491712705%;*width:31.4385212156383%;} .row-fluid .span3{width:22.928176794%;*width:22.874985304638297%;} .row-fluid .span2{width:14.364640883%;*width:14.311449393638298%;} .row-fluid .span1{width:5.801104972%;*width:5.747913482638298%;} input,textarea,.uneditable-input{margin-left:0;} input.span12, textarea.span12, .uneditable-input.span12{width:714px;} input.span11, textarea.span11, .uneditable-input.span11{width:652px;} input.span10, textarea.span10, .uneditable-input.span10{width:590px;} input.span9, textarea.span9, .uneditable-input.span9{width:528px;} input.span8, textarea.span8, .uneditable-input.span8{width:466px;} input.span7, textarea.span7, .uneditable-input.span7{width:404px;} input.span6, textarea.span6, .uneditable-input.span6{width:342px;} input.span5, textarea.span5, .uneditable-input.span5{width:280px;} input.span4, textarea.span4, .uneditable-input.span4{width:218px;} input.span3, textarea.span3, .uneditable-input.span3{width:156px;} input.span2, textarea.span2, .uneditable-input.span2{width:94px;} input.span1, textarea.span1, .uneditable-input.span1{width:32px;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:30px;} .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564%;*margin-left:2.510911074638298%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145300001%;*width:91.3997999636383%;} .row-fluid .span10{width:82.905982906%;*width:82.8527914166383%;} .row-fluid .span9{width:74.358974359%;*width:74.30578286963829%;} .row-fluid .span8{width:65.81196581200001%;*width:65.7587743226383%;} .row-fluid .span7{width:57.264957265%;*width:57.2117657756383%;} .row-fluid .span6{width:48.717948718%;*width:48.6647572286383%;} .row-fluid .span5{width:40.170940171000005%;*width:40.117748681638304%;} .row-fluid .span4{width:31.623931624%;*width:31.5707401346383%;} .row-fluid .span3{width:23.076923077%;*width:23.0237315876383%;} .row-fluid .span2{width:14.529914530000001%;*width:14.4767230406383%;} .row-fluid .span1{width:5.982905983%;*width:5.929714493638298%;} input,textarea,.uneditable-input{margin-left:0;} input.span12, textarea.span12, .uneditable-input.span12{width:1160px;} input.span11, textarea.span11, .uneditable-input.span11{width:1060px;} input.span10, textarea.span10, .uneditable-input.span10{width:960px;} input.span9, textarea.span9, .uneditable-input.span9{width:860px;} input.span8, textarea.span8, .uneditable-input.span8{width:760px;} input.span7, textarea.span7, .uneditable-input.span7{width:660px;} input.span6, textarea.span6, .uneditable-input.span6{width:560px;} input.span5, textarea.span5, .uneditable-input.span5{width:460px;} input.span4, textarea.span4, .uneditable-input.span4{width:360px;} input.span3, textarea.span3, .uneditable-input.span3{width:260px;} input.span2, textarea.span2, .uneditable-input.span2{width:160px;} input.span1, textarea.span1, .uneditable-input.span1{width:60px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:18px;} .navbar-fixed-bottom{margin-top:18px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 9px;} .nav-collapse .nav>li{float:none;} .nav-collapse .nav>li>a{margin-bottom:2px;} .nav-collapse .nav>.divider-vertical{display:none;} .nav-collapse .nav .nav-header{color:#999999;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} .nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#222222;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:block;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} .nav-collapse .dropdown-menu .divider{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222222;border-bottom:1px solid #222222;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-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);} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}} diff --git a/samples/scala/play-authenticate-usage/public/css/main.css b/samples/scala/play-authenticate-usage/public/css/main.css new file mode 100644 index 00000000..74684727 --- /dev/null +++ b/samples/scala/play-authenticate-usage/public/css/main.css @@ -0,0 +1,32 @@ +body { + padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */ +} + +form .error input { + background-color: #F2DEDE; + border-color: #EED3D7; + color: #B94A48; +} + +form .error .help-inline { + color: #B94A48; +} + +.providers { + margin: 5px 0; + list-style: none; +} + +.providers li { + display: inline; +} + +.help-block { + margin: -10px 0 10px 0; + font-size: 10px; + color: #ccc !important; +} + +h1 { + margin-bottom: 20px !important; +} diff --git a/samples/scala/play-authenticate-usage/public/icons/basic-24x24.png b/samples/scala/play-authenticate-usage/public/icons/basic-24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..5389f254c306a1fe40dc7aad0e4d22fe6bd5cb74 GIT binary patch literal 1460 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 Tl2pA7x?hwR$CrK1En??CGTzD^ literal 0 HcmV?d00001 diff --git a/samples/scala/play-authenticate-usage/public/icons/google-24x24.png b/samples/scala/play-authenticate-usage/public/icons/google-24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..3c32168a73716bf9621b82dd31ebe545352267f2 GIT binary patch literal 1452 zcmV;d1ylNoP)_!dPL7+Mo&5-K5NOW(3qZ{p1IHx|M)W-te+0FUd}1b=4IUC_J?1H$$<#2-g6H{ zl8}dhs)89wxt0(Mi~G(j*`4PzK*Ixg?~|pAIlfXsFvLo!QXQ`H!s#^@SK0tEQT2{H zFp(ImDvn4dE!Soi*RG6x2?6l*Y@-WSD)& zAj+jF{{`4uQS#Pigm}}~vT4A3$3`ZD4gjQHj|sI`tvZK7lK{vfY^O+&-W`cgHK#HMs}%<7sY9y^Ts+B z0(-9-r*A6{KFDzuo-aX%KQ+mb1KT-z;0k6x_jaDXc8n9iNfB0otlvQ&a_`L(%q^Vf z)w35cDPr=6zI-hoc;{#=Vr_n&N1ppBo$p`G%I?c33Zb(pDcxD_ibZ(TOEM4zn|b6N54cdRiimvM-2*r zPB&1PXS4KKAjYjSsH_L(XXlIsFFKA}Bq&;URXn6POdKX+r9uR&h8Jydx@2)A$Zl1XYP12M_@{m5OJ0>j=&95l$_>!toa`^5)sx zc=-W5DXmUMAx66!FrVN`seuF~h~Rsd#d!}l02E}amuQ_kPwV^ztjIX@^JloUkqsW! zmE)8A?Bjo6vN^-b>#KAMBM(L)fJhlNGWo5?HJ|rH|^xZ@7c!0c>T@C zGnhrQ*5G@49_69=dpY*X6O50Jl8d5vvRnw}5w!@B8212={a`=0efE?6Y6r=6ZJyju zP;XB5_ap3^yAP2E<>{A?(A?6b5GiE@pioff5i!I713&rJ5&9;}zo2vM1~z{`NpbvE z{GUHW_t{(Nyzx@MfaveO?mjj%iPtd~=n6zg6o>-OgMtUJVx7*BkD?3rk;oaUCDgs8 z4kHz~^c?*0COYT;H0Z8T8DaWu*Ravb$qGfx$M+y41dX#H^a0jcCOi6Rd^m^SGK^MJ zT*c$O;fGRua~Kkj|LfPtvNr~hi7ne{XMt`YKC-SrmIpeyL|*_1_+sf{EMLaghhmGU zBXkv~DVWF1VYLd{S;w!Pq-SxkqMj^Re7#aCSQ2kn9%te~Aq{8dke$2GT&dI&9EKEv z1;aZ>$Q4hDiX*L!4hDXv^;$e04Th*-&X;RJ@d%KqfHnw=9QqHfpf$|=1b;gK0000_A^TUz3r`)`zi;pC)YLRoky!u&C=e^#;u4s&l@eTW} z;jsDshw}@o*RFxKKKtgEPak^XAcSV(h@q+|@Fbks4p&Z@8DV@K0*KtP>I<=v2DFX7PAF0c}m$O9MM`Ick>tm^A=pTTHkS`nBTgJA@#_{WMV;+@Bq zU~rw;1De(nRH1-#rGO?Th>~-c@-j9qET|#kPfVG;j@k6_pReHgefOKbjO@;W4hn$? zn<@%U*M10Gqt2dDpBLx<&s9r$ha z1`h0*$AdfXz||YKarW{W9^P{|8dexQ#$eC@to{Oj7Ssd*3V8iH95{BW$DjG|TYUY> zqqx&rvBR&H@Z}R{F;P{hOgLwN0IE7*l{DB3W zy0iw#0;15iy9jK>h^0eDF(Mfs$7qy#{O?;0-uQe4AFW)*?YLok;h{xuf+j@_Z9lRA z>h+sm=gfj1ul_S`^9qDefkeTqT>?fbZAfKs<(yIAoi)bYS3qquFmJLcAPH3{ zBd6;kKU8WTs;YNLKs~O;M`LB|C-A{o;>lPSsen!VTANCggnN8wYXZFEIQMKGN4vHo z+V}=Z0M172kZS){EV_wH>%*oAn_pK(i2@-2QW7u}O5Hrk*tTt3udc>>L0H&JX}V`? zqE7@*P)|()-7LxglocWgP{RDt6JAR#?(=V-K-C5`U3-U+B=4A=M?ZF(Lfd(i*>zWL zPY{`*IraWl%wpWk%x%3@08m?^K!B2uc~D!fP`*iBlEu&o-wKK^@ zO*pr&h&lVs>vCI$!}zo}LMC#qgW-Tz&i?_?Glaz_=Kwka!a*q75lQNS3c5`F{XRN} fjzp8QfWG%1Lsd_q#(@)z00000NkvXXu0mjf#1IKu literal 0 HcmV?d00001 diff --git a/samples/scala/play-authenticate-usage/public/icons/openid-24x24.png b/samples/scala/play-authenticate-usage/public/icons/openid-24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..553c229e39653988c0d2b7e8c0b37d01003facd0 GIT binary patch literal 1002 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 P00000NkvXXu0mjfU&r-* literal 0 HcmV?d00001 diff --git a/samples/scala/play-authenticate-usage/public/icons/untappd-24x24.png b/samples/scala/play-authenticate-usage/public/icons/untappd-24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..5389f254c306a1fe40dc7aad0e4d22fe6bd5cb74 GIT binary patch literal 1460 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 D15iXi literal 0 HcmV?d00001 diff --git a/samples/scala/play-authenticate-usage/public/img/glyphicons-halflings-white.png b/samples/scala/play-authenticate-usage/public/img/glyphicons-halflings-white.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf6484a29d8da269f9bc874b25493a45fae3bae GIT binary patch literal 8777 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 B7G?kd literal 0 HcmV?d00001 diff --git a/samples/scala/play-authenticate-usage/public/img/glyphicons-halflings.png b/samples/scala/play-authenticate-usage/public/img/glyphicons-halflings.png new file mode 100644 index 0000000000000000000000000000000000000000..79bc568c21395d5a5ceab62fadb04457094b2ac7 GIT binary patch literal 13826 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 literal 0 HcmV?d00001 diff --git a/samples/scala/play-authenticate-usage/public/js/bootstrap.js b/samples/scala/play-authenticate-usage/public/js/bootstrap.js new file mode 100644 index 00000000..28c72e0b --- /dev/null +++ b/samples/scala/play-authenticate-usage/public/js/bootstrap.js @@ -0,0 +1,1836 @@ +/* =================================================== + * bootstrap-transition.js v2.0.4 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + $(function () { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd' + , 'msTransition' : 'MSTransitionEnd' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.jQuery); +/* ========================================================= + * bootstrap-modal.js v2.0.4 + * http://twitter.github.com/bootstrap/javascript.html#modals + * ========================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* MODAL CLASS DEFINITION + * ====================== */ + + var Modal = function (content, options) { + this.options = options + this.$element = $(content) + .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) + } + + Modal.prototype = { + + constructor: Modal + + , toggle: function () { + return this[!this.isShown ? 'show' : 'hide']() + } + + , show: function () { + var that = this + , e = $.Event('show') + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + $('body').addClass('modal-open') + + this.isShown = true + + escape.call(this) + backdrop.call(this, function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(document.body) //don't move modals dom position + } + + that.$element + .show() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + transition ? + that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) : + that.$element.trigger('shown') + + }) + } + + , hide: function (e) { + e && e.preventDefault() + + var that = this + + e = $.Event('hide') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + $('body').removeClass('modal-open') + + escape.call(this) + + this.$element.removeClass('in') + + $.support.transition && this.$element.hasClass('fade') ? + hideWithTransition.call(this) : + hideModal.call(this) + } + + } + + + /* MODAL PRIVATE METHODS + * ===================== */ + + function hideWithTransition() { + var that = this + , timeout = setTimeout(function () { + that.$element.off($.support.transition.end) + hideModal.call(that) + }, 500) + + this.$element.one($.support.transition.end, function () { + clearTimeout(timeout) + hideModal.call(that) + }) + } + + function hideModal(that) { + this.$element + .hide() + .trigger('hidden') + + backdrop.call(this) + } + + function backdrop(callback) { + var that = this + , animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('