From a4d1c399368d4d1f1e6dbd5c7832a6dfaf260fd4 Mon Sep 17 00:00:00 2001 From: xuchang Date: Thu, 25 Mar 2021 14:58:56 +0800 Subject: [PATCH] =?UTF-8?q?--user=3Dxuchang,--message=3D'=E6=95=B4?= =?UTF-8?q?=E5=90=88sso=E6=90=AD=E5=BB=BA'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- itools-core/pom.xml | 16 +- itools-fms/pom.xml | 2 +- itools-gms/pom.xml | 2 +- itools-oms/pom.xml | 2 +- ...30\346\226\271\346\226\207\346\241\243.md" | 400 +++ ...\346\236\266\346\236\204\345\233\276.pptx" | Bin 0 -> 45185 bytes itools-sso/doc/images/img_01.png | Bin 0 -> 176414 bytes itools-sso/itools-sso-core/pom.xml | 39 + .../java/com/itools/sso/core/conf/Conf.java | 61 + .../com/itools/sso/core/entity/ReturnT.java | 51 + .../sso/core/exception/XxlSsoException.java | 22 + .../sso/core/filter/XxlSsoTokenFilter.java | 101 + .../sso/core/filter/XxlSsoWebFilter.java | 116 + .../sso/core/login/SsoTokenLoginHelper.java | 99 + .../sso/core/login/SsoWebLoginHelper.java | 119 + .../com/itools/sso/core/path/PathMatcher.java | 106 + .../sso/core/path/impl/AntPathMatcher.java | 881 +++++++ .../itools/sso/core/store/SsoLoginStore.java | 70 + .../sso/core/store/SsoSessionIdHelper.java | 70 + .../com/itools/sso/core/user/XxlSsoUser.java | 73 + .../com/itools/sso/core/util/CookieUtil.java | 98 + .../com/itools/sso/core/util/JedisUtil.java | 391 +++ .../com/itools/sso/core/util/StringUtils.java | 79 + .../pom.xml | 91 + .../sso/sample/XxlClientApplication.java | 16 + .../sso/sample/config/XxlSsoConfig.java | 59 + .../sample/controller/IndexController.java | 25 + .../src/main/resources/application.properties | 9 + .../src/main/resources/logback.xml | 32 + .../xxl/app/sample/test/TokenClientTest.java | 182 ++ .../app/sample/test/util/HttpClientUtil.java | 90 + .../src/test/resources/logback.xml | 16 + .../target/classes/application.properties | 9 + .../target/classes/logback.xml | 32 + .../target/test-classes/logback.xml | 16 + .../itools-sso-web-sample-springboot/pom.xml | 83 + .../sso/sample/XxlClientApplication.java | 16 + .../sso/sample/config/XxlSsoConfig.java | 59 + .../sample/controller/IndexController.java | 34 + .../src/main/resources/application.properties | 18 + .../src/main/resources/logback.xml | 32 + .../src/main/resources/templates/index.ftl | 17 + itools-sso/itools-sso-samples/pom.xml | 19 + itools-sso/itools-sso-server/pom.xml | 85 + .../sso/server/XxlSsoServerApplication.java | 16 + .../sso/server/config/XxlSsoConfig.java | 33 + .../sso/server/controller/AppController.java | 99 + .../sso/server/controller/WebController.java | 151 ++ .../interceptor/MyWebMvcConfigurer.java | 21 + .../interceptor/PermissionInterceptor.java | 38 + .../resolver/WebExceptionResolver.java | 72 + .../sso/server/core/model/UserInfo.java | 36 + .../sso/server/core/result/ReturnT.java | 51 + .../sso/server/service/UserService.java | 10 + .../server/service/impl/UserServiceImpl.java | 46 + .../src/main/resources/application.properties | 18 + .../src/main/resources/logback.xml | 32 + .../adminlte/bootstrap/css/bootstrap.css.map | 1 + .../adminlte/bootstrap/css/bootstrap.min.css | 6 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 +++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../adminlte/bootstrap/js/bootstrap.min.js | 7 + .../adminlte/dist/css/AdminLTE-local.min.css | 7 + .../static/adminlte/dist/css/AdminLTE.min.css | 7 + ...PJhLKp0zdtTvoM40tgx99jmYGv_xzYuwd1rU.woff2 | Bin 0 -> 12264 bytes ...PJhLKp0zdtTvoM7YHq4FgHI02B8rPccK0FJQ.woff2 | Bin 0 -> 4584 bytes ...PJhLKp0zdtTvoMxgy2Fsj5sj3EzlXpqVXRKo.woff2 | Bin 0 -> 13980 bytes ...HBYDBqgeIAH2zlC2Q8seG17bfDXYR_jUsrzg.woff2 | Bin 0 -> 12336 bytes ...HBYDBqgeIAH2zlNOAHFN6BivSraYkjhveRHY.woff2 | Bin 0 -> 4504 bytes ...DBqgeIAH2zlNOAHFN6BivSraYkjhveRHY[0].woff2 | Bin 0 -> 4504 bytes ...HBYDBqgeIAH2zlNV_2ngZ8dMf8fLgjYEouxg.woff2 | Bin 0 -> 14308 bytes ...qsXbIeTHTrnQH6CzM2XYAq8cDhaXsrN8WXcA.woff2 | Bin 0 -> 4596 bytes ...qsXbIeTHTrnQH6E78GtRp3lhchupCJNw8t58.woff2 | Bin 0 -> 4556 bytes ...qsXbIeTHTrnQH6GQKuzMuncr0JB710wa2dPI.woff2 | Bin 0 -> 13716 bytes ...qsXbIeTHTrnQH6Lpx497t94oDua8KfAL9f-E.woff2 | Bin 0 -> 12196 bytes ...qsXbIeTHTrnQH6MAjkyiewWYrWZc50I8hK7I.woff2 | Bin 0 -> 13772 bytes ...qsXbIeTHTrnQH6OXKTZYPNtG1yMB_YJSqlic.woff2 | Bin 0 -> 12228 bytes ...mlt9b38dHJxOBGCOFnW3Jk0f09zW_Yln67Ac.woff2 | Bin 0 -> 13992 bytes ...mlt9b38dHJxOBGClYwVOhDRq2vbpGRTZ7bbs.woff2 | Bin 0 -> 4512 bytes ...mlt9b38dHJxOBGDRVvBvQIc1z78c__uoBcyI.woff2 | Bin 0 -> 12396 bytes ...mlt9b38dHJxOBGD_j0nMiB9fPhg_k1wdK2h0.woff2 | Bin 0 -> 4588 bytes ...mlt9b38dHJxOBGDovqjS_dXPZszO_XltPdNg.woff2 | Bin 0 -> 4432 bytes ...mlt9b38dHJxOBGEo0As1BFRXtCDhS66znb_k.woff2 | Bin 0 -> 13892 bytes ...mlt9b38dHJxOBGFKFh1TDTPrUZWzVp6FtpG8.woff2 | Bin 0 -> 12384 bytes ...mlt9b38dHJxOBGFxe-GPfKKFmiXaJ_Q0GFr8.woff2 | Bin 0 -> 12244 bytes ...mlt9b38dHJxOBGOode0-EuMkY--TSyExeINg.woff2 | Bin 0 -> 14308 bytes .../css/google-local/local.google.fonts.css | 168 ++ .../dist/css/skins/_all-skins.min.css | 1 + .../static/adminlte/dist/js/app.min.js | 13 + .../plugins/fastclick/fastclick.min.js | 1 + .../adminlte/plugins/iCheck/icheck.min.js | 10 + .../adminlte/plugins/iCheck/square/_all.css | 620 +++++ .../adminlte/plugins/iCheck/square/aero.css | 62 + .../adminlte/plugins/iCheck/square/aero.png | Bin 0 -> 2167 bytes .../plugins/iCheck/square/aero@2x.png | Bin 0 -> 4455 bytes .../adminlte/plugins/iCheck/square/blue.css | 62 + .../adminlte/plugins/iCheck/square/blue.png | Bin 0 -> 2185 bytes .../plugins/iCheck/square/blue@2x.png | Bin 0 -> 4485 bytes .../adminlte/plugins/iCheck/square/green.css | 62 + .../adminlte/plugins/iCheck/square/green.png | Bin 0 -> 2193 bytes .../plugins/iCheck/square/green@2x.png | Bin 0 -> 4498 bytes .../adminlte/plugins/iCheck/square/grey.css | 62 + .../adminlte/plugins/iCheck/square/grey.png | Bin 0 -> 2186 bytes .../plugins/iCheck/square/grey@2x.png | Bin 0 -> 4483 bytes .../adminlte/plugins/iCheck/square/orange.css | 62 + .../adminlte/plugins/iCheck/square/orange.png | Bin 0 -> 2181 bytes .../plugins/iCheck/square/orange@2x.png | Bin 0 -> 4474 bytes .../adminlte/plugins/iCheck/square/pink.css | 62 + .../adminlte/plugins/iCheck/square/pink.png | Bin 0 -> 2189 bytes .../plugins/iCheck/square/pink@2x.png | Bin 0 -> 4479 bytes .../adminlte/plugins/iCheck/square/purple.css | 62 + .../adminlte/plugins/iCheck/square/purple.png | Bin 0 -> 2188 bytes .../plugins/iCheck/square/purple@2x.png | Bin 0 -> 4501 bytes .../adminlte/plugins/iCheck/square/red.css | 62 + .../adminlte/plugins/iCheck/square/red.png | Bin 0 -> 2190 bytes .../adminlte/plugins/iCheck/square/red@2x.png | Bin 0 -> 4490 bytes .../adminlte/plugins/iCheck/square/square.css | 62 + .../adminlte/plugins/iCheck/square/square.png | Bin 0 -> 2175 bytes .../plugins/iCheck/square/square@2x.png | Bin 0 -> 4478 bytes .../adminlte/plugins/iCheck/square/yellow.css | 62 + .../adminlte/plugins/iCheck/square/yellow.png | Bin 0 -> 2131 bytes .../plugins/iCheck/square/yellow@2x.png | Bin 0 -> 4385 bytes .../plugins/jQuery/jquery-2.2.3.min.js | 4 + .../slimScroll/jquery.slimscroll.min.js | 16 + .../src/main/resources/static/js/common.1.js | 46 + .../src/main/resources/static/js/index.js | 3 + .../src/main/resources/static/js/login.1.js | 10 + .../css/font-awesome.css.map | 7 + .../css/font-awesome.min.css | 4 + .../font-awesome-4.5.0/fonts/FontAwesome.otf | Bin 0 -> 109688 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 70807 bytes .../fonts/fontawesome-webfont.svg | 655 +++++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 142072 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 83588 bytes .../fonts/fontawesome-webfont.woff2 | Bin 0 -> 66624 bytes .../ionicons-2.0.1/css/ionicons.min.css | 11 + .../plugins/ionicons-2.0.1/fonts/ionicons.eot | Bin 0 -> 120724 bytes .../plugins/ionicons-2.0.1/fonts/ionicons.svg | 2230 +++++++++++++++++ .../plugins/ionicons-2.0.1/fonts/ionicons.ttf | Bin 0 -> 188508 bytes .../ionicons-2.0.1/fonts/ionicons.woff | Bin 0 -> 67904 bytes .../templates/common/common.exception.ftl | 1 + .../templates/common/common.macro.ftl | 96 + .../src/main/resources/templates/index.ftl | 49 + .../src/main/resources/templates/login.ftl | 55 + .../src/test/java/ApplicationTests.java | 25 + .../target/classes/application.properties | 18 + .../target/classes/logback.xml | 32 + .../adminlte/bootstrap/css/bootstrap.css.map | 1 + .../adminlte/bootstrap/css/bootstrap.min.css | 6 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 +++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../adminlte/bootstrap/js/bootstrap.min.js | 7 + .../adminlte/dist/css/AdminLTE-local.min.css | 7 + .../static/adminlte/dist/css/AdminLTE.min.css | 7 + ...PJhLKp0zdtTvoM40tgx99jmYGv_xzYuwd1rU.woff2 | Bin 0 -> 12264 bytes ...PJhLKp0zdtTvoM7YHq4FgHI02B8rPccK0FJQ.woff2 | Bin 0 -> 4584 bytes ...PJhLKp0zdtTvoMxgy2Fsj5sj3EzlXpqVXRKo.woff2 | Bin 0 -> 13980 bytes ...HBYDBqgeIAH2zlC2Q8seG17bfDXYR_jUsrzg.woff2 | Bin 0 -> 12336 bytes ...HBYDBqgeIAH2zlNOAHFN6BivSraYkjhveRHY.woff2 | Bin 0 -> 4504 bytes ...DBqgeIAH2zlNOAHFN6BivSraYkjhveRHY[0].woff2 | Bin 0 -> 4504 bytes ...HBYDBqgeIAH2zlNV_2ngZ8dMf8fLgjYEouxg.woff2 | Bin 0 -> 14308 bytes ...qsXbIeTHTrnQH6CzM2XYAq8cDhaXsrN8WXcA.woff2 | Bin 0 -> 4596 bytes ...qsXbIeTHTrnQH6E78GtRp3lhchupCJNw8t58.woff2 | Bin 0 -> 4556 bytes ...qsXbIeTHTrnQH6GQKuzMuncr0JB710wa2dPI.woff2 | Bin 0 -> 13716 bytes ...qsXbIeTHTrnQH6Lpx497t94oDua8KfAL9f-E.woff2 | Bin 0 -> 12196 bytes ...qsXbIeTHTrnQH6MAjkyiewWYrWZc50I8hK7I.woff2 | Bin 0 -> 13772 bytes ...qsXbIeTHTrnQH6OXKTZYPNtG1yMB_YJSqlic.woff2 | Bin 0 -> 12228 bytes ...mlt9b38dHJxOBGCOFnW3Jk0f09zW_Yln67Ac.woff2 | Bin 0 -> 13992 bytes ...mlt9b38dHJxOBGClYwVOhDRq2vbpGRTZ7bbs.woff2 | Bin 0 -> 4512 bytes ...mlt9b38dHJxOBGDRVvBvQIc1z78c__uoBcyI.woff2 | Bin 0 -> 12396 bytes ...mlt9b38dHJxOBGD_j0nMiB9fPhg_k1wdK2h0.woff2 | Bin 0 -> 4588 bytes ...mlt9b38dHJxOBGDovqjS_dXPZszO_XltPdNg.woff2 | Bin 0 -> 4432 bytes ...mlt9b38dHJxOBGEo0As1BFRXtCDhS66znb_k.woff2 | Bin 0 -> 13892 bytes ...mlt9b38dHJxOBGFKFh1TDTPrUZWzVp6FtpG8.woff2 | Bin 0 -> 12384 bytes ...mlt9b38dHJxOBGFxe-GPfKKFmiXaJ_Q0GFr8.woff2 | Bin 0 -> 12244 bytes ...mlt9b38dHJxOBGOode0-EuMkY--TSyExeINg.woff2 | Bin 0 -> 14308 bytes .../css/google-local/local.google.fonts.css | 168 ++ .../dist/css/skins/_all-skins.min.css | 1 + .../static/adminlte/dist/js/app.min.js | 13 + .../plugins/fastclick/fastclick.min.js | 1 + .../adminlte/plugins/iCheck/icheck.min.js | 10 + .../adminlte/plugins/iCheck/square/_all.css | 620 +++++ .../adminlte/plugins/iCheck/square/aero.css | 62 + .../adminlte/plugins/iCheck/square/aero.png | Bin 0 -> 2167 bytes .../plugins/iCheck/square/aero@2x.png | Bin 0 -> 4455 bytes .../adminlte/plugins/iCheck/square/blue.css | 62 + .../adminlte/plugins/iCheck/square/blue.png | Bin 0 -> 2185 bytes .../plugins/iCheck/square/blue@2x.png | Bin 0 -> 4485 bytes .../adminlte/plugins/iCheck/square/green.css | 62 + .../adminlte/plugins/iCheck/square/green.png | Bin 0 -> 2193 bytes .../plugins/iCheck/square/green@2x.png | Bin 0 -> 4498 bytes .../adminlte/plugins/iCheck/square/grey.css | 62 + .../adminlte/plugins/iCheck/square/grey.png | Bin 0 -> 2186 bytes .../plugins/iCheck/square/grey@2x.png | Bin 0 -> 4483 bytes .../adminlte/plugins/iCheck/square/orange.css | 62 + .../adminlte/plugins/iCheck/square/orange.png | Bin 0 -> 2181 bytes .../plugins/iCheck/square/orange@2x.png | Bin 0 -> 4474 bytes .../adminlte/plugins/iCheck/square/pink.css | 62 + .../adminlte/plugins/iCheck/square/pink.png | Bin 0 -> 2189 bytes .../plugins/iCheck/square/pink@2x.png | Bin 0 -> 4479 bytes .../adminlte/plugins/iCheck/square/purple.css | 62 + .../adminlte/plugins/iCheck/square/purple.png | Bin 0 -> 2188 bytes .../plugins/iCheck/square/purple@2x.png | Bin 0 -> 4501 bytes .../adminlte/plugins/iCheck/square/red.css | 62 + .../adminlte/plugins/iCheck/square/red.png | Bin 0 -> 2190 bytes .../adminlte/plugins/iCheck/square/red@2x.png | Bin 0 -> 4490 bytes .../adminlte/plugins/iCheck/square/square.css | 62 + .../adminlte/plugins/iCheck/square/square.png | Bin 0 -> 2175 bytes .../plugins/iCheck/square/square@2x.png | Bin 0 -> 4478 bytes .../adminlte/plugins/iCheck/square/yellow.css | 62 + .../adminlte/plugins/iCheck/square/yellow.png | Bin 0 -> 2131 bytes .../plugins/iCheck/square/yellow@2x.png | Bin 0 -> 4385 bytes .../plugins/jQuery/jquery-2.2.3.min.js | 4 + .../slimScroll/jquery.slimscroll.min.js | 16 + .../target/classes/static/js/common.1.js | 46 + .../target/classes/static/js/index.js | 3 + .../target/classes/static/js/login.1.js | 10 + .../css/font-awesome.css.map | 7 + .../css/font-awesome.min.css | 4 + .../font-awesome-4.5.0/fonts/FontAwesome.otf | Bin 0 -> 109688 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 70807 bytes .../fonts/fontawesome-webfont.svg | 655 +++++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 142072 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 83588 bytes .../fonts/fontawesome-webfont.woff2 | Bin 0 -> 66624 bytes .../ionicons-2.0.1/css/ionicons.min.css | 11 + .../plugins/ionicons-2.0.1/fonts/ionicons.eot | Bin 0 -> 120724 bytes .../plugins/ionicons-2.0.1/fonts/ionicons.svg | 2230 +++++++++++++++++ .../plugins/ionicons-2.0.1/fonts/ionicons.ttf | Bin 0 -> 188508 bytes .../ionicons-2.0.1/fonts/ionicons.woff | Bin 0 -> 67904 bytes .../templates/common/common.exception.ftl | 1 + .../classes/templates/common/common.macro.ftl | 96 + .../target/classes/templates/index.ftl | 49 + .../target/classes/templates/login.ftl | 55 + itools-sso/pom.xml | 28 +- itools-ums/pom.xml | 2 +- pom.xml | 6 +- 243 files changed, 14323 insertions(+), 21 deletions(-) create mode 100644 "itools-sso/doc/XXL-SSO\345\256\230\346\226\271\346\226\207\346\241\243.md" create mode 100644 "itools-sso/doc/XXL-SSO\346\236\266\346\236\204\345\233\276.pptx" create mode 100644 itools-sso/doc/images/img_01.png create mode 100644 itools-sso/itools-sso-core/pom.xml create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/conf/Conf.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/entity/ReturnT.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/exception/XxlSsoException.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/filter/XxlSsoTokenFilter.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/filter/XxlSsoWebFilter.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/login/SsoTokenLoginHelper.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/login/SsoWebLoginHelper.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/path/PathMatcher.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/path/impl/AntPathMatcher.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/store/SsoLoginStore.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/store/SsoSessionIdHelper.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/user/XxlSsoUser.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/CookieUtil.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/JedisUtil.java create mode 100644 itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/StringUtils.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/pom.xml create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/XxlClientApplication.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/config/XxlSsoConfig.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/controller/IndexController.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/resources/application.properties create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/resources/logback.xml create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/java/com/xxl/app/sample/test/TokenClientTest.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/java/com/xxl/app/sample/test/util/HttpClientUtil.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/resources/logback.xml create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/classes/application.properties create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/classes/logback.xml create mode 100644 itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/test-classes/logback.xml create mode 100644 itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/pom.xml create mode 100644 itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/XxlClientApplication.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/config/XxlSsoConfig.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/controller/IndexController.java create mode 100644 itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/application.properties create mode 100644 itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/logback.xml create mode 100644 itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/templates/index.ftl create mode 100644 itools-sso/itools-sso-samples/pom.xml create mode 100644 itools-sso/itools-sso-server/pom.xml create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/XxlSsoServerApplication.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/config/XxlSsoConfig.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/AppController.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/WebController.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/interceptor/MyWebMvcConfigurer.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/interceptor/PermissionInterceptor.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/resolver/WebExceptionResolver.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/core/model/UserInfo.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/core/result/ReturnT.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/service/UserService.java create mode 100644 itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/service/impl/UserServiceImpl.java create mode 100644 itools-sso/itools-sso-server/src/main/resources/application.properties create mode 100644 itools-sso/itools-sso-server/src/main/resources/logback.xml create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/css/bootstrap.css.map create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/css/bootstrap.min.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.eot create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.svg create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.ttf create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.woff create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/js/bootstrap.min.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/AdminLTE-local.min.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/AdminLTE.min.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/M2Jd71oPJhLKp0zdtTvoM40tgx99jmYGv_xzYuwd1rU.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/M2Jd71oPJhLKp0zdtTvoM7YHq4FgHI02B8rPccK0FJQ.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/M2Jd71oPJhLKp0zdtTvoMxgy2Fsj5sj3EzlXpqVXRKo.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/ODelI1aHBYDBqgeIAH2zlC2Q8seG17bfDXYR_jUsrzg.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/ODelI1aHBYDBqgeIAH2zlNOAHFN6BivSraYkjhveRHY.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/ODelI1aHBYDBqgeIAH2zlNOAHFN6BivSraYkjhveRHY[0].woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/ODelI1aHBYDBqgeIAH2zlNV_2ngZ8dMf8fLgjYEouxg.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6CzM2XYAq8cDhaXsrN8WXcA.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6E78GtRp3lhchupCJNw8t58.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6GQKuzMuncr0JB710wa2dPI.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6Lpx497t94oDua8KfAL9f-E.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6MAjkyiewWYrWZc50I8hK7I.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6OXKTZYPNtG1yMB_YJSqlic.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGCOFnW3Jk0f09zW_Yln67Ac.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGClYwVOhDRq2vbpGRTZ7bbs.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGDRVvBvQIc1z78c__uoBcyI.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGD_j0nMiB9fPhg_k1wdK2h0.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGDovqjS_dXPZszO_XltPdNg.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGEo0As1BFRXtCDhS66znb_k.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGFKFh1TDTPrUZWzVp6FtpG8.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGFxe-GPfKKFmiXaJ_Q0GFr8.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGOode0-EuMkY--TSyExeINg.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/google-local/local.google.fonts.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/css/skins/_all-skins.min.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/dist/js/app.min.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/fastclick/fastclick.min.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/icheck.min.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/_all.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/aero.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/aero.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/aero@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/blue.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/blue.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/blue@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/green.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/green.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/green@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/grey.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/grey.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/grey@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/orange.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/orange.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/orange@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/pink.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/pink.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/pink@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/purple.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/purple.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/purple@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/red.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/red.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/red@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/square.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/square.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/square@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/yellow.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/yellow.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/iCheck/square/yellow@2x.png create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/jQuery/jquery-2.2.3.min.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/adminlte/plugins/slimScroll/jquery.slimscroll.min.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/js/common.1.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/js/index.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/js/login.1.js create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/font-awesome-4.5.0/css/font-awesome.css.map create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/font-awesome-4.5.0/css/font-awesome.min.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/font-awesome-4.5.0/fonts/FontAwesome.otf create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.eot create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.svg create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.ttf create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.woff create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.woff2 create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/ionicons-2.0.1/css/ionicons.min.css create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/ionicons-2.0.1/fonts/ionicons.eot create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/ionicons-2.0.1/fonts/ionicons.svg create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/ionicons-2.0.1/fonts/ionicons.ttf create mode 100644 itools-sso/itools-sso-server/src/main/resources/static/plugins/ionicons-2.0.1/fonts/ionicons.woff create mode 100644 itools-sso/itools-sso-server/src/main/resources/templates/common/common.exception.ftl create mode 100644 itools-sso/itools-sso-server/src/main/resources/templates/common/common.macro.ftl create mode 100644 itools-sso/itools-sso-server/src/main/resources/templates/index.ftl create mode 100644 itools-sso/itools-sso-server/src/main/resources/templates/login.ftl create mode 100644 itools-sso/itools-sso-server/src/test/java/ApplicationTests.java create mode 100644 itools-sso/itools-sso-server/target/classes/application.properties create mode 100644 itools-sso/itools-sso-server/target/classes/logback.xml create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/bootstrap/css/bootstrap.css.map create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/bootstrap/css/bootstrap.min.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.eot create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.svg create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.ttf create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.woff create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/bootstrap/fonts/glyphicons-halflings-regular.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/bootstrap/js/bootstrap.min.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/AdminLTE-local.min.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/AdminLTE.min.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/M2Jd71oPJhLKp0zdtTvoM40tgx99jmYGv_xzYuwd1rU.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/M2Jd71oPJhLKp0zdtTvoM7YHq4FgHI02B8rPccK0FJQ.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/M2Jd71oPJhLKp0zdtTvoMxgy2Fsj5sj3EzlXpqVXRKo.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/ODelI1aHBYDBqgeIAH2zlC2Q8seG17bfDXYR_jUsrzg.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/ODelI1aHBYDBqgeIAH2zlNOAHFN6BivSraYkjhveRHY.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/ODelI1aHBYDBqgeIAH2zlNOAHFN6BivSraYkjhveRHY[0].woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/ODelI1aHBYDBqgeIAH2zlNV_2ngZ8dMf8fLgjYEouxg.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6CzM2XYAq8cDhaXsrN8WXcA.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6E78GtRp3lhchupCJNw8t58.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6GQKuzMuncr0JB710wa2dPI.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6Lpx497t94oDua8KfAL9f-E.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6MAjkyiewWYrWZc50I8hK7I.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/fpTVHK8qsXbIeTHTrnQH6OXKTZYPNtG1yMB_YJSqlic.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGCOFnW3Jk0f09zW_Yln67Ac.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGClYwVOhDRq2vbpGRTZ7bbs.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGDRVvBvQIc1z78c__uoBcyI.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGD_j0nMiB9fPhg_k1wdK2h0.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGDovqjS_dXPZszO_XltPdNg.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGEo0As1BFRXtCDhS66znb_k.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGFKFh1TDTPrUZWzVp6FtpG8.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGFxe-GPfKKFmiXaJ_Q0GFr8.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/fonts/toadOcfmlt9b38dHJxOBGOode0-EuMkY--TSyExeINg.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/google-local/local.google.fonts.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/css/skins/_all-skins.min.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/dist/js/app.min.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/fastclick/fastclick.min.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/icheck.min.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/_all.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/aero.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/aero.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/aero@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/blue.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/blue.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/blue@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/green.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/green.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/green@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/grey.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/grey.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/grey@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/orange.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/orange.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/orange@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/pink.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/pink.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/pink@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/purple.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/purple.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/purple@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/red.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/red.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/red@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/square.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/square.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/square@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/yellow.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/yellow.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/iCheck/square/yellow@2x.png create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/jQuery/jquery-2.2.3.min.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/adminlte/plugins/slimScroll/jquery.slimscroll.min.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/js/common.1.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/js/index.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/js/login.1.js create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/font-awesome-4.5.0/css/font-awesome.css.map create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/font-awesome-4.5.0/css/font-awesome.min.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/font-awesome-4.5.0/fonts/FontAwesome.otf create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.eot create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.svg create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.ttf create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.woff create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/font-awesome-4.5.0/fonts/fontawesome-webfont.woff2 create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/ionicons-2.0.1/css/ionicons.min.css create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/ionicons-2.0.1/fonts/ionicons.eot create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/ionicons-2.0.1/fonts/ionicons.svg create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/ionicons-2.0.1/fonts/ionicons.ttf create mode 100644 itools-sso/itools-sso-server/target/classes/static/plugins/ionicons-2.0.1/fonts/ionicons.woff create mode 100644 itools-sso/itools-sso-server/target/classes/templates/common/common.exception.ftl create mode 100644 itools-sso/itools-sso-server/target/classes/templates/common/common.macro.ftl create mode 100644 itools-sso/itools-sso-server/target/classes/templates/index.ftl create mode 100644 itools-sso/itools-sso-server/target/classes/templates/login.ftl diff --git a/itools-core/pom.xml b/itools-core/pom.xml index 932528c..1d8f4c6 100644 --- a/itools-core/pom.xml +++ b/itools-core/pom.xml @@ -2,13 +2,10 @@ - - itools-backend - com.itools.core - 1.0-SNAPSHOT - - 4.0.0 + 4.0.0 + com.itools.core + 1.0-SNAPSHOT itools-core pom 工具集成统一异常、分布式雪花算法、参数验证、日志、统一拦截等等 @@ -47,6 +44,13 @@ + + org.springframework.boot + spring-boot-starter-parent + ${spring-boot.version} + pom + import + org.springframework.cloud spring-cloud-dependencies diff --git a/itools-fms/pom.xml b/itools-fms/pom.xml index 89975b0..870bb4f 100644 --- a/itools-fms/pom.xml +++ b/itools-fms/pom.xml @@ -8,7 +8,7 @@ 1.0-SNAPSHOT 4.0.0 - + pom itools-fms diff --git a/itools-gms/pom.xml b/itools-gms/pom.xml index eef6669..6907651 100644 --- a/itools-gms/pom.xml +++ b/itools-gms/pom.xml @@ -8,7 +8,7 @@ 1.0-SNAPSHOT 4.0.0 - + pom itools-gms diff --git a/itools-oms/pom.xml b/itools-oms/pom.xml index 0f2830d..5357863 100644 --- a/itools-oms/pom.xml +++ b/itools-oms/pom.xml @@ -8,7 +8,7 @@ 1.0-SNAPSHOT 4.0.0 - + pom itools-oms diff --git "a/itools-sso/doc/XXL-SSO\345\256\230\346\226\271\346\226\207\346\241\243.md" "b/itools-sso/doc/XXL-SSO\345\256\230\346\226\271\346\226\207\346\241\243.md" new file mode 100644 index 0000000..506c9da --- /dev/null +++ "b/itools-sso/doc/XXL-SSO\345\256\230\346\226\271\346\226\207\346\241\243.md" @@ -0,0 +1,400 @@ +## 《分布式单点登录框架XXL-SSO》 + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-sso/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-sso/) +[![GitHub release](https://img.shields.io/github/release/xuxueli/xxl-sso.svg)](https://github.com/xuxueli/xxl-sso/releases) +[![License](https://img.shields.io/badge/license-GPLv3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0.html) +[![donate](https://img.shields.io/badge/%24-donate-ff69b4.svg?style=flat-square)](http://www.xuxueli.com/page/donate.html) + +## 一、简介 + +### 1.1 概述 +XXL-SSO 是一个分布式单点登录框架。只需要登录一次就可以访问所有相互信任的应用系统。 +拥有"轻量级、分布式、跨域、Cookie+Token均支持、Web+APP均支持"等特性;。现已开放源代码,开箱即用。 + +### 1.2 特性 +- 1、简洁:API直观简洁,可快速上手; +- 2、轻量级:环境依赖小,部署与接入成本较低; +- 3、单点登录:只需要登录一次就可以访问所有相互信任的应用系统。 +- 4、分布式:接入SSO认证中心的应用,支持分布式部署; +- 5、HA:Server端与Client端,均支持集群部署,提高系统可用性; +- 6、跨域:支持跨域应用接入SSO认证中心; +- 7、Cookie+Token均支持:支持基于Cookie和基于Token两种接入方式,并均提供Sample项目; +- 8、Web+APP均支持:支持Web和APP接入; +- 9、实时性:系统登陆、注销状态,全部Server与Client端实时共享; +- 10、CS结构:基于CS结构,包括Server"认证中心"与Client"受保护应用"; +- 11、记住密码:未记住密码时,关闭浏览器则登录态失效;记住密码时,支持登录态自动延期,在自定义延期时间的基础上,原则上可以无限延期; +- 12、路径排除:支持自定义多个排除路径,支持Ant表达式。用于排除SSO客户端不需要过滤的路径; + +### 1.3 下载 + +#### 文档地址 + +- [中文文档](http://www.xuxueli.com/xxl-sso/) + +#### 源码仓库地址 + +源码仓库地址 | Release Download +--- | --- +[https://github.com/xuxueli/xxl-sso](https://github.com/xuxueli/xxl-sso) | [Download](https://github.com/xuxueli/xxl-sso/releases) +[https://gitee.com/xuxueli0323/xxl-sso](https://gitee.com/xuxueli0323/xxl-sso) | [Download](https://gitee.com/xuxueli0323/xxl-sso/releases) + + +#### 技术交流 +- [社区交流](http://www.xuxueli.com/page/community.html) + +### 1.4 环境 +- JDK:1.7+ +- Redis:4.0+ +- Mysql:5.6+ + + +## 二、快速入门(基于Cookie) + +> 基于Cookie,相关概念可参考 "章节 4.6"; + + +### 2.1:系统数据库初始化 + + +### 2.2:源码编译 + +``` +- xxl-sso-server:中央认证服务,支持集群; +- xxl-sso-core:Client端依赖; +- xxl-sso-samples:单点登陆Client端接入示例项目; + - xxl-sso-web-sample-springboot:基于Cookie接入方式,供用户浏览器访问,springboot版本 + - xxl-sso-token-sample-springboot:基于Token接入方式,常用于无法使用Cookie的场景使用,如APP、Cookie被禁用等,springboot版本 +``` + +### 2.3 部署 "认证中心(SSO Server)" + +``` +项目名:xxl-sso-server +``` + +#### 配置说明 + +配置文件位置:application.properties +``` +…… + +// redis 地址: 如 "{ip}"、"{ip}:{port}"、"{redis/rediss}://xxl-sso:{password}@{ip}:{port:6379}/{db}";多地址逗号分隔 +xxl.sso.redis.address=redis://127.0.0.1:6379 + +// 登录态有效期窗口,默认24H,当登录态有效期窗口过半时,自动顺延一个周期; +xxl.sso.redis.expire.minite=1440 + +``` + +### 2.4 部署 "单点登陆Client端接入示例项目" + +``` +项目名:xxl-sso-web-sample-springboot +``` + +#### maven依赖 + +``` + + com.xuxueli + xxl-sso-core + ${最新稳定版} + +``` + +#### 配置 XxlSsoFilter + +参考代码:XxlSsoConfig +``` +@Bean +public FilterRegistrationBean xxlSsoFilterRegistration() { + + // xxl-sso, redis init + JedisUtil.init(xxlSsoRedisAddress); + + // xxl-sso, filter init + FilterRegistrationBean registration = new FilterRegistrationBean(); + + registration.setName("XxlSsoWebFilter"); + registration.setOrder(1); + registration.addUrlPatterns("/*"); + registration.setFilter(new XxlSsoWebFilter()); + registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer); + registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath); + + return registration; +} +``` + + +#### 配置说明 + +配置文件位置:application.properties +``` +…… + +### xxl-sso (CLient端SSO配置) + +##### SSO Server认证中心地址(推荐以域名方式配置认证中心,本机可参考章节"2.5"修改host文件配置域名指向) +xxl.sso.server=http://xxlssoserver.com:8080/xxl-sso-server + +##### 注销登陆path,值为Client端应用的相对路径 +xxl.sso.logout.path=/logout + +##### 路径排除Path,允许设置多个,且支持Ant表达式。用于排除SSO客户端不需要过滤的路径 +xxl-sso.excluded.paths= + +### redis // redis address, like "{ip}"、"{ip}:{port}"、"{redis/rediss}://xxl-sso:{password}@{ip}:{port:6379}/{db}";Multiple "," separated +xxl.sso.redis.address=redis://xxl-sso:password@127.0.0.1:6379/0 +``` + +### 2.5 验证 + +- 环境准备:启动Redis、初始化Mysql表数据; + +- 修改Host文件:域名方式访问认证中心,模拟跨域与线上真实环境 +``` +### 在host文件中添加以下内容0 +127.0.0.1 xxlssoserver.com +127.0.0.1 xxlssoclient1.com +127.0.0.1 xxlssoclient2.com +``` + +- 分别运行 "xxl-sso-server" 与 "xxl-sso-web-sample-springboot" + + + 1、SSO认证中心地址: + http://xxlssoserver.com:8080/xxl-sso-server + + 2、Client01应用地址: + http://xxlssoclient1.com:8081/xxl-sso-web-sample-springboot/ + + 3、Client02应用地址: + http://xxlssoclient2.com:8081/xxl-sso-web-sample-springboot/ + + +- SSO登录/注销流程验证 + + + 正常情况下,登录流程如下: + 1、访问 "Client01应用地址" ,将会自动 redirect 到 "SSO认证中心地址" 登录界面; + 2、成功登录后,将会自动 redirect 返回到 "Client01应用地址",并切换为已登录状态; + 3、此时,访问 "Client02应用地址",不需登陆将会自动切换为已登录状态; + + 正常情况下,注销流程如下: + 1、访问 "Client01应用地址" 配置的 "注销登陆path",将会自动 redirect 到 "SSO认证中心地址" 并自动注销登陆状态; + 2、此时,访问 "Client02应用地址",也将会自动注销登陆状态; + + + +## 三、快速入门(基于Token) + +> 基于Token,相关概念可参考 "章节 4.7";(在一些无法使用Cookie的场景下,可使用该方式,否则可以忽略本章节) + +### 3.1 "认证中心(SSO Server)" 搭建 +> 可参考 "章节二" 搭建; + +"认证中心" 搭建成功后,默认为Token方式登陆提供API接口如下: + +- 1、登陆接口:/app/login + - 参数:POST参数 + - username:账号 + - password:账号 + - 响应:JSON格式 + - code:200 表示成功、其他失败; + - msg:错误提示 + - data: 登陆用户的 sso sessionid + +- 2、注销接口:/app/logout + - 参数:POST参数 + - sessionId:登陆用户的 sso sessionid + - 响应:JSON格式 + - code:200 表示成功、其他失败; + - msg:错误提示 + +- 3、登陆状态校验接口:/app/logincheck + - 参数:POST参数 + - sessionId:登陆用户的 sso sessionid + - 响应:JSON格式 + - code:200 表示成功、其他失败; + - msg:错误提示 + - data:登陆用户信息 + - userid:用户ID + - username:用户名 + +### 2.2 部署 "单点登陆Client端接入示例项目" (Token方式) + +``` +项目名:xxl-sso-token-sample-springboot +``` + +> 可参考 "章节 2.4" 部署 "单点登陆Client端接入示例项目",唯一不同点是:将web应用的 "XxlSsoFilter" 更换为app应用 "XxlSsoTokenFilter"; + +### 2.3 验证 (模拟请求 Token 方式接入SSO的接口) + +- 环境准备:启动Redis、初始化Mysql表数据; + +- 修改Host文件:域名方式访问认证中心,模拟跨域与线上真实环境 +``` +### 在host文件中添加以下内容0 +127.0.0.1 xxlssoserver.com +127.0.0.1 xxlssoclient1.com +127.0.0.1 xxlssoclient2.com +``` + +- 分别运行 "xxl-sso-server" 与 "xxl-sso-token-sample-springboot" + + + 1、SSO认证中心地址: + http://xxlssoserver.com:8080/xxl-sso-server + + 2、Client01应用地址: + http://xxlssoclient1.com:8082/xxl-sso-token-sample-springboot/ + + 3、Client02应用地址: + http://xxlssoclient2.com:8082/xxl-sso-token-sample-springboot/ + + +- SSO登录/注销流程验证 +> 可参考测试用例 :com.xxl.app.sample.test.TokenClientTest + + + 正常情况下,登录流程如下: + 1、获取用户输入的账号密码后,请求SSO Server的登录接口,获取用户 sso sessionid ;(参考代码:TokenClientTest.loginTest) + 2、登陆成功后,获取到 sso sessionid ,需要主动存储,后续请求时需要设置在 Header参数 中; + 3、此时,使用 sso sessionid 访问受保护的 "Client01应用" 和 "Client02应用" 提供的接口,接口均正常返回;(参考代码:TokenClientTest.clientApiRequestTest) + + 正常情况下,注销流程如下: + 1、请求SSO Server的注销接口,注销登陆凭证 sso sessionid ;(参考代码:TokenClientTest.logoutTest) + 2、注销成功后,sso sessionid 将会全局失效; + 3、此时,使用 sso sessionid 访问受保护的 "Client01应用" 和 "Client02应用" 提供的接口,接口请求将会被拦截,提示未登录并返回状态码 501 ;(参考代码:TokenClientTest.clientApiRequestTest) + + +## 四、总体设计 + +### 4.1 架构图 + +![输入图片说明](https://raw.githubusercontent.com/xuxueli/xxl-sso/master/doc/images/img_01.png "在这里输入图片标题") + +### 4.2 功能定位 + +XXL-SSO 是一个分布式单点登录框架。只需要登录一次就可以访问所有相互信任的应用系统。 + +借助 XXL-SSO,可以快速实现分布式系统单点登录。 + +### 4.3 核心概念 + +概念 | 说明 +--- | --- +SSO Server | 中央认证服务,支持集群; +SSO Client | 接入SSO认证中心的Client应用; +SSO SessionId | 登录用户会话ID,SSO 登录成功为用户自动分配; +SSO User | 登录用户信息,与 SSO SessionId 相对应; + +### 4.4 登录流程剖析 + +- 用户于Client端应用访问受限资源时,将会自动 redirect 到 SSO Server 进入统一登录界面。 +- 用户登录成功之后将会为用户分配 SSO SessionId 并 redirect 返回来源Client端应用,同时附带分配的 SSO SessionId。 +- 在Client端的SSO Filter里验证 SSO SessionId 无误,将 SSO SessionId 写入到用户浏览器Client端域名下 cookie 中。 +- SSO Filter验证 SSO SessionId 通过,受限资源请求放行; + +### 4.5 注销流程剖析 + +- 用户与Client端应用请求注销Path时,将会 redirect 到 SSO Server 自动销毁全局 SSO SessionId,实现全局销毁; +- 然后,访问接入SSO保护的任意Client端应用时,SSO Filter 均会拦截请求并 redirect 到 SSO Server 的统一登录界面。 + +### 4.6 基于Cookie,相关感念 + +- 登陆凭证存储:登陆成功后,用户登陆凭证被自动存储在浏览器Cookie中; +- Client端校验登陆状态:通过校验请求Cookie中的是否包含用户登录凭证判断; +- 系统角色模型: + - SSO Server:认证中心,提供用户登陆、注销以及登陆状态校验等功能。 + - Client应用:受SSO保护的Client端Web应用,为用户浏览器访问提供服务; + - 用户:发起请求的用户,使用浏览器访问。 + + +### 4.7 基于Token,相关感念 + +- 登陆凭证存储:登陆成功后,获取到登录凭证(xxl_sso_sessionid=xxx),需要主动存储,如存储在 localStorage、Sqlite 中; +- Client端校验登陆状态:通过校验请求 Header参数 中的是否包含用户登录凭证(xxl_sso_sessionid=xxx)判断;因此,发送请求时需要在 Header参数 中设置登陆凭证; +- 系统角色模型: + - SSO Server:认证中心,提供用户登陆、注销以及登陆状态校验等功能。 + - Client应用:受SSO保护的Client端Web应用,为用户请求提供接口服务; + - 用户:发起请求的用户,如使用Android、IOS、桌面客户端等请求访问。 + +### 4.8 未登录状态请求处理 + +基于Cookie,未登录状态请求: +- 页面请求:redirect 到SSO Server登录界面; +- JSON请求:返回未登录的JSON格式响应数据 + - 数据格式: + - code:501 错误码 + - msg:sso not login. + +基于Token,未登录状态请求: +- 返回未登录的JSON格式响应数据 + - 数据格式: + - code:501 错误码 + - msg:sso not login. + + +### 4.9 登录态自动延期 +支持自定义登录态有效期窗口,默认24H,当登录态有效期窗口过半时,自动顺延一个周期; + +### 4.10 记住密码 +未记住密码时,关闭浏览器则登录态失效;记住密码时,登录态自动延期,在自定义延期时间的基础上,原则上可以无限延期; + +### 4.11 路径排除 +自定义路径排除Path,允许设置多个,且支持Ant表达式。用于排除SSO客户端不需要过滤的路径 + + +## 五、版本更新日志 + +### 5.1 版本 v0.1.0,新特性[2018-04-04] +- 1、简洁:API直观简洁,可快速上手; +- 2、轻量级:环境依赖小,部署与接入成本较低; +- 3、单点登录:只需要登录一次就可以访问所有相互信任的应用系统。 +- 4、分布式:接入SSO认证中心的应用,支持分布式部署; +- 5、HA:Server端与Client端,均支持集群部署,提高系统可用性; +- 6、实时性:系统登陆、注销状态,全部Server与Client端实时共享; +- 7、CS结构:基于CS结构,包括Server"认证中心"与Client"受保护应用"; +- 8、跨域:支持跨域应用接入SSO认证中心; + +### 5.2 版本 v1.1.0 Release Notes [2018-11-06] +- 1、Redis配置方式增强,支持自定义DB、密码、IP、PORT等等;; +- 2、Token接入方式;除了常规Cookie方式外,新增Token接入方式,并提供Sample项目; +- 3、登录态自动延期:支持自定义登录态有效期窗口,默认24H,当登录态有效期窗口过半时,自动顺延一个周期; +- 4、"记住密码" 功能优化:未记住密码时,关闭浏览器则登录态失效;记住密码时,登录态自动延期,在自定义延期时间的基础上,原则上可以无限延期; +- 5、sessionId数据结构优化,进一步提升暴露破解难度; +- 6、认证数据存储结构调整,避免登陆信息存储冗余; +- 7、认证中心用户登录校验改为Mock数据方式,取消对DB强依赖,降低部署难度; +- 8、Client端依赖Core包,slf4j依赖优化,移除log4j强依赖; +- 9、Ajax请求未登录处理逻辑优化,返回JSON格式提示数据; +- 10、项目结构梳理,清理冗余依赖,升级多项依赖版本至较近版本; +- 11、路径排除:新增自定义属性 "excludedPaths",允许设置多个,且支持Ant表达式。用于排除SSO客户端不需要过滤的路径 + +### TODO LIST +- 1、认证中心与接入端交互数据加密,增强安全性;redirect_url必须和临时AccessToken配合才会生效,AccessToken有效期60s; +- 2、SSO SessionId 与IP绑定,增强用户增强安全性; +- 3、支持认证分组,分组内共享登陆状态,分组之间登录态隔离;待考虑; +- 4、客户端新增属性 "xxl.sso.server",用于构建跳转连接,防止跳转第三方导致登陆漏洞; + + + +## 六、其他 + +### 6.1 项目贡献 +欢迎参与项目贡献!比如提交PR修复一个bug,或者新建 [Issue](https://github.com/xuxueli/xxl-sso/issues/) 讨论新特性或者变更。 + +### 6.2 用户接入登记 +更多接入的公司,欢迎在 [登记地址](https://github.com/xuxueli/xxl-sso/issues/1 ) 登记,登记仅仅为了产品推广。 + +### 6.3 开源协议和版权 +产品开源免费,并且将持续提供免费的社区技术支持。个人或企业内部可自由的接入和使用。 + +- Licensed under the GNU General Public License (GPL) v3. +- Copyright (c) 2015-present, xuxueli. + +--- +### 捐赠 +无论金额多少都足够表达您这份心意,非常感谢 :) [前往捐赠](http://www.xuxueli.com/page/donate.html ) diff --git "a/itools-sso/doc/XXL-SSO\346\236\266\346\236\204\345\233\276.pptx" "b/itools-sso/doc/XXL-SSO\346\236\266\346\236\204\345\233\276.pptx" new file mode 100644 index 0000000000000000000000000000000000000000..3331f736e931ae3ebec63ba03ebd61deba2548bc GIT binary patch literal 45185 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 Hz4PrCNaW%4 literal 0 HcmV?d00001 diff --git a/itools-sso/doc/images/img_01.png b/itools-sso/doc/images/img_01.png new file mode 100644 index 0000000000000000000000000000000000000000..c8a37085d83e83ed3d87f0167cff77c996056f61 GIT binary patch literal 176414 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
  • $^Fcs-Z`g{OwS0(Qt)zLT+ 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 literal 0 HcmV?d00001 diff --git a/itools-sso/itools-sso-core/pom.xml b/itools-sso/itools-sso-core/pom.xml new file mode 100644 index 0000000..f0d98df --- /dev/null +++ b/itools-sso/itools-sso-core/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + itools-sso + com.itools.core + 1.0-SNAPSHOT + + xxl-sso-core + jar + + + + + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + + + + + org.slf4j + slf4j-api + ${slf4j-api.version} + + + + + redis.clients + jedis + ${jedis.version} + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/conf/Conf.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/conf/Conf.java new file mode 100644 index 0000000..45889a1 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/conf/Conf.java @@ -0,0 +1,61 @@ +package com.itools.sso.core.conf; + +import com.itools.sso.core.entity.ReturnT; + +/** + * conf + * + * @author xuxueli 2018-04-02 19:18:04 + */ +public class Conf { + + /** + * sso sessionid, between browser and sso-server (web + token client) + */ + public static final String SSO_SESSIONID = "xxl_sso_sessionid"; + + + /** + * redirect url (web client) + */ + public static final String REDIRECT_URL = "redirect_url"; + + /** + * sso user, request attribute (web client) + */ + public static final String SSO_USER = "xxl_sso_user"; + + + /** + * sso server address (web + token client) + */ + public static final String SSO_SERVER = "sso_server"; + + /** + * login url, server relative path (web client) + */ + public static final String SSO_LOGIN = "/login"; + /** + * logout url, server relative path (web client) + */ + public static final String SSO_LOGOUT = "/logout"; + + + /** + * logout path, client relatice path + */ + public static final String SSO_LOGOUT_PATH = "SSO_LOGOUT_PATH"; + + /** + * excluded paths, client relatice path, include path can be set by "filter-mapping" + */ + public static final String SSO_EXCLUDED_PATHS = "SSO_EXCLUDED_PATHS"; + + + /** + * login fail result + */ + public static final ReturnT SSO_LOGIN_FAIL_RESULT = new ReturnT(501, "sso not login."); + + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/entity/ReturnT.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/entity/ReturnT.java new file mode 100644 index 0000000..1c8031e --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/entity/ReturnT.java @@ -0,0 +1,51 @@ +package com.itools.sso.core.entity; + +import java.io.Serializable; + +/** + * common return + * + * @author xuxueli 2015-12-4 16:32:31 + * @param + */ +public class ReturnT implements Serializable { + public static final long serialVersionUID = 42L; + + public static final int SUCCESS_CODE = 200; + public static final int FAIL_CODE = 500; + public static final ReturnT SUCCESS = new ReturnT(null); + public static final ReturnT FAIL = new ReturnT(FAIL_CODE, null); + + private int code; + private String msg; + private T data; + + public ReturnT(int code, String msg) { + this.code = code; + this.msg = msg; + } + public ReturnT(T data) { + this.code = SUCCESS_CODE; + this.data = data; + } + + public int getCode() { + return code; + } + public void setCode(int code) { + this.code = code; + } + public String getMsg() { + return msg; + } + public void setMsg(String msg) { + this.msg = msg; + } + public T getData() { + return data; + } + public void setData(T data) { + this.data = data; + } + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/exception/XxlSsoException.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/exception/XxlSsoException.java new file mode 100644 index 0000000..fe201a0 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/exception/XxlSsoException.java @@ -0,0 +1,22 @@ +package com.itools.sso.core.exception; + +/** + * @author xuxueli 2018-04-02 21:01:41 + */ +public class XxlSsoException extends RuntimeException { + + private static final long serialVersionUID = 42L; + + public XxlSsoException(String msg) { + super(msg); + } + + public XxlSsoException(String msg, Throwable cause) { + super(msg, cause); + } + + public XxlSsoException(Throwable cause) { + super(cause); + } + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/filter/XxlSsoTokenFilter.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/filter/XxlSsoTokenFilter.java new file mode 100644 index 0000000..826e19c --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/filter/XxlSsoTokenFilter.java @@ -0,0 +1,101 @@ +package com.itools.sso.core.filter; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.entity.ReturnT; +import com.itools.sso.core.login.SsoTokenLoginHelper; +import com.itools.sso.core.path.impl.AntPathMatcher; +import com.itools.sso.core.user.XxlSsoUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.*; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * app sso filter + * + * @author xuxueli 2018-04-08 21:30:54 + */ +public class XxlSsoTokenFilter extends HttpServlet implements Filter { + private static Logger logger = LoggerFactory.getLogger(XxlSsoTokenFilter.class); + + private static final AntPathMatcher antPathMatcher = new AntPathMatcher(); + + private String ssoServer; + private String logoutPath; + private String excludedPaths; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + ssoServer = filterConfig.getInitParameter(Conf.SSO_SERVER); + logoutPath = filterConfig.getInitParameter(Conf.SSO_LOGOUT_PATH); + excludedPaths = filterConfig.getInitParameter(Conf.SSO_EXCLUDED_PATHS); + + logger.info("XxlSsoTokenFilter init."); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse res = (HttpServletResponse) response; + + // make url + String servletPath = req.getServletPath(); + + // excluded path check + if (excludedPaths!=null && excludedPaths.trim().length()>0) { + for (String excludedPath:excludedPaths.split(",")) { + String uriPattern = excludedPath.trim(); + + // 支持ANT表达式 + if (antPathMatcher.match(uriPattern, servletPath)) { + // excluded path, allow + chain.doFilter(request, response); + return; + } + + } + } + + // logout filter + if (logoutPath!=null + && logoutPath.trim().length()>0 + && logoutPath.equals(servletPath)) { + + // logout + SsoTokenLoginHelper.logout(req); + + // response + res.setStatus(HttpServletResponse.SC_OK); + res.setContentType("application/json;charset=UTF-8"); + res.getWriter().println("{\"code\":"+ ReturnT.SUCCESS_CODE+", \"msg\":\"\"}"); + + return; + } + + // login filter + XxlSsoUser xxlUser = SsoTokenLoginHelper.loginCheck(req); + if (xxlUser == null) { + + // response + res.setStatus(HttpServletResponse.SC_OK); + res.setContentType("application/json;charset=UTF-8"); + res.getWriter().println("{\"code\":"+Conf.SSO_LOGIN_FAIL_RESULT.getCode()+", \"msg\":\""+ Conf.SSO_LOGIN_FAIL_RESULT.getMsg() +"\"}"); + return; + } + + // ser sso user + request.setAttribute(Conf.SSO_USER, xxlUser); + + + // already login, allow + chain.doFilter(request, response); + return; + } + + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/filter/XxlSsoWebFilter.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/filter/XxlSsoWebFilter.java new file mode 100644 index 0000000..42b78b1 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/filter/XxlSsoWebFilter.java @@ -0,0 +1,116 @@ +package com.itools.sso.core.filter; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.login.SsoWebLoginHelper; +import com.itools.sso.core.path.impl.AntPathMatcher; +import com.itools.sso.core.user.XxlSsoUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.*; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * web sso filter + * + * @author xuxueli 2018-04-03 + */ +public class XxlSsoWebFilter extends HttpServlet implements Filter { + private static Logger logger = LoggerFactory.getLogger(XxlSsoWebFilter.class); + + private static final AntPathMatcher antPathMatcher = new AntPathMatcher(); + + private String ssoServer; + private String logoutPath; + private String excludedPaths; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + ssoServer = filterConfig.getInitParameter(Conf.SSO_SERVER); + logoutPath = filterConfig.getInitParameter(Conf.SSO_LOGOUT_PATH); + excludedPaths = filterConfig.getInitParameter(Conf.SSO_EXCLUDED_PATHS); + + logger.info("XxlSsoWebFilter init."); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse res = (HttpServletResponse) response; + + // make url + String servletPath = req.getServletPath(); + + // excluded path check + if (excludedPaths!=null && excludedPaths.trim().length()>0) { + for (String excludedPath:excludedPaths.split(",")) { + String uriPattern = excludedPath.trim(); + + // 支持ANT表达式 + if (antPathMatcher.match(uriPattern, servletPath)) { + // excluded path, allow + chain.doFilter(request, response); + return; + } + + } + } + + // logout path check + if (logoutPath!=null + && logoutPath.trim().length()>0 + && logoutPath.equals(servletPath)) { + + // remove cookie + SsoWebLoginHelper.removeSessionIdByCookie(req, res); + + // redirect logout + String logoutPageUrl = ssoServer.concat(Conf.SSO_LOGOUT); + res.sendRedirect(logoutPageUrl); + + return; + } + + // valid login user, cookie + redirect + XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(req, res); + + // valid login fail + if (xxlUser == null) { + + String header = req.getHeader("content-type"); + boolean isJson= header!=null && header.contains("json"); + if (isJson) { + + // json msg + res.setContentType("application/json;charset=utf-8"); + res.getWriter().println("{\"code\":"+Conf.SSO_LOGIN_FAIL_RESULT.getCode()+", \"msg\":\""+ Conf.SSO_LOGIN_FAIL_RESULT.getMsg() +"\"}"); + return; + } else { + + // total link + String link = req.getRequestURL().toString(); + + // redirect logout + String loginPageUrl = ssoServer.concat(Conf.SSO_LOGIN) + + "?" + Conf.REDIRECT_URL + "=" + link; + + res.sendRedirect(loginPageUrl); + return; + } + + } + + // ser sso user + request.setAttribute(Conf.SSO_USER, xxlUser); + + + // already login, allow + chain.doFilter(request, response); + return; + } + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/login/SsoTokenLoginHelper.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/login/SsoTokenLoginHelper.java new file mode 100644 index 0000000..e320072 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/login/SsoTokenLoginHelper.java @@ -0,0 +1,99 @@ +package com.itools.sso.core.login; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.store.SsoLoginStore; +import com.itools.sso.core.user.XxlSsoUser; +import com.itools.sso.core.store.SsoSessionIdHelper; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author xuxueli 2018-11-15 15:54:40 + */ +public class SsoTokenLoginHelper { + + /** + * client login + * + * @param sessionId + * @param xxlUser + */ + public static void login(String sessionId, XxlSsoUser xxlUser) { + + String storeKey = SsoSessionIdHelper.parseStoreKey(sessionId); + if (storeKey == null) { + throw new RuntimeException("parseStoreKey Fail, sessionId:" + sessionId); + } + + SsoLoginStore.put(storeKey, xxlUser); + } + + /** + * client logout + * + * @param sessionId + */ + public static void logout(String sessionId) { + + String storeKey = SsoSessionIdHelper.parseStoreKey(sessionId); + if (storeKey == null) { + return; + } + + SsoLoginStore.remove(storeKey); + } + /** + * client logout + * + * @param request + */ + public static void logout(HttpServletRequest request) { + String headerSessionId = request.getHeader(Conf.SSO_SESSIONID); + logout(headerSessionId); + } + + + /** + * login check + * + * @param sessionId + * @return + */ + public static XxlSsoUser loginCheck(String sessionId){ + + String storeKey = SsoSessionIdHelper.parseStoreKey(sessionId); + if (storeKey == null) { + return null; + } + + XxlSsoUser xxlUser = SsoLoginStore.get(storeKey); + if (xxlUser != null) { + String version = SsoSessionIdHelper.parseVersion(sessionId); + if (xxlUser.getVersion().equals(version)) { + + // After the expiration time has passed half, Auto refresh + if ((System.currentTimeMillis() - xxlUser.getExpireFreshTime()) > xxlUser.getExpireMinite()/2) { + xxlUser.setExpireFreshTime(System.currentTimeMillis()); + SsoLoginStore.put(storeKey, xxlUser); + } + + return xxlUser; + } + } + return null; + } + + + /** + * login check + * + * @param request + * @return + */ + public static XxlSsoUser loginCheck(HttpServletRequest request){ + String headerSessionId = request.getHeader(Conf.SSO_SESSIONID); + return loginCheck(headerSessionId); + } + + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/login/SsoWebLoginHelper.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/login/SsoWebLoginHelper.java new file mode 100644 index 0000000..8021215 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/login/SsoWebLoginHelper.java @@ -0,0 +1,119 @@ +package com.itools.sso.core.login; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.store.SsoLoginStore; +import com.itools.sso.core.user.XxlSsoUser; +import com.itools.sso.core.util.CookieUtil; +import com.itools.sso.core.store.SsoSessionIdHelper; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author xuxueli 2018-04-03 + */ +public class SsoWebLoginHelper { + + /** + * client login + * + * @param response + * @param sessionId + * @param ifRemember true: cookie not expire, false: expire when browser close (server cookie) + * @param xxlUser + */ + public static void login(HttpServletResponse response, + String sessionId, + XxlSsoUser xxlUser, + boolean ifRemember) { + + String storeKey = SsoSessionIdHelper.parseStoreKey(sessionId); + if (storeKey == null) { + throw new RuntimeException("parseStoreKey Fail, sessionId:" + sessionId); + } + + SsoLoginStore.put(storeKey, xxlUser); + CookieUtil.set(response, Conf.SSO_SESSIONID, sessionId, ifRemember); + } + + /** + * client logout + * + * @param request + * @param response + */ + public static void logout(HttpServletRequest request, + HttpServletResponse response) { + + String cookieSessionId = CookieUtil.getValue(request, Conf.SSO_SESSIONID); + if (cookieSessionId==null) { + return; + } + + String storeKey = SsoSessionIdHelper.parseStoreKey(cookieSessionId); + if (storeKey != null) { + SsoLoginStore.remove(storeKey); + } + + CookieUtil.remove(request, response, Conf.SSO_SESSIONID); + } + + + + /** + * login check + * + * @param request + * @param response + * @return + */ + public static XxlSsoUser loginCheck(HttpServletRequest request, HttpServletResponse response){ + + String cookieSessionId = CookieUtil.getValue(request, Conf.SSO_SESSIONID); + + // cookie user + XxlSsoUser xxlUser = SsoTokenLoginHelper.loginCheck(cookieSessionId); + if (xxlUser != null) { + return xxlUser; + } + + // redirect user + + // remove old cookie + SsoWebLoginHelper.removeSessionIdByCookie(request, response); + + // set new cookie + String paramSessionId = request.getParameter(Conf.SSO_SESSIONID); + xxlUser = SsoTokenLoginHelper.loginCheck(paramSessionId); + if (xxlUser != null) { + CookieUtil.set(response, Conf.SSO_SESSIONID, paramSessionId, false); // expire when browser close (client cookie) + return xxlUser; + } + + return null; + } + + + /** + * client logout, cookie only + * + * @param request + * @param response + */ + public static void removeSessionIdByCookie(HttpServletRequest request, HttpServletResponse response) { + CookieUtil.remove(request, response, Conf.SSO_SESSIONID); + } + + /** + * get sessionid by cookie + * + * @param request + * @return + */ + public static String getSessionIdByCookie(HttpServletRequest request) { + String cookieSessionId = CookieUtil.getValue(request, Conf.SSO_SESSIONID); + return cookieSessionId; + } + + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/path/PathMatcher.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/path/PathMatcher.java new file mode 100644 index 0000000..76ceadd --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/path/PathMatcher.java @@ -0,0 +1,106 @@ +package com.itools.sso.core.path; + +import com.itools.sso.core.path.impl.AntPathMatcher; + +import java.util.Comparator; +import java.util.Map; + +/** + * Strategy interface for {@code String}-based path matching. + * + *

    The default implementation is {@link AntPathMatcher}, supporting the Ant-style pattern syntax. (borrowed from spring) + */ +public interface PathMatcher { + + /** + * Does the given {@code path} represent a pattern that can be matched by an implementation of this interface? + * + *

    If the return value is {@code false}, then the {@link #match} + * method does not have to be used because direct equality comparisons + * on the static path Strings will lead to the same result. + * + * @param path the path String to check + * @return {@code true} if the given {@code path} represents a pattern + */ + boolean isPattern(String path); + + /** + * Match the given {@code path} against the given {@code pattern}, according to this PathMatcher's matching strategy. + * + * @param pattern the pattern to match against + * @param path the path String to test + * @return {@code true} if the supplied {@code path} matched, + * {@code false} if it didn't + */ + boolean match(String pattern, String path); + + /** + * Match the given {@code path} against the corresponding part of the given {@code pattern}, according to this PathMatcher's matching strategy. + * + *

    Determines whether the pattern at least matches as far as the given base path goes, assuming that a full path may then match as well. + * + * @param pattern the pattern to match against + * @param path the path String to test + * @return {@code true} if the supplied {@code path} matched, + * {@code false} if it didn't + */ + boolean matchStart(String pattern, String path); + + /** + * Given a pattern and a full path, determine the pattern-mapped part. + * + *

    This method is supposed to find out which part of the path is matched dynamically through an actual pattern, + * that is, it strips off a statically defined leading path from the given full path, + * returning only the actually pattern-matched part of the path. + * + *

    For example: For "myroot/*.html" as pattern and "myroot/myfile.html" as full path, this method should return "myfile.html". + * The detailed determination rules are specified to this PathMatcher's matching strategy. + * + *

    A simple implementation may return the given full path as-is in case of an actual pattern, + * and the empty String in case of the pattern not containing any dynamic parts (i.e. the {@code pattern} parameter being + * a static path that wouldn't qualify as an actual {@link #isPattern pattern}). + * A sophisticated implementation will differentiate between the static parts and the dynamic parts of the given path pattern. + * + * @param pattern the path pattern + * @param path the full path to introspect + * @return the pattern-mapped part of the given {@code path} + * (never {@code null}) + */ + String extractPathWithinPattern(String pattern, String path); + + /** + * Given a pattern and a full path, extract the URI template variables. URI template variables are expressed through curly brackets ('{' and '}'). + * + *

    For example: For pattern "/hotels/{hotel}" and path "/hotels/1", this method will return a map containing "hotel"->"1". + * + * @param pattern the path pattern, possibly containing URI templates + * @param path the full path to extract template variables from + * @return a map, containing variable names as keys; variables values as values + */ + Map extractUriTemplateVariables(String pattern, String path); + + /** + * Given a full path, returns a {@link Comparator} suitable for sorting patterns in order of explicitness for that path. + * + *

    The full algorithm used depends on the underlying implementation, but generally, + * the returned {@code Comparator} will {@linkplain java.util.Collections#sort(java.util.List, java.util.Comparator) sort} + * a list so that more specific patterns come before generic patterns. + * + * @param path the full path to use for comparison + * @return a comparator capable of sorting patterns in order of explicitness + */ + Comparator getPatternComparator(String path); + + /** + * Combines two patterns into a new pattern that is returned. + * + *

    The full algorithm used for combining the two pattern depends on the underlying implementation. + * + * @param pattern1 the first pattern + * @param pattern2 the second pattern + * @return the combination of the two patterns + * @throws IllegalArgumentException when the two patterns cannot be combined + */ + String combine(String pattern1, String pattern2); + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/path/impl/AntPathMatcher.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/path/impl/AntPathMatcher.java new file mode 100644 index 0000000..88c3b45 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/path/impl/AntPathMatcher.java @@ -0,0 +1,881 @@ +package com.itools.sso.core.path.impl; + +import com.itools.sso.core.path.PathMatcher; +import com.itools.sso.core.util.StringUtils; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * {@link PathMatcher} implementation for Ant-style path patterns. + * + *

    The mapping matches URLs using the following rules:
    + * + *

      + *
    • {@code ?} matches one character
    • + *
    • {@code *} matches zero or more characters
    • + *
    • {@code **} matches zero or more directories in a path
    • + *
    • {@code {spring:[a-z]+}} matches the regexp {@code [a-z]+} as a path variable named "spring"
    • + *
    + * + *

    Examples

    + *
      + *
    • {@code com/t?st.jsp} — matches {@code com/test.jsp} but also {@code com/tast.jsp} or {@code com/txst.jsp}
    • + *
    • {@code com/*.jsp} — matches all {@code .jsp} files in the {@code com} directory
    • + *
    • com/**/test.jsp — matches all {@code test.jsp} files underneath the {@code com} path
    • + *
    • org/springframework/**/*.jsp — matches all {@code .jsp} files underneath the {@code org/springframework} path
    • + *
    • org/**/servlet/bla.jsp — matches {@code org/springframework/servlet/bla.jsp} but also + * {@code org/springframework/testing/servlet/bla.jsp} and {@code org/servlet/bla.jsp}
    • + *
    • {@code com/{filename:\\w+}.jsp} will match {@code com/test.jsp} and assign the value {@code test} to the {@code filename} variable
    • + *
    + * + *

    Note: a pattern and a path must both be absolute or must both be relative in order for the two to match. + * Therefore it is recommended that users of this implementation to sanitize patterns + * in order to prefix them with "/" as it makes sense in the context in which they're used. + */ +public class AntPathMatcher implements PathMatcher { + + /** Default path separator: "/" */ + public static final String DEFAULT_PATH_SEPARATOR = "/"; + + private static final int CACHE_TURNOFF_THRESHOLD = 65536; + + private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{[^/]+?\\}"); + + private static final char[] WILDCARD_CHARS = { '*', '?', '{' }; + + + private String pathSeparator; + + private PathSeparatorPatternCache pathSeparatorPatternCache; + + private boolean caseSensitive = true; + + private boolean trimTokens = false; + + private volatile Boolean cachePatterns; + + private final Map tokenizedPatternCache = new ConcurrentHashMap(256); + + final Map stringMatcherCache = new ConcurrentHashMap(256); + + + /** + * Create a new instance with the {@link #DEFAULT_PATH_SEPARATOR}. + */ + public AntPathMatcher() { + this.pathSeparator = DEFAULT_PATH_SEPARATOR; + this.pathSeparatorPatternCache = new PathSeparatorPatternCache(DEFAULT_PATH_SEPARATOR); + } + + /** + * A convenient, alternative constructor to use with a custom path separator. + * @param pathSeparator the path separator to use, must not be {@code null}. + * @since 4.1 + */ + public AntPathMatcher(String pathSeparator) { + if (pathSeparator == null) { + throw new IllegalArgumentException("'pathSeparator' is required"); + } + + this.pathSeparator = pathSeparator; + this.pathSeparatorPatternCache = new PathSeparatorPatternCache(pathSeparator); + } + + + /** + * Set the path separator to use for pattern parsing. + *

    Default is "/", as in Ant. + */ + public void setPathSeparator(String pathSeparator) { + this.pathSeparator = (pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR); + this.pathSeparatorPatternCache = new PathSeparatorPatternCache(this.pathSeparator); + } + + /** + * Specify whether to perform pattern matching in a case-sensitive fashion. + *

    Default is {@code true}. Switch this to {@code false} for case-insensitive matching. + * @since 4.2 + */ + public void setCaseSensitive(boolean caseSensitive) { + this.caseSensitive = caseSensitive; + } + + /** + * Specify whether to trim tokenized paths and patterns. + *

    Default is {@code false}. + */ + public void setTrimTokens(boolean trimTokens) { + this.trimTokens = trimTokens; + } + + /** + * Specify whether to cache parsed pattern metadata for patterns passed + * into this matcher's {@link #match} method. A value of {@code true} + * activates an unlimited pattern cache; a value of {@code false} turns + * the pattern cache off completely. + *

    Default is for the cache to be on, but with the variant to automatically + * turn it off when encountering too many patterns to cache at runtime + * (the threshold is 65536), assuming that arbitrary permutations of patterns + * are coming in, with little chance for encountering a recurring pattern. + * @since 4.0.1 + * @see #getStringMatcher(String) + */ + public void setCachePatterns(boolean cachePatterns) { + this.cachePatterns = cachePatterns; + } + + private void deactivatePatternCache() { + this.cachePatterns = false; + this.tokenizedPatternCache.clear(); + this.stringMatcherCache.clear(); + } + + + @Override + public boolean isPattern(String path) { + return (path.indexOf('*') != -1 || path.indexOf('?') != -1); + } + + @Override + public boolean match(String pattern, String path) { + return doMatch(pattern, path, true, null); + } + + @Override + public boolean matchStart(String pattern, String path) { + return doMatch(pattern, path, false, null); + } + + /** + * Actually match the given {@code path} against the given {@code pattern}. + * @param pattern the pattern to match against + * @param path the path String to test + * @param fullMatch whether a full pattern match is required (else a pattern match + * as far as the given base path goes is sufficient) + * @return {@code true} if the supplied {@code path} matched, {@code false} if it didn't + */ + protected boolean doMatch(String pattern, String path, boolean fullMatch, Map uriTemplateVariables) { + if (path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) { + return false; + } + + String[] pattDirs = tokenizePattern(pattern); + if (fullMatch && this.caseSensitive && !isPotentialMatch(path, pattDirs)) { + return false; + } + + String[] pathDirs = tokenizePath(path); + + int pattIdxStart = 0; + int pattIdxEnd = pattDirs.length - 1; + int pathIdxStart = 0; + int pathIdxEnd = pathDirs.length - 1; + + // Match all elements up to the first ** + while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) { + String pattDir = pattDirs[pattIdxStart]; + if ("**".equals(pattDir)) { + break; + } + if (!matchStrings(pattDir, pathDirs[pathIdxStart], uriTemplateVariables)) { + return false; + } + pattIdxStart++; + pathIdxStart++; + } + + if (pathIdxStart > pathIdxEnd) { + // Path is exhausted, only match if rest of pattern is * or **'s + if (pattIdxStart > pattIdxEnd) { + return (pattern.endsWith(this.pathSeparator) == path.endsWith(this.pathSeparator)); + } + if (!fullMatch) { + return true; + } + if (pattIdxStart == pattIdxEnd && pattDirs[pattIdxStart].equals("*") && path.endsWith(this.pathSeparator)) { + return true; + } + for (int i = pattIdxStart; i <= pattIdxEnd; i++) { + if (!pattDirs[i].equals("**")) { + return false; + } + } + return true; + } + else if (pattIdxStart > pattIdxEnd) { + // String not exhausted, but pattern is. Failure. + return false; + } + else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) { + // Path start definitely matches due to "**" part in pattern. + return true; + } + + // up to last '**' + while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) { + String pattDir = pattDirs[pattIdxEnd]; + if (pattDir.equals("**")) { + break; + } + if (!matchStrings(pattDir, pathDirs[pathIdxEnd], uriTemplateVariables)) { + return false; + } + pattIdxEnd--; + pathIdxEnd--; + } + if (pathIdxStart > pathIdxEnd) { + // String is exhausted + for (int i = pattIdxStart; i <= pattIdxEnd; i++) { + if (!pattDirs[i].equals("**")) { + return false; + } + } + return true; + } + + while (pattIdxStart != pattIdxEnd && pathIdxStart <= pathIdxEnd) { + int patIdxTmp = -1; + for (int i = pattIdxStart + 1; i <= pattIdxEnd; i++) { + if (pattDirs[i].equals("**")) { + patIdxTmp = i; + break; + } + } + if (patIdxTmp == pattIdxStart + 1) { + // '**/**' situation, so skip one + pattIdxStart++; + continue; + } + // Find the pattern between padIdxStart & padIdxTmp in str between + // strIdxStart & strIdxEnd + int patLength = (patIdxTmp - pattIdxStart - 1); + int strLength = (pathIdxEnd - pathIdxStart + 1); + int foundIdx = -1; + + strLoop: + for (int i = 0; i <= strLength - patLength; i++) { + for (int j = 0; j < patLength; j++) { + String subPat = pattDirs[pattIdxStart + j + 1]; + String subStr = pathDirs[pathIdxStart + i + j]; + if (!matchStrings(subPat, subStr, uriTemplateVariables)) { + continue strLoop; + } + } + foundIdx = pathIdxStart + i; + break; + } + + if (foundIdx == -1) { + return false; + } + + pattIdxStart = patIdxTmp; + pathIdxStart = foundIdx + patLength; + } + + for (int i = pattIdxStart; i <= pattIdxEnd; i++) { + if (!pattDirs[i].equals("**")) { + return false; + } + } + + return true; + } + + private boolean isPotentialMatch(String path, String[] pattDirs) { + if (!this.trimTokens) { + int pos = 0; + for (String pattDir : pattDirs) { + int skipped = skipSeparator(path, pos, this.pathSeparator); + pos += skipped; + skipped = skipSegment(path, pos, pattDir); + if (skipped < pattDir.length()) { + return (skipped > 0 || (pattDir.length() > 0 && isWildcardChar(pattDir.charAt(0)))); + } + pos += skipped; + } + } + return true; + } + + private int skipSegment(String path, int pos, String prefix) { + int skipped = 0; + for (int i = 0; i < prefix.length(); i++) { + char c = prefix.charAt(i); + if (isWildcardChar(c)) { + return skipped; + } + int currPos = pos + skipped; + if (currPos >= path.length()) { + return 0; + } + if (c == path.charAt(currPos)) { + skipped++; + } + } + return skipped; + } + + private int skipSeparator(String path, int pos, String separator) { + int skipped = 0; + while (path.startsWith(separator, pos + skipped)) { + skipped += separator.length(); + } + return skipped; + } + + private boolean isWildcardChar(char c) { + for (char candidate : WILDCARD_CHARS) { + if (c == candidate) { + return true; + } + } + return false; + } + + /** + * Tokenize the given path pattern into parts, based on this matcher's settings. + *

    Performs caching based on {@link #setCachePatterns}, delegating to + * {@link #tokenizePath(String)} for the actual tokenization algorithm. + * @param pattern the pattern to tokenize + * @return the tokenized pattern parts + */ + protected String[] tokenizePattern(String pattern) { + String[] tokenized = null; + Boolean cachePatterns = this.cachePatterns; + if (cachePatterns == null || cachePatterns.booleanValue()) { + tokenized = this.tokenizedPatternCache.get(pattern); + } + if (tokenized == null) { + tokenized = tokenizePath(pattern); + if (cachePatterns == null && this.tokenizedPatternCache.size() >= CACHE_TURNOFF_THRESHOLD) { + // Try to adapt to the runtime situation that we're encountering: + // There are obviously too many different patterns coming in here... + // So let's turn off the cache since the patterns are unlikely to be reoccurring. + deactivatePatternCache(); + return tokenized; + } + if (cachePatterns == null || cachePatterns.booleanValue()) { + this.tokenizedPatternCache.put(pattern, tokenized); + } + } + return tokenized; + } + + /** + * Tokenize the given path String into parts, based on this matcher's settings. + * @param path the path to tokenize + * @return the tokenized path parts + */ + protected String[] tokenizePath(String path) { + return StringUtils.tokenizeToStringArray(path, this.pathSeparator, this.trimTokens, true); + } + + /** + * Test whether or not a string matches against a pattern. + * @param pattern the pattern to match against (never {@code null}) + * @param str the String which must be matched against the pattern (never {@code null}) + * @return {@code true} if the string matches against the pattern, or {@code false} otherwise + */ + private boolean matchStrings(String pattern, String str, Map uriTemplateVariables) { + return getStringMatcher(pattern).matchStrings(str, uriTemplateVariables); + } + + /** + * Build or retrieve an {@link AntPathStringMatcher} for the given pattern. + *

    The default implementation checks this AntPathMatcher's internal cache + * (see {@link #setCachePatterns}), creating a new AntPathStringMatcher instance + * if no cached copy is found. + *

    When encountering too many patterns to cache at runtime (the threshold is 65536), + * it turns the default cache off, assuming that arbitrary permutations of patterns + * are coming in, with little chance for encountering a recurring pattern. + *

    This method may be overridden to implement a custom cache strategy. + * @param pattern the pattern to match against (never {@code null}) + * @return a corresponding AntPathStringMatcher (never {@code null}) + * @see #setCachePatterns + */ + protected AntPathStringMatcher getStringMatcher(String pattern) { + AntPathStringMatcher matcher = null; + Boolean cachePatterns = this.cachePatterns; + if (cachePatterns == null || cachePatterns.booleanValue()) { + matcher = this.stringMatcherCache.get(pattern); + } + if (matcher == null) { + matcher = new AntPathStringMatcher(pattern, this.caseSensitive); + if (cachePatterns == null && this.stringMatcherCache.size() >= CACHE_TURNOFF_THRESHOLD) { + // Try to adapt to the runtime situation that we're encountering: + // There are obviously too many different patterns coming in here... + // So let's turn off the cache since the patterns are unlikely to be reoccurring. + deactivatePatternCache(); + return matcher; + } + if (cachePatterns == null || cachePatterns.booleanValue()) { + this.stringMatcherCache.put(pattern, matcher); + } + } + return matcher; + } + + /** + * Given a pattern and a full path, determine the pattern-mapped part.

    For example:

      + *
    • '{@code /docs/cvs/commit.html}' and '{@code /docs/cvs/commit.html} -> ''
    • + *
    • '{@code /docs/*}' and '{@code /docs/cvs/commit} -> '{@code cvs/commit}'
    • + *
    • '{@code /docs/cvs/*.html}' and '{@code /docs/cvs/commit.html} -> '{@code commit.html}'
    • + *
    • '{@code /docs/**}' and '{@code /docs/cvs/commit} -> '{@code cvs/commit}'
    • + *
    • '{@code /docs/**\/*.html}' and '{@code /docs/cvs/commit.html} -> '{@code cvs/commit.html}'
    • + *
    • '{@code /*.html}' and '{@code /docs/cvs/commit.html} -> '{@code docs/cvs/commit.html}'
    • + *
    • '{@code *.html}' and '{@code /docs/cvs/commit.html} -> '{@code /docs/cvs/commit.html}'
    • + *
    • '{@code *}' and '{@code /docs/cvs/commit.html} -> '{@code /docs/cvs/commit.html}'
    + *

    Assumes that {@link #match} returns {@code true} for '{@code pattern}' and '{@code path}', but + * does not enforce this. + */ + @Override + public String extractPathWithinPattern(String pattern, String path) { + String[] patternParts = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator, this.trimTokens, true); + String[] pathParts = StringUtils.tokenizeToStringArray(path, this.pathSeparator, this.trimTokens, true); + StringBuilder builder = new StringBuilder(); + boolean pathStarted = false; + + for (int segment = 0; segment < patternParts.length; segment++) { + String patternPart = patternParts[segment]; + if (patternPart.indexOf('*') > -1 || patternPart.indexOf('?') > -1) { + for (; segment < pathParts.length; segment++) { + if (pathStarted || (segment == 0 && !pattern.startsWith(this.pathSeparator))) { + builder.append(this.pathSeparator); + } + builder.append(pathParts[segment]); + pathStarted = true; + } + } + } + + return builder.toString(); + } + + @Override + public Map extractUriTemplateVariables(String pattern, String path) { + Map variables = new LinkedHashMap(); + boolean result = doMatch(pattern, path, true, variables); + if (!result) { + throw new IllegalStateException("Pattern \"" + pattern + "\" is not a match for \"" + path + "\""); + } + return variables; + } + + /** + * Combine two patterns into a new pattern. + *

    This implementation simply concatenates the two patterns, unless + * the first pattern contains a file extension match (e.g., {@code *.html}). + * In that case, the second pattern will be merged into the first. Otherwise, + * an {@code IllegalArgumentException} will be thrown. + *

    Examples

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Pattern 1Pattern 2Result
    {@code null}{@code null} 
    /hotels{@code null}/hotels
    {@code null}/hotels/hotels
    /hotels/bookings/hotels/bookings
    /hotelsbookings/hotels/bookings
    /hotels/*/bookings/hotels/bookings
    /hotels/**/bookings/hotels/**/bookings
    /hotels{hotel}/hotels/{hotel}
    /hotels/*{hotel}/hotels/{hotel}
    /hotels/**{hotel}/hotels/**/{hotel}
    /*.html/hotels.html/hotels.html
    /*.html/hotels/hotels.html
    /*.html/*.txt{@code IllegalArgumentException}
    + * @param pattern1 the first pattern + * @param pattern2 the second pattern + * @return the combination of the two patterns + * @throws IllegalArgumentException if the two patterns cannot be combined + */ + @Override + public String combine(String pattern1, String pattern2) { + if (!StringUtils.hasText(pattern1) && !StringUtils.hasText(pattern2)) { + return ""; + } + if (!StringUtils.hasText(pattern1)) { + return pattern2; + } + if (!StringUtils.hasText(pattern2)) { + return pattern1; + } + + boolean pattern1ContainsUriVar = (pattern1.indexOf('{') != -1); + if (!pattern1.equals(pattern2) && !pattern1ContainsUriVar && match(pattern1, pattern2)) { + // /* + /hotel -> /hotel ; "/*.*" + "/*.html" -> /*.html + // However /user + /user -> /usr/user ; /{foo} + /bar -> /{foo}/bar + return pattern2; + } + + // /hotels/* + /booking -> /hotels/booking + // /hotels/* + booking -> /hotels/booking + if (pattern1.endsWith(this.pathSeparatorPatternCache.getEndsOnWildCard())) { + return concat(pattern1.substring(0, pattern1.length() - 2), pattern2); + } + + // /hotels/** + /booking -> /hotels/**/booking + // /hotels/** + booking -> /hotels/**/booking + if (pattern1.endsWith(this.pathSeparatorPatternCache.getEndsOnDoubleWildCard())) { + return concat(pattern1, pattern2); + } + + int starDotPos1 = pattern1.indexOf("*."); + if (pattern1ContainsUriVar || starDotPos1 == -1 || this.pathSeparator.equals(".")) { + // simply concatenate the two patterns + return concat(pattern1, pattern2); + } + + String ext1 = pattern1.substring(starDotPos1 + 1); + int dotPos2 = pattern2.indexOf('.'); + String file2 = (dotPos2 == -1 ? pattern2 : pattern2.substring(0, dotPos2)); + String ext2 = (dotPos2 == -1 ? "" : pattern2.substring(dotPos2)); + boolean ext1All = (ext1.equals(".*") || ext1.equals("")); + boolean ext2All = (ext2.equals(".*") || ext2.equals("")); + if (!ext1All && !ext2All) { + throw new IllegalArgumentException("Cannot combine patterns: " + pattern1 + " vs " + pattern2); + } + String ext = (ext1All ? ext2 : ext1); + return file2 + ext; + } + + private String concat(String path1, String path2) { + boolean path1EndsWithSeparator = path1.endsWith(this.pathSeparator); + boolean path2StartsWithSeparator = path2.startsWith(this.pathSeparator); + + if (path1EndsWithSeparator && path2StartsWithSeparator) { + return path1 + path2.substring(1); + } + else if (path1EndsWithSeparator || path2StartsWithSeparator) { + return path1 + path2; + } + else { + return path1 + this.pathSeparator + path2; + } + } + + /** + * Given a full path, returns a {@link Comparator} suitable for sorting patterns in order of + * explicitness. + *

    This{@code Comparator} will {@linkplain java.util.Collections#sort(List, Comparator) sort} + * a list so that more specific patterns (without uri templates or wild cards) come before + * generic patterns. So given a list with the following patterns: + *

      + *
    1. {@code /hotels/new}
    2. + *
    3. {@code /hotels/{hotel}}
    4. {@code /hotels/*}
    5. + *
    + * the returned comparator will sort this list so that the order will be as indicated. + *

    The full path given as parameter is used to test for exact matches. So when the given path + * is {@code /hotels/2}, the pattern {@code /hotels/2} will be sorted before {@code /hotels/1}. + * @param path the full path to use for comparison + * @return a comparator capable of sorting patterns in order of explicitness + */ + @Override + public Comparator getPatternComparator(String path) { + return new AntPatternComparator(path); + } + + + /** + * Tests whether or not a string matches against a pattern via a {@link Pattern}. + *

    The pattern may contain special characters: '*' means zero or more characters; '?' means one and + * only one character; '{' and '}' indicate a URI template pattern. For example /users/{user}. + */ + protected static class AntPathStringMatcher { + + private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}"); + + private static final String DEFAULT_VARIABLE_PATTERN = "(.*)"; + + private final Pattern pattern; + + private final List variableNames = new LinkedList(); + + public AntPathStringMatcher(String pattern) { + this(pattern, true); + } + + public AntPathStringMatcher(String pattern, boolean caseSensitive) { + StringBuilder patternBuilder = new StringBuilder(); + Matcher matcher = GLOB_PATTERN.matcher(pattern); + int end = 0; + while (matcher.find()) { + patternBuilder.append(quote(pattern, end, matcher.start())); + String match = matcher.group(); + if ("?".equals(match)) { + patternBuilder.append('.'); + } + else if ("*".equals(match)) { + patternBuilder.append(".*"); + } + else if (match.startsWith("{") && match.endsWith("}")) { + int colonIdx = match.indexOf(':'); + if (colonIdx == -1) { + patternBuilder.append(DEFAULT_VARIABLE_PATTERN); + this.variableNames.add(matcher.group(1)); + } + else { + String variablePattern = match.substring(colonIdx + 1, match.length() - 1); + patternBuilder.append('('); + patternBuilder.append(variablePattern); + patternBuilder.append(')'); + String variableName = match.substring(1, colonIdx); + this.variableNames.add(variableName); + } + } + end = matcher.end(); + } + patternBuilder.append(quote(pattern, end, pattern.length())); + this.pattern = (caseSensitive ? Pattern.compile(patternBuilder.toString()) : + Pattern.compile(patternBuilder.toString(), Pattern.CASE_INSENSITIVE)); + } + + private String quote(String s, int start, int end) { + if (start == end) { + return ""; + } + return Pattern.quote(s.substring(start, end)); + } + + /** + * Main entry point. + * @return {@code true} if the string matches against the pattern, or {@code false} otherwise. + */ + public boolean matchStrings(String str, Map uriTemplateVariables) { + Matcher matcher = this.pattern.matcher(str); + if (matcher.matches()) { + if (uriTemplateVariables != null) { + // SPR-8455 + if (this.variableNames.size() != matcher.groupCount()) { + throw new IllegalArgumentException("The number of capturing groups in the pattern segment " + + this.pattern + " does not match the number of URI template variables it defines, " + + "which can occur if capturing groups are used in a URI template regex. " + + "Use non-capturing groups instead."); + } + for (int i = 1; i <= matcher.groupCount(); i++) { + String name = this.variableNames.get(i - 1); + String value = matcher.group(i); + uriTemplateVariables.put(name, value); + } + } + return true; + } + else { + return false; + } + } + } + + + /** + * The default {@link Comparator} implementation returned by + * {@link #getPatternComparator(String)}. + *

    In order, the most "generic" pattern is determined by the following: + *

      + *
    • if it's null or a capture all pattern (i.e. it is equal to "/**")
    • + *
    • if the other pattern is an actual match
    • + *
    • if it's a catch-all pattern (i.e. it ends with "**"
    • + *
    • if it's got more "*" than the other pattern
    • + *
    • if it's got more "{foo}" than the other pattern
    • + *
    • if it's shorter than the other pattern
    • + *
    + */ + protected static class AntPatternComparator implements Comparator { + + private final String path; + + public AntPatternComparator(String path) { + this.path = path; + } + + /** + * Compare two patterns to determine which should match first, i.e. which + * is the most specific regarding the current path. + * @return a negative integer, zero, or a positive integer as pattern1 is + * more specific, equally specific, or less specific than pattern2. + */ + @Override + public int compare(String pattern1, String pattern2) { + PatternInfo info1 = new PatternInfo(pattern1); + PatternInfo info2 = new PatternInfo(pattern2); + + if (info1.isLeastSpecific() && info2.isLeastSpecific()) { + return 0; + } + else if (info1.isLeastSpecific()) { + return 1; + } + else if (info2.isLeastSpecific()) { + return -1; + } + + boolean pattern1EqualsPath = pattern1.equals(path); + boolean pattern2EqualsPath = pattern2.equals(path); + if (pattern1EqualsPath && pattern2EqualsPath) { + return 0; + } + else if (pattern1EqualsPath) { + return -1; + } + else if (pattern2EqualsPath) { + return 1; + } + + if (info1.isPrefixPattern() && info2.getDoubleWildcards() == 0) { + return 1; + } + else if (info2.isPrefixPattern() && info1.getDoubleWildcards() == 0) { + return -1; + } + + if (info1.getTotalCount() != info2.getTotalCount()) { + return info1.getTotalCount() - info2.getTotalCount(); + } + + if (info1.getLength() != info2.getLength()) { + return info2.getLength() - info1.getLength(); + } + + if (info1.getSingleWildcards() < info2.getSingleWildcards()) { + return -1; + } + else if (info2.getSingleWildcards() < info1.getSingleWildcards()) { + return 1; + } + + if (info1.getUriVars() < info2.getUriVars()) { + return -1; + } + else if (info2.getUriVars() < info1.getUriVars()) { + return 1; + } + + return 0; + } + + + /** + * Value class that holds information about the pattern, e.g. number of + * occurrences of "*", "**", and "{" pattern elements. + */ + private static class PatternInfo { + + private final String pattern; + + private int uriVars; + + private int singleWildcards; + + private int doubleWildcards; + + private boolean catchAllPattern; + + private boolean prefixPattern; + + private Integer length; + + public PatternInfo(String pattern) { + this.pattern = pattern; + if (this.pattern != null) { + initCounters(); + this.catchAllPattern = this.pattern.equals("/**"); + this.prefixPattern = !this.catchAllPattern && this.pattern.endsWith("/**"); + } + if (this.uriVars == 0) { + this.length = (this.pattern != null ? this.pattern.length() : 0); + } + } + + protected void initCounters() { + int pos = 0; + while (pos < this.pattern.length()) { + if (this.pattern.charAt(pos) == '{') { + this.uriVars++; + pos++; + } + else if (this.pattern.charAt(pos) == '*') { + if (pos + 1 < this.pattern.length() && this.pattern.charAt(pos + 1) == '*') { + this.doubleWildcards++; + pos += 2; + } + else if (pos > 0 && !this.pattern.substring(pos - 1).equals(".*")) { + this.singleWildcards++; + pos++; + } + else { + pos++; + } + } + else { + pos++; + } + } + } + + public int getUriVars() { + return this.uriVars; + } + + public int getSingleWildcards() { + return this.singleWildcards; + } + + public int getDoubleWildcards() { + return this.doubleWildcards; + } + + public boolean isLeastSpecific() { + return (this.pattern == null || this.catchAllPattern); + } + + public boolean isPrefixPattern() { + return this.prefixPattern; + } + + public int getTotalCount() { + return this.uriVars + this.singleWildcards + (2 * this.doubleWildcards); + } + + /** + * Returns the length of the given pattern, where template variables are considered to be 1 long. + */ + public int getLength() { + if (this.length == null) { + this.length = VARIABLE_PATTERN.matcher(this.pattern).replaceAll("#").length(); + } + return this.length; + } + } + } + + + /** + * A simple cache for patterns that depend on the configured path separator. + */ + private static class PathSeparatorPatternCache { + + private final String endsOnWildCard; + + private final String endsOnDoubleWildCard; + + public PathSeparatorPatternCache(String pathSeparator) { + this.endsOnWildCard = pathSeparator + "*"; + this.endsOnDoubleWildCard = pathSeparator + "**"; + } + + public String getEndsOnWildCard() { + return this.endsOnWildCard; + } + + public String getEndsOnDoubleWildCard() { + return this.endsOnDoubleWildCard; + } + } + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/store/SsoLoginStore.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/store/SsoLoginStore.java new file mode 100644 index 0000000..d6d2a60 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/store/SsoLoginStore.java @@ -0,0 +1,70 @@ +package com.itools.sso.core.store; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.user.XxlSsoUser; +import com.itools.sso.core.util.JedisUtil; + +/** + * local login store + * + * @author xuxueli 2018-04-02 20:03:11 + */ +public class SsoLoginStore { + /** + * 1440 minite, 24 hour + */ + private static int redisExpireMinite = 1440; + public static void setRedisExpireMinite(int redisExpireMinite) { + if (redisExpireMinite < 30) { + redisExpireMinite = 30; + } + SsoLoginStore.redisExpireMinite = redisExpireMinite; + } + public static int getRedisExpireMinite() { + return redisExpireMinite; + } + + /** + * get + * + * @param storeKey + * @return + */ + public static XxlSsoUser get(String storeKey) { + + String redisKey = redisKey(storeKey); + Object objectValue = JedisUtil.getObjectValue(redisKey); + if (objectValue != null) { + XxlSsoUser xxlUser = (XxlSsoUser) objectValue; + return xxlUser; + } + return null; + } + + /** + * remove + * + * @param storeKey + */ + public static void remove(String storeKey) { + String redisKey = redisKey(storeKey); + JedisUtil.del(redisKey); + } + + /** + * put + * + * @param storeKey + * @param xxlUser + */ + public static void put(String storeKey, XxlSsoUser xxlUser) { + String redisKey = redisKey(storeKey); + // minite to second + JedisUtil.setObjectValue(redisKey, xxlUser, redisExpireMinite * 60); + } + + private static String redisKey(String sessionId){ + return Conf.SSO_SESSIONID.concat("#").concat(sessionId); + } + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/store/SsoSessionIdHelper.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/store/SsoSessionIdHelper.java new file mode 100644 index 0000000..69383b1 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/store/SsoSessionIdHelper.java @@ -0,0 +1,70 @@ +package com.itools.sso.core.store; + +import com.itools.sso.core.user.XxlSsoUser; + +/** + * make client sessionId + * + * client: cookie = [userid#version] + * server: redis + * key = [userid] + * value = user (user.version, valid this) + * + * // group The same group shares the login status, Different groups will not interact + * + * @author xuxueli 2018-11-15 15:45:08 + */ + +public class SsoSessionIdHelper { + + + /** + * make client sessionId + * + * @param xxlSsoUser + * @return + */ + public static String makeSessionId(XxlSsoUser xxlSsoUser){ + String sessionId = xxlSsoUser.getUserid().concat("_").concat(xxlSsoUser.getVersion()); + return sessionId; + } + + /** + * parse storeKey from sessionId + * + * @param sessionId + * @return + */ + public static String parseStoreKey(String sessionId) { + if (sessionId!=null && sessionId.indexOf("_")>-1) { + String[] sessionIdArr = sessionId.split("_"); + if (sessionIdArr.length==2 + && sessionIdArr[0]!=null + && sessionIdArr[0].trim().length()>0) { + String userId = sessionIdArr[0].trim(); + return userId; + } + } + return null; + } + + /** + * parse version from sessionId + * + * @param sessionId + * @return + */ + public static String parseVersion(String sessionId) { + if (sessionId!=null && sessionId.indexOf("_")>-1) { + String[] sessionIdArr = sessionId.split("_"); + if (sessionIdArr.length==2 + && sessionIdArr[1]!=null + && sessionIdArr[1].trim().length()>0) { + String version = sessionIdArr[1].trim(); + return version; + } + } + return null; + } + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/user/XxlSsoUser.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/user/XxlSsoUser.java new file mode 100644 index 0000000..808a3f5 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/user/XxlSsoUser.java @@ -0,0 +1,73 @@ +package com.itools.sso.core.user; + +import java.io.Serializable; +import java.util.Map; + +/** + * xxl sso user + * + * @author xuxueli 2018-04-02 19:59:49 + */ +public class XxlSsoUser implements Serializable { + private static final long serialVersionUID = 42L; + + // field + private String userid; + private String username; + private Map plugininfo; + + private String version; + private int expireMinite; + private long expireFreshTime; + + + // set get + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Map getPlugininfo() { + return plugininfo; + } + + public void setPlugininfo(Map plugininfo) { + this.plugininfo = plugininfo; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public int getExpireMinite() { + return expireMinite; + } + + public void setExpireMinite(int expireMinite) { + this.expireMinite = expireMinite; + } + + public long getExpireFreshTime() { + return expireFreshTime; + } + + public void setExpireFreshTime(long expireFreshTime) { + this.expireFreshTime = expireFreshTime; + } + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/CookieUtil.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/CookieUtil.java new file mode 100644 index 0000000..88a650d --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/CookieUtil.java @@ -0,0 +1,98 @@ +package com.itools.sso.core.util; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Cookie.Util + * + * @author xuxueli 2015-12-12 18:01:06 + */ +public class CookieUtil { + + // 默认缓存时间,单位/秒, 2H + private static final int COOKIE_MAX_AGE = Integer.MAX_VALUE; + // 保存路径,根路径 + private static final String COOKIE_PATH = "/"; + + /** + * 保存 + * + * @param response + * @param key + * @param value + * @param ifRemember + */ + public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) { + int age = ifRemember?COOKIE_MAX_AGE:-1; + set(response, key, value, null, COOKIE_PATH, age, true); + } + + /** + * 保存 + * + * @param response + * @param key + * @param value + * @param maxAge + */ + private static void set(HttpServletResponse response, String key, String value, String domain, String path, int maxAge, boolean isHttpOnly) { + Cookie cookie = new Cookie(key, value); + if (domain != null) { + cookie.setDomain(domain); + } + cookie.setPath(path); + cookie.setMaxAge(maxAge); + cookie.setHttpOnly(isHttpOnly); + response.addCookie(cookie); + } + + /** + * 查询value + * + * @param request + * @param key + * @return + */ + public static String getValue(HttpServletRequest request, String key) { + Cookie cookie = get(request, key); + if (cookie != null) { + return cookie.getValue(); + } + return null; + } + + /** + * 查询Cookie + * + * @param request + * @param key + */ + private static Cookie get(HttpServletRequest request, String key) { + Cookie[] arr_cookie = request.getCookies(); + if (arr_cookie != null && arr_cookie.length > 0) { + for (Cookie cookie : arr_cookie) { + if (cookie.getName().equals(key)) { + return cookie; + } + } + } + return null; + } + + /** + * 删除Cookie + * + * @param request + * @param response + * @param key + */ + public static void remove(HttpServletRequest request, HttpServletResponse response, String key) { + Cookie cookie = get(request, key); + if (cookie != null) { + set(response, key, "", null, COOKIE_PATH, 0, true); + } + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/JedisUtil.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/JedisUtil.java new file mode 100644 index 0000000..1a1cf1f --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/JedisUtil.java @@ -0,0 +1,391 @@ +package com.itools.sso.core.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.JedisShardInfo; +import redis.clients.jedis.ShardedJedis; +import redis.clients.jedis.ShardedJedisPool; + +import java.io.*; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + + +/** + * Redis client base on jedis + * + * @author xuxueli 2015-7-10 18:34:07 + */ +public class JedisUtil { + private static Logger logger = LoggerFactory.getLogger(JedisUtil.class); + + /** + * redis address, like "{ip}"、"{ip}:{port}"、"{redis/rediss}://xxl-sso:{password}@{ip}:{port:6379}/{db}";Multiple "," separated + */ + private static String address; + + public static void init(String address) { + JedisUtil.address = address; + + getInstance(); + } + + // ------------------------ ShardedJedisPool ------------------------ + /** + * 方式01: Redis单节点 + Jedis单例 : Redis单节点压力过重, Jedis单例存在并发瓶颈 》》不可用于线上 + * new Jedis("127.0.0.1", 6379).get("cache_key"); + * 方式02: Redis单节点 + JedisPool单节点连接池 》》 Redis单节点压力过重,负载和容灾比较差 + * new JedisPool(new JedisPoolConfig(), "127.0.0.1", 6379, 10000).getResource().get("cache_key"); + * 方式03: Redis分片(通过client端集群,一致性哈希方式实现) + Jedis多节点连接池 》》Redis集群,负载和容灾较好, ShardedJedisPool一致性哈希分片,读写均匀,动态扩充 + * new ShardedJedisPool(new JedisPoolConfig(), new LinkedList()); + * 方式03: Redis集群; + * new JedisCluster(jedisClusterNodes); // TODO + */ + + private static ShardedJedisPool shardedJedisPool; + private static ReentrantLock INSTANCE_INIT_LOCL = new ReentrantLock(false); + + /** + * 获取ShardedJedis实例 + * + * @return + */ + private static ShardedJedis getInstance() { + if (shardedJedisPool == null) { + try { + if (INSTANCE_INIT_LOCL.tryLock(2, TimeUnit.SECONDS)) { + + try { + + if (shardedJedisPool == null) { + + // JedisPoolConfig + JedisPoolConfig config = new JedisPoolConfig(); + config.setMaxTotal(200); + config.setMaxIdle(50); + config.setMinIdle(8); + config.setMaxWaitMillis(10000); // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1 + config.setTestOnBorrow(true); // 在获取连接的时候检查有效性, 默认false + config.setTestOnReturn(false); // 调用returnObject方法时,是否进行有效检查 + config.setTestWhileIdle(true); // Idle时进行连接扫描 + config.setTimeBetweenEvictionRunsMillis(30000); // 表示idle object evitor两次扫描之间要sleep的毫秒数 + config.setNumTestsPerEvictionRun(10); // 表示idle object evitor每次扫描的最多的对象数 + config.setMinEvictableIdleTimeMillis(60000); // 表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义 + + + // JedisShardInfo List + List jedisShardInfos = new LinkedList(); + + String[] addressArr = address.split(","); + for (int i = 0; i < addressArr.length; i++) { + JedisShardInfo jedisShardInfo = new JedisShardInfo(addressArr[i]); + jedisShardInfos.add(jedisShardInfo); + } + shardedJedisPool = new ShardedJedisPool(config, jedisShardInfos); + logger.info(">>>>>>>>>>> xxl-sso, JedisUtil.ShardedJedisPool init success."); + } + + } finally { + INSTANCE_INIT_LOCL.unlock(); + } + } + + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + if (shardedJedisPool == null) { + throw new NullPointerException(">>>>>>>>>>> xxl-sso, JedisUtil.ShardedJedisPool is null."); + } + + ShardedJedis shardedJedis = shardedJedisPool.getResource(); + return shardedJedis; + } + + public static void close() throws IOException { + if(shardedJedisPool != null) { + shardedJedisPool.close(); + } + } + + + // ------------------------ serialize and unserialize ------------------------ + + /** + * 将对象-->byte[] (由于jedis中不支持直接存储object所以转换成byte[]存入) + * + * @param object + * @return + */ + private static byte[] serialize(Object object) { + ObjectOutputStream oos = null; + ByteArrayOutputStream baos = null; + try { + // 序列化 + baos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(baos); + oos.writeObject(object); + byte[] bytes = baos.toByteArray(); + return bytes; + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + try { + oos.close(); + baos.close(); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } + return null; + } + + /** + * 将byte[] -->Object + * + * @param bytes + * @return + */ + private static Object unserialize(byte[] bytes) { + ByteArrayInputStream bais = null; + try { + // 反序列化 + bais = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(bais); + return ois.readObject(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + try { + bais.close(); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } + return null; + } + + // ------------------------ jedis util ------------------------ + /** + * 存储简单的字符串或者是Object 因为jedis没有分装直接存储Object的方法,所以在存储对象需斟酌下 + * 存储对象的字段是不是非常多而且是不是每个字段都用到,如果是的话那建议直接存储对象, + * 否则建议用集合的方式存储,因为redis可以针对集合进行日常的操作很方便而且还可以节省空间 + */ + + /** + * Set String + * + * @param key + * @param value + * @param seconds 存活时间,单位/秒 + * @return + */ + public static String setStringValue(String key, String value, int seconds) { + String result = null; + ShardedJedis client = getInstance(); + try { + result = client.setex(key, seconds, value); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return result; + } + + /** + * Set Object + * + * @param key + * @param obj + * @param seconds 存活时间,单位/秒 + */ + public static String setObjectValue(String key, Object obj, int seconds) { + String result = null; + ShardedJedis client = getInstance(); + try { + result = client.setex(key.getBytes(), seconds, serialize(obj)); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return result; + } + + /** + * Get String + * + * @param key + * @return + */ + public static String getStringValue(String key) { + String value = null; + ShardedJedis client = getInstance(); + try { + value = client.get(key); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return value; + } + + /** + * Get Object + * + * @param key + * @return + */ + public static Object getObjectValue(String key) { + Object obj = null; + ShardedJedis client = getInstance(); + try { + byte[] bytes = client.get(key.getBytes()); + if (bytes != null && bytes.length > 0) { + obj = unserialize(bytes); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return obj; + } + + /** + * Delete key + * + * @param key + * @return Integer reply, specifically: + * an integer greater than 0 if one or more keys were removed + * 0 if none of the specified key existed + */ + public static Long del(String key) { + Long result = null; + ShardedJedis client = getInstance(); + try { + result = client.del(key); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return result; + } + + /** + * incrBy i(+i) + * + * @param key + * @param i + * @return new value after incr + */ + public static Long incrBy(String key, int i) { + Long result = null; + ShardedJedis client = getInstance(); + try { + result = client.incrBy(key, i); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return result; + } + + /** + * exists valid + * + * @param key + * @return Boolean reply, true if the key exists, otherwise false + */ + public static boolean exists(String key) { + Boolean result = null; + ShardedJedis client = getInstance(); + try { + result = client.exists(key); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return result; + } + + /** + * expire reset + * + * @param key + * @param seconds 存活时间,单位/秒 + * @return Integer reply, specifically: + * 1: the timeout was set. + * 0: the timeout was not set since the key already has an associated timeout (versions lt 2.1.3), or the key does not exist. + */ + public static long expire(String key, int seconds) { + Long result = null; + ShardedJedis client = getInstance(); + try { + result = client.expire(key, seconds); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return result; + } + + /** + * expire at unixTime + * + * @param key + * @param unixTime + * @return + */ + public static long expireAt(String key, long unixTime) { + Long result = null; + ShardedJedis client = getInstance(); + try { + result = client.expireAt(key, unixTime); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + if (client != null) { + client.close(); + } + } + return result; + } + + public static void main(String[] args) { + String xxlSsoRedisAddress = "redis://xxl-sso:password@127.0.0.1:6379/0"; + xxlSsoRedisAddress = "redis://127.0.0.1:6379/0"; + init(xxlSsoRedisAddress); + + setObjectValue("key", "666", 2*60*60); + System.out.println(getObjectValue("key")); + + } + +} diff --git a/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/StringUtils.java b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/StringUtils.java new file mode 100644 index 0000000..ca73276 --- /dev/null +++ b/itools-sso/itools-sso-core/src/main/java/com/itools/sso/core/util/StringUtils.java @@ -0,0 +1,79 @@ +package com.itools.sso.core.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.StringTokenizer; + +public abstract class StringUtils { + + /** + * + * @param str + * @return + */ + public static boolean hasLength(String str) { + return (str != null && !str.isEmpty()); + } + + /** + * + * @param str + * @return + */ + public static boolean hasText(String str) { + return (hasLength(str) && containsText(str)); + } + + private static boolean containsText(CharSequence str) { + int strLen = str.length(); + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return true; + } + } + return false; + } + + /** + * + * @param str + * @param delimiters + * @param trimTokens + * @param ignoreEmptyTokens + * @return + */ + public static String[] tokenizeToStringArray( + String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) { + + if (str == null) { + return null; + } + + StringTokenizer st = new StringTokenizer(str, delimiters); + List tokens = new ArrayList(); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if (trimTokens) { + token = token.trim(); + } + if (!ignoreEmptyTokens || token.length() > 0) { + tokens.add(token); + } + } + return toStringArray(tokens); + } + + /** + * + * @param collection + * @return + */ + public static String[] toStringArray(Collection collection) { + if (collection == null) { + return null; + } + return collection.toArray(new String[collection.size()]); + } + +} diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/pom.xml b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/pom.xml new file mode 100644 index 0000000..76d1f11 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + + xxl-sso-samples + com.itools.core + 1.0-SNAPSHOT + + xxl-sso-token-sample-springboot + jar + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring-boot.version} + pom + import + + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + com.itools.core + xxl-sso-core + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-devtools + provided + true + + + + + org.apache.httpcomponents + httpclient + 4.5.6 + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + true + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/XxlClientApplication.java b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/XxlClientApplication.java new file mode 100644 index 0000000..778041f --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/XxlClientApplication.java @@ -0,0 +1,16 @@ +package com.itools.sso.sample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author xuxueli 2018-04-08 21:49:41 + */ +@SpringBootApplication +public class XxlClientApplication { + + public static void main(String[] args) { + SpringApplication.run(XxlClientApplication.class, args); + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/config/XxlSsoConfig.java b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/config/XxlSsoConfig.java new file mode 100644 index 0000000..fe4e8b6 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/config/XxlSsoConfig.java @@ -0,0 +1,59 @@ +package com.itools.sso.sample.config; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.filter.XxlSsoTokenFilter; +import com.itools.sso.core.util.JedisUtil; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author xuxueli 2018-11-15 + */ +@Configuration +public class XxlSsoConfig implements DisposableBean { + + + @Value("${xxl.sso.server}") + private String xxlSsoServer; + + @Value("${xxl.sso.logout.path}") + private String xxlSsoLogoutPath; + + @Value("${xxl.sso.redis.address}") + private String xxlSsoRedisAddress; + + @Value("${xxl-sso.excluded.paths}") + private String xxlSsoExcludedPaths; + + + @Bean + public FilterRegistrationBean xxlSsoFilterRegistration() { + + // xxl-sso, redis init + JedisUtil.init(xxlSsoRedisAddress); + + // xxl-sso, filter init + FilterRegistrationBean registration = new FilterRegistrationBean(); + + registration.setName("XxlSsoWebFilter"); + registration.setOrder(1); + registration.addUrlPatterns("/*"); + registration.setFilter(new XxlSsoTokenFilter()); + registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer); + registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath); + registration.addInitParameter(Conf.SSO_EXCLUDED_PATHS, xxlSsoExcludedPaths); + + return registration; + } + + @Override + public void destroy() throws Exception { + + // xxl-sso, redis close + JedisUtil.close(); + } + +} diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/controller/IndexController.java b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/controller/IndexController.java new file mode 100644 index 0000000..577eb8b --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/java/com/itools/sso/sample/controller/IndexController.java @@ -0,0 +1,25 @@ +package com.itools.sso.sample.controller; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.entity.ReturnT; +import com.itools.sso.core.user.XxlSsoUser; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author xuxueli 2017-08-01 21:39:47 + */ +@Controller +public class IndexController { + + @RequestMapping("/") + @ResponseBody + public ReturnT index(HttpServletRequest request) { + XxlSsoUser xxlUser = (XxlSsoUser) request.getAttribute(Conf.SSO_USER); + return new ReturnT(xxlUser); + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/resources/application.properties b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/resources/application.properties new file mode 100644 index 0000000..95a16b3 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/resources/application.properties @@ -0,0 +1,9 @@ +### web +server.port=8092 +server.context-path=/xxl-sso-token-sample-springboot + +### xxl-sso +xxl.sso.server=http://xxlssoserver.com:8090/xxl-sso-server +xxl.sso.logout.path=/logout +xxl-sso.excluded.paths= +xxl.sso.redis.address=redis://127.0.0.1:6379 diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/resources/logback.xml b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/resources/logback.xml new file mode 100644 index 0000000..cb7f94e --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/main/resources/logback.xml @@ -0,0 +1,32 @@ + + + + logback + + + + + + %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n + + + + + ${log.path} + + ${log.path}.%d{yyyy-MM-dd}.zip + + + %date %level [%thread] %logger{36} [%file : %line] %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/java/com/xxl/app/sample/test/TokenClientTest.java b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/java/com/xxl/app/sample/test/TokenClientTest.java new file mode 100644 index 0000000..a7d17ec --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/java/com/xxl/app/sample/test/TokenClientTest.java @@ -0,0 +1,182 @@ +package com.xxl.app.sample.test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.xxl.app.sample.test.util.HttpClientUtil; +import com.itools.sso.core.conf.Conf; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * @author xuxueli 2018-04-09 11:38:15 + */ +public class TokenClientTest { + private static Logger logger = LoggerFactory.getLogger(TokenClientTest.class); + + public static String ssoServer = "http://xxlssoserver.com:8080/xxl-sso-server"; + + public static String client01 = "http://xxlssoclient1.com:8082/xxl-sso-token-sample-springboot/"; + public static String client02 = "http://xxlssoclient2.com:8082/xxl-sso-token-sample-springboot/"; + + @Test + public void test() throws Exception { + + // 登录:获取 sso sessionId + String sessionId = loginTest(); + Assert.assertNotNull(sessionId); + + // 登陆状态校验 + String username = logincheckTest(sessionId); + Assert.assertNotNull(username); + + clientApiRequestTest(client01, sessionId); + clientApiRequestTest(client02, sessionId); + + // 注销:销毁 sso sessionId + boolean loginoutResult = logoutTest(sessionId); + Assert.assertTrue(loginoutResult); + + // 登陆状态校验 + username = logincheckTest(sessionId); + Assert.assertNull(username); + + clientApiRequestTest(client01, sessionId); + clientApiRequestTest(client02, sessionId); + } + + /** + * Client API Request, SSO APP Filter + * + * @param clientApiUrl + * @return + */ + private void clientApiRequestTest(String clientApiUrl, String sessionId) throws IOException { + + Map headerParam = new HashMap<>(); + headerParam.put(Conf.SSO_SESSIONID, sessionId); + + + String resultJson = HttpClientUtil.post(clientApiUrl, null, headerParam); + Map loginResult = new ObjectMapper().readValue(resultJson, Map.class); + + int code = (int) loginResult.get("code"); + if (code == 200) { + + Map user = (Map) loginResult.get("data"); + String username = (String) user.get("username"); + + logger.info("模拟请求APP应用接口,请求成功,登陆用户 = " + username); + } else { + + String failMsg = (String) loginResult.get("msg"); + + logger.info("模拟请求APP应用接口,请求失败:" + failMsg); + } + } + + /** + * SSO Login + * + * @return + */ + private String loginTest() throws IOException { + // login url + String loginUrl = ssoServer + "/app/login"; + + // login param + Map loginParam = new HashMap<>(); + loginParam.put("username", "user"); + loginParam.put("password", "123456"); + + String loginResultJson = HttpClientUtil.post(loginUrl, loginParam, null); + Map loginResult = new ObjectMapper().readValue(loginResultJson, Map.class); + + int code = (int) loginResult.get("code"); + if (code == 200) { + + String sessionId = (String) loginResult.get("data"); + logger.info("登录成功,sessionid = " + sessionId); + + return sessionId; + } else { + + String failMsg = (String) loginResult.get("msg"); + logger.info("登录失败:" + failMsg); + + return null; + } + + } + + /** + * SSO Logout + * + * @param sessionId + * @return + */ + private boolean logoutTest(String sessionId) throws IOException { + // logout url + String logoutUrl = ssoServer + "/app/logout"; + + // logout param + Map logoutParam = new HashMap<>(); + logoutParam.put("sessionId", sessionId); + + String logoutResultJson = HttpClientUtil.post(logoutUrl, logoutParam, null); + Map logoutResult = new ObjectMapper().readValue(logoutResultJson, Map.class); + + int code = (int) logoutResult.get("code"); + if (code == 200) { + + logger.info("注销成功"); + return true; + } else { + + String failMsg = (String) logoutResult.get("msg"); + logger.info("注销失败:" + failMsg); + + return false; + } + + } + + /** + * SSO Login Check + * + * @param sessionId + * @return + */ + private String logincheckTest(String sessionId) throws IOException { + // logout url + String logincheckUrl = ssoServer + "/app/logincheck"; + + // logout param + Map logincheckParam = new HashMap<>(); + logincheckParam.put("sessionId", sessionId); + + String logincheckResultJson = HttpClientUtil.post(logincheckUrl, logincheckParam, null); + Map logincheckResult = new ObjectMapper().readValue(logincheckResultJson, Map.class); + + int code = (int) logincheckResult.get("code"); + if (code == 200) { + + Map user = (Map) logincheckResult.get("data"); + String username = (String) user.get("username"); + + logger.info("当前为登录状态,登陆用户 = " + username); + + return username; + } else { + + logger.info("当前为注销状态"); + return null; + } + + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/java/com/xxl/app/sample/test/util/HttpClientUtil.java b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/java/com/xxl/app/sample/test/util/HttpClientUtil.java new file mode 100644 index 0000000..e1cc926 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/java/com/xxl/app/sample/test/util/HttpClientUtil.java @@ -0,0 +1,90 @@ +package com.xxl.app.sample.test.util; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * http util to send data + * + * @author xuxueli + * @version 2015-11-28 15:30:59 + */ +public class HttpClientUtil { + private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class); + + public static String post(String url, Map params, Map headers){ + HttpPost httpPost = null; + CloseableHttpClient httpClient = null; + try{ + // httpPost config + httpPost = new HttpPost(url); + if (params != null && !params.isEmpty()) { + List formParams = new ArrayList(); + for(Map.Entry entry : params.entrySet()){ + formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); + } + httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8")); + } + RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build(); + httpPost.setConfig(requestConfig); + + // headers + if (headers!=null && headers.size()>0) { + for (Map.Entry headerItem: headers.entrySet()) { + httpPost.setHeader(headerItem.getKey(), headerItem.getValue()); + } + } + + // httpClient = HttpClients.createDefault(); // default retry 3 times + // httpClient = HttpClients.custom().setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)).build(); + httpClient = HttpClients.custom().disableAutomaticRetries().build(); + + // parse response + HttpResponse response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + if (null != entity) { + if (response.getStatusLine().getStatusCode() == 200) { + String responseMsg = EntityUtils.toString(entity, "UTF-8"); + EntityUtils.consume(entity); + return responseMsg; + } + EntityUtils.consume(entity); + } + logger.info("http statusCode error, statusCode:" + response.getStatusLine().getStatusCode()); + return null; + } catch (Exception e) { + e.printStackTrace(); + /*StringWriter out = new StringWriter(); + e.printStackTrace(new PrintWriter(out)); + callback.setMsg(out.toString());*/ + return e.getMessage(); + } finally{ + if (httpPost!=null) { + httpPost.releaseConnection(); + } + if (httpClient!=null) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + +} diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/resources/logback.xml b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/resources/logback.xml new file mode 100644 index 0000000..1780ec4 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/src/test/resources/logback.xml @@ -0,0 +1,16 @@ + + + + logback + + + + %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/classes/application.properties b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/classes/application.properties new file mode 100644 index 0000000..95a16b3 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/classes/application.properties @@ -0,0 +1,9 @@ +### web +server.port=8092 +server.context-path=/xxl-sso-token-sample-springboot + +### xxl-sso +xxl.sso.server=http://xxlssoserver.com:8090/xxl-sso-server +xxl.sso.logout.path=/logout +xxl-sso.excluded.paths= +xxl.sso.redis.address=redis://127.0.0.1:6379 diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/classes/logback.xml b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/classes/logback.xml new file mode 100644 index 0000000..cb7f94e --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/classes/logback.xml @@ -0,0 +1,32 @@ + + + + logback + + + + + + %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n + + + + + ${log.path} + + ${log.path}.%d{yyyy-MM-dd}.zip + + + %date %level [%thread] %logger{36} [%file : %line] %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/test-classes/logback.xml b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/test-classes/logback.xml new file mode 100644 index 0000000..1780ec4 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-token-sample-springboot/target/test-classes/logback.xml @@ -0,0 +1,16 @@ + + + + logback + + + + %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/pom.xml b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/pom.xml new file mode 100644 index 0000000..ac73aca --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + + xxl-sso-samples + com.itools.core + 1.0-SNAPSHOT + + xxl-sso-web-sample-springboot + jar + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring-boot.version} + pom + import + + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + com.itools.core + xxl-sso-core + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-devtools + provided + true + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + true + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/XxlClientApplication.java b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/XxlClientApplication.java new file mode 100644 index 0000000..3b1b7f5 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/XxlClientApplication.java @@ -0,0 +1,16 @@ +package com.itools.sso.sample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author xuxueli 2018-03-22 23:41:47 + */ +@SpringBootApplication +public class XxlClientApplication { + + public static void main(String[] args) { + SpringApplication.run(XxlClientApplication.class, args); + } + +} diff --git a/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/config/XxlSsoConfig.java b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/config/XxlSsoConfig.java new file mode 100644 index 0000000..05d0321 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/config/XxlSsoConfig.java @@ -0,0 +1,59 @@ +package com.itools.sso.sample.config; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.filter.XxlSsoWebFilter; +import com.itools.sso.core.util.JedisUtil; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author xuxueli 2018-11-15 + */ +@Configuration +public class XxlSsoConfig implements DisposableBean { + + + @Value("${xxl.sso.server}") + private String xxlSsoServer; + + @Value("${xxl.sso.logout.path}") + private String xxlSsoLogoutPath; + + @Value("${xxl-sso.excluded.paths}") + private String xxlSsoExcludedPaths; + + @Value("${xxl.sso.redis.address}") + private String xxlSsoRedisAddress; + + + @Bean + public FilterRegistrationBean xxlSsoFilterRegistration() { + + // xxl-sso, redis init + JedisUtil.init(xxlSsoRedisAddress); + + // xxl-sso, filter init + FilterRegistrationBean registration = new FilterRegistrationBean(); + + registration.setName("XxlSsoWebFilter"); + registration.setOrder(1); + registration.addUrlPatterns("/*"); + registration.setFilter(new XxlSsoWebFilter()); + registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer); + registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath); + registration.addInitParameter(Conf.SSO_EXCLUDED_PATHS, xxlSsoExcludedPaths); + + return registration; + } + + @Override + public void destroy() throws Exception { + + // xxl-sso, redis close + JedisUtil.close(); + } + +} diff --git a/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/controller/IndexController.java b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/controller/IndexController.java new file mode 100644 index 0000000..7a9cb77 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/java/com/itools/sso/sample/controller/IndexController.java @@ -0,0 +1,34 @@ +package com.itools.sso.sample.controller; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.entity.ReturnT; +import com.itools.sso.core.user.XxlSsoUser; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author xuxueli 2017-08-01 21:39:47 + */ +@Controller +public class IndexController { + + @RequestMapping("/") + public String index(Model model, HttpServletRequest request) { + + XxlSsoUser xxlUser = (XxlSsoUser) request.getAttribute(Conf.SSO_USER); + model.addAttribute("xxlUser", xxlUser); + return "index"; + } + + @RequestMapping("/json") + @ResponseBody + public ReturnT json(Model model, HttpServletRequest request) { + XxlSsoUser xxlUser = (XxlSsoUser) request.getAttribute(Conf.SSO_USER); + return new ReturnT(xxlUser); + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/application.properties b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/application.properties new file mode 100644 index 0000000..eff4911 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/application.properties @@ -0,0 +1,18 @@ +### web +server.port=8091 +server.context-path=/xxl-sso-web-sample-springboot + +### freemarker +spring.freemarker.request-context-attribute=request +spring.freemarker.cache=false + +### resource (default: /** + classpath:/static/ ) +spring.mvc.static-path-pattern=/static/** +spring.resources.static-locations=classpath:/static/ + +### xxl-sso +xxl.sso.server=http://xxlssoserver.com:8090/xxl-sso-server +xxl.sso.logout.path=/logout +xxl-sso.excluded.paths= +xxl.sso.redis.address=redis://127.0.0.1:6379 + diff --git a/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/logback.xml b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/logback.xml new file mode 100644 index 0000000..03a5074 --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/logback.xml @@ -0,0 +1,32 @@ + + + + logback + + + + + + %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n + + + + + ${log.path} + + ${log.path}.%d{yyyy-MM-dd}.zip + + + %date %level [%thread] %logger{36} [%file : %line] %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/templates/index.ftl b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/templates/index.ftl new file mode 100644 index 0000000..9f74c4d --- /dev/null +++ b/itools-sso/itools-sso-samples/itools-sso-web-sample-springboot/src/main/resources/templates/index.ftl @@ -0,0 +1,17 @@ + + + + + SSO Client + + + +
    +

    【${xxlUser.username}】login success.

    + + Logout + +
    + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-samples/pom.xml b/itools-sso/itools-sso-samples/pom.xml new file mode 100644 index 0000000..131951e --- /dev/null +++ b/itools-sso/itools-sso-samples/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + itools-sso + com.itools.core + 1.0-SNAPSHOT + + xxl-sso-samples + pom + + + itools-sso-web-sample-springboot + itools-sso-token-sample-springboot + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-server/pom.xml b/itools-sso/itools-sso-server/pom.xml new file mode 100644 index 0000000..86d88f8 --- /dev/null +++ b/itools-sso/itools-sso-server/pom.xml @@ -0,0 +1,85 @@ + + + 4.0.0 + + itools-sso + com.itools.core + 1.0-SNAPSHOT + + xxl-sso-server + jar + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring-boot.version} + pom + import + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + com.itools.core + xxl-sso-core + ${parent.version} + + + + + org.springframework.boot + spring-boot-devtools + provided + true + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + true + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/XxlSsoServerApplication.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/XxlSsoServerApplication.java new file mode 100644 index 0000000..2de58d4 --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/XxlSsoServerApplication.java @@ -0,0 +1,16 @@ +package com.itools.sso.server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author xuxueli 2018-03-22 23:41:47 + */ +@SpringBootApplication +public class XxlSsoServerApplication { + + public static void main(String[] args) { + SpringApplication.run(XxlSsoServerApplication.class, args); + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/config/XxlSsoConfig.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/config/XxlSsoConfig.java new file mode 100644 index 0000000..fe91d5e --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/config/XxlSsoConfig.java @@ -0,0 +1,33 @@ +package com.itools.sso.server.config; + +import com.itools.sso.core.store.SsoLoginStore; +import com.itools.sso.core.util.JedisUtil; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +/** + * @author xuxueli 2018-04-03 20:41:07 + */ +@Configuration +public class XxlSsoConfig implements InitializingBean, DisposableBean { + + @Value("${xxl.sso.redis.address}") + private String redisAddress; + + @Value("${xxl.sso.redis.expire.minite}") + private int redisExpireMinite; + + @Override + public void afterPropertiesSet() throws Exception { + SsoLoginStore.setRedisExpireMinite(redisExpireMinite); + JedisUtil.init(redisAddress); + } + + @Override + public void destroy() throws Exception { + JedisUtil.close(); + } + +} diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/AppController.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/AppController.java new file mode 100644 index 0000000..dc7abc3 --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/AppController.java @@ -0,0 +1,99 @@ +package com.itools.sso.server.controller; + +import com.itools.sso.core.login.SsoTokenLoginHelper; +import com.itools.sso.core.store.SsoLoginStore; +import com.itools.sso.core.user.XxlSsoUser; +import com.itools.sso.core.store.SsoSessionIdHelper; +import com.itools.sso.server.core.model.UserInfo; +import com.itools.sso.server.core.result.ReturnT; +import com.itools.sso.server.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.UUID; + +/** + * sso server (for app) + * + * @author xuxueli 2018-04-08 21:02:54 + */ +@Controller +@RequestMapping("/app") +public class AppController { + + @Autowired + private UserService userService; + + + /** + * Login + * + * @param username + * @param password + * @return + */ + @RequestMapping("/login") + @ResponseBody + public ReturnT login(String username, String password) { + + // valid login + ReturnT result = userService.findUser(username, password); + if (result.getCode() != ReturnT.SUCCESS_CODE) { + return new ReturnT(result.getCode(), result.getMsg()); + } + + // 1、make xxl-sso user + XxlSsoUser xxlUser = new XxlSsoUser(); + xxlUser.setUserid(String.valueOf(result.getData().getUserid())); + xxlUser.setUsername(result.getData().getUsername()); + xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", "")); + xxlUser.setExpireMinite(SsoLoginStore.getRedisExpireMinite()); + xxlUser.setExpireFreshTime(System.currentTimeMillis()); + + + // 2、generate sessionId + storeKey + String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser); + + // 3、login, store storeKey + SsoTokenLoginHelper.login(sessionId, xxlUser); + + // 4、return sessionId + return new ReturnT(sessionId); + } + + + /** + * Logout + * + * @param sessionId + * @return + */ + @RequestMapping("/logout") + @ResponseBody + public ReturnT logout(String sessionId) { + // logout, remove storeKey + SsoTokenLoginHelper.logout(sessionId); + return ReturnT.SUCCESS; + } + + /** + * logincheck + * + * @param sessionId + * @return + */ + @RequestMapping("/logincheck") + @ResponseBody + public ReturnT logincheck(String sessionId) { + + // logout + XxlSsoUser xxlUser = SsoTokenLoginHelper.loginCheck(sessionId); + if (xxlUser == null) { + return new ReturnT(ReturnT.FAIL_CODE, "sso not login."); + } + return new ReturnT(xxlUser); + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/WebController.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/WebController.java new file mode 100644 index 0000000..79cfacd --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/WebController.java @@ -0,0 +1,151 @@ +package com.itools.sso.server.controller; + +import com.itools.sso.core.conf.Conf; +import com.itools.sso.core.login.SsoWebLoginHelper; +import com.itools.sso.core.store.SsoLoginStore; +import com.itools.sso.core.user.XxlSsoUser; +import com.itools.sso.core.store.SsoSessionIdHelper; +import com.itools.sso.server.core.model.UserInfo; +import com.itools.sso.server.core.result.ReturnT; +import com.itools.sso.server.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.UUID; + +/** + * sso server (for web) + * + * @author xuxueli 2017-08-01 21:39:47 + */ +@Controller +public class WebController { + + @Autowired + private UserService userService; + + @RequestMapping("/") + public String index(Model model, HttpServletRequest request, HttpServletResponse response) { + + // login check + XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response); + + if (xxlUser == null) { + return "redirect:/login"; + } else { + model.addAttribute("xxlUser", xxlUser); + return "index"; + } + } + + /** + * Login page + * + * @param model + * @param request + * @return + */ + @RequestMapping(Conf.SSO_LOGIN) + public String login(Model model, HttpServletRequest request, HttpServletResponse response) { + + // login check + XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response); + + if (xxlUser != null) { + + // success redirect + String redirectUrl = request.getParameter(Conf.REDIRECT_URL); + if (redirectUrl!=null && redirectUrl.trim().length()>0) { + + String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request); + String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;; + + return "redirect:" + redirectUrlFinal; + } else { + return "redirect:/"; + } + } + + model.addAttribute("errorMsg", request.getParameter("errorMsg")); + model.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL)); + return "login"; + } + + /** + * Login + * + * @param request + * @param redirectAttributes + * @param username + * @param password + * @return + */ + @RequestMapping("/doLogin") + public String doLogin(HttpServletRequest request, + HttpServletResponse response, + RedirectAttributes redirectAttributes, + String username, + String password, + String ifRemember) { + + boolean ifRem = (ifRemember!=null&&"on".equals(ifRemember))?true:false; + + // valid login + ReturnT result = userService.findUser(username, password); + if (result.getCode() != ReturnT.SUCCESS_CODE) { + redirectAttributes.addAttribute("errorMsg", result.getMsg()); + + redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL)); + return "redirect:/login"; + } + + // 1、make xxl-sso user + XxlSsoUser xxlUser = new XxlSsoUser(); + xxlUser.setUserid(String.valueOf(result.getData().getUserid())); + xxlUser.setUsername(result.getData().getUsername()); + xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", "")); + xxlUser.setExpireMinite(SsoLoginStore.getRedisExpireMinite()); + xxlUser.setExpireFreshTime(System.currentTimeMillis()); + + + // 2、make session id + String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser); + + // 3、login, store storeKey + cookie sessionId + SsoWebLoginHelper.login(response, sessionId, xxlUser, ifRem); + + // 4、return, redirect sessionId + String redirectUrl = request.getParameter(Conf.REDIRECT_URL); + if (redirectUrl!=null && redirectUrl.trim().length()>0) { + String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId; + return "redirect:" + redirectUrlFinal; + } else { + return "redirect:/"; + } + + } + + /** + * Logout + * + * @param request + * @param redirectAttributes + * @return + */ + @RequestMapping(Conf.SSO_LOGOUT) + public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) { + + // logout + SsoWebLoginHelper.logout(request, response); + + redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL)); + return "redirect:/login"; + } + + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/interceptor/MyWebMvcConfigurer.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/interceptor/MyWebMvcConfigurer.java new file mode 100644 index 0000000..6ef1a9a --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/interceptor/MyWebMvcConfigurer.java @@ -0,0 +1,21 @@ +package com.itools.sso.server.controller.interceptor; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +/** + * web mvc config + * + * @author xuxueli 2018-04-02 20:48:20 + */ +@Configuration +public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter { + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new PermissionInterceptor()).addPathPatterns("/**"); + super.addInterceptors(registry); + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/interceptor/PermissionInterceptor.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/interceptor/PermissionInterceptor.java new file mode 100644 index 0000000..c44ffc5 --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/interceptor/PermissionInterceptor.java @@ -0,0 +1,38 @@ +package com.itools.sso.server.controller.interceptor; + +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author xuxueli 2015-12-12 18:09:04 + */ +public class PermissionInterceptor implements HandlerInterceptor { + + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + if (!(handler instanceof HandlerMethod)) { + return true; + } + + // TODO + + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + + } + +} diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/resolver/WebExceptionResolver.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/resolver/WebExceptionResolver.java new file mode 100644 index 0000000..b195429 --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/controller/resolver/WebExceptionResolver.java @@ -0,0 +1,72 @@ +package com.itools.sso.server.controller.resolver; + +import com.itools.sso.core.exception.XxlSsoException; +import com.itools.sso.server.core.result.ReturnT; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 统一异常处理(Controller切面方式实现) + * + * 1、@ControllerAdvice:扫描所有Controller; + * 2、@ControllerAdvice(annotations=RestController.class):扫描指定注解类型的Controller; + * 3、@ControllerAdvice(basePackages={"com.aaa","com.bbb"}):扫描指定package下的Controller + * + * @author xuxueli 2017-08-01 21:51:21 + */ +@Component +public class WebExceptionResolver implements HandlerExceptionResolver { + private static transient Logger logger = LoggerFactory.getLogger(WebExceptionResolver.class); + + @Override + public ModelAndView resolveException(HttpServletRequest request, + HttpServletResponse response, + Object handler, + Exception ex) { + + logger.error("WebExceptionResolver:{}", ex); + + // if json + boolean isJson = false; + HandlerMethod method = (HandlerMethod)handler; + ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class); + if (responseBody != null) { + isJson = true; + } + + // error result + ReturnT errorResult = null; + if (ex instanceof XxlSsoException) { + errorResult = new ReturnT(ReturnT.FAIL_CODE, ex.getMessage()); + } else { + errorResult = new ReturnT(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "
    ")); + } + + // response + ModelAndView mv = new ModelAndView(); + if (isJson) { + try { + response.setContentType("application/json;charset=utf-8"); + response.getWriter().print("{\"code\":"+errorResult.getCode()+", \"msg\":\""+ errorResult.getMsg() +"\"}"); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + return mv; + } else { + + mv.addObject("exceptionMsg", errorResult.getMsg()); + mv.setViewName("/common/common.exception"); + return mv; + } + } + +} \ No newline at end of file diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/core/model/UserInfo.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/core/model/UserInfo.java new file mode 100644 index 0000000..1181bba --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/core/model/UserInfo.java @@ -0,0 +1,36 @@ +package com.itools.sso.server.core.model; + +/** + * @author xuxueli 2018-03-22 23:51:51 + */ +public class UserInfo { + + private int userid; + private String username; + private String password; + + public int getUserid() { + return userid; + } + + public void setUserid(int userid) { + this.userid = userid; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/core/result/ReturnT.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/core/result/ReturnT.java new file mode 100644 index 0000000..8e16b4f --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/core/result/ReturnT.java @@ -0,0 +1,51 @@ +package com.itools.sso.server.core.result; + +import java.io.Serializable; + +/** + * common return + * + * @author xuxueli 2015-12-4 16:32:31 + * @param + */ +public class ReturnT implements Serializable { + public static final long serialVersionUID = 42L; + + public static final int SUCCESS_CODE = 200; + public static final int FAIL_CODE = 500; + public static final ReturnT SUCCESS = new ReturnT(null); + public static final ReturnT FAIL = new ReturnT(FAIL_CODE, null); + + private int code; + private String msg; + private T data; + + public ReturnT(int code, String msg) { + this.code = code; + this.msg = msg; + } + public ReturnT(T data) { + this.code = SUCCESS_CODE; + this.data = data; + } + + public int getCode() { + return code; + } + public void setCode(int code) { + this.code = code; + } + public String getMsg() { + return msg; + } + public void setMsg(String msg) { + this.msg = msg; + } + public T getData() { + return data; + } + public void setData(T data) { + this.data = data; + } + +} diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/service/UserService.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/service/UserService.java new file mode 100644 index 0000000..95fa711 --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/service/UserService.java @@ -0,0 +1,10 @@ +package com.itools.sso.server.service; + +import com.itools.sso.server.core.model.UserInfo; +import com.itools.sso.server.core.result.ReturnT; + +public interface UserService { + + public ReturnT findUser(String username, String password); + +} diff --git a/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/service/impl/UserServiceImpl.java b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..8dbce48 --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/java/com/itools/sso/server/service/impl/UserServiceImpl.java @@ -0,0 +1,46 @@ +package com.itools.sso.server.service.impl; + +import com.itools.sso.server.core.model.UserInfo; +import com.itools.sso.server.core.result.ReturnT; +import com.itools.sso.server.service.UserService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class UserServiceImpl implements UserService { + + private static List mockUserList = new ArrayList<>(); + static { + for (int i = 0; i <5; i++) { + UserInfo userInfo = new UserInfo(); + userInfo.setUserid(1000+i); + userInfo.setUsername("user" + (i>0?String.valueOf(i):"")); + userInfo.setPassword("123456"); + mockUserList.add(userInfo); + } + } + + @Override + public ReturnT findUser(String username, String password) { + + if (username==null || username.trim().length()==0) { + return new ReturnT(ReturnT.FAIL_CODE, "Please input username."); + } + if (password==null || password.trim().length()==0) { + return new ReturnT(ReturnT.FAIL_CODE, "Please input password."); + } + + // mock user + for (UserInfo mockUser: mockUserList) { + if (mockUser.getUsername().equals(username) && mockUser.getPassword().equals(password)) { + return new ReturnT(mockUser); + } + } + + return new ReturnT(ReturnT.FAIL_CODE, "username or password is invalid."); + } + + +} diff --git a/itools-sso/itools-sso-server/src/main/resources/application.properties b/itools-sso/itools-sso-server/src/main/resources/application.properties new file mode 100644 index 0000000..d349c4d --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/resources/application.properties @@ -0,0 +1,18 @@ +### web +server.port=8090 +server.context-path=/xxl-sso-server + +### resources +spring.mvc.static-path-pattern=/static/** +spring.resources.static-locations=classpath:/static/ + +### freemarker +spring.freemarker.templateLoaderPath=classpath:/templates/ +spring.freemarker.suffix=.ftl +spring.freemarker.charset=UTF-8 +spring.freemarker.request-context-attribute=request +spring.freemarker.settings.number_format=0.########## + +### xxl-sso +xxl.sso.redis.address=redis://127.0.0.1:6379 +xxl.sso.redis.expire.minite=1440 diff --git a/itools-sso/itools-sso-server/src/main/resources/logback.xml b/itools-sso/itools-sso-server/src/main/resources/logback.xml new file mode 100644 index 0000000..9b5ae60 --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/resources/logback.xml @@ -0,0 +1,32 @@ + + + + logback + + + + + + %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n + + + + + ${log.path} + + ${log.path}.%d{yyyy-MM-dd}.zip + + + %date %level [%thread] %logger{36} [%file : %line] %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/css/bootstrap.css.map b/itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/css/bootstrap.css.map new file mode 100644 index 0000000..f010c82 --- /dev/null +++ b/itools-sso/itools-sso-server/src/main/resources/static/adminlte/bootstrap/css/bootstrap.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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AW,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;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ukDH;AexkDC;EACE,oBAAA;Cf0kDH;Ae3kDC;EACE,WAAA;Cf6kDH;Ae9kDC;EACE,oBAAA;CfglDH;AejlDC;EACE,mBAAA;CfmlDH;Ae/kDC;EACE,YAAA;CfilDH;AejmDC;EACE,WAAA;CfmmDH;AepmDC;EACE,mBAAA;CfsmDH;AevmDC;EACE,mBAAA;CfymDH;Ae1mDC;EACE,UAAA;Cf4mDH;Ae7mDC;EACE,mBAAA;Cf+mDH;AehnDC;EACE,mBAAA;CfknDH;AennDC;EACE,UAAA;CfqnDH;AetnDC;EACE,mBAAA;CfwnDH;AeznDC;EACE,mBAAA;Cf2nDH;Ae5nDC;EACE,UAAA;Cf8nDH;Ae/nDC;EACE,mBAAA;CfioDH;AeloDC;EACE,kBAAA;CfooDH;AehoDC;EACE,WAAA;CfkoDH;AepnDC;EACE,kBAAA;CfsnDH;AevnDC;EACE,0BAAA;CfynDH;Ae1nDC;EACE,0BAAA;Cf4nDH;Ae7nDC;EACE,iBAAA;Cf+nDH;AehoDC;EACE,0BAAA;CfkoDH;AenoDC;EACE,0BAAA;CfqoDH;AetoDC;EACE,iBAAA;CfwoDH;AezoDC;EACE,0BAAA;Cf2oDH;Ae5oDC;EACE,0BAAA;Cf8oDH;Ae/oDC;EACE,iBAAA;CfipDH;AelpDC;EACE,0BAAA;CfopDH;AerpDC;EACE,yBAAA;CfupDH;AexpDC;EACE,gBAAA;Cf0pDH;Aa1pDD;EElCI;IACE,YAAA;Gf+rDH;EexrDD;IACE,YAAA;Gf0rDD;Ee3rDD;IACE,oBAAA;Gf6rDD;Ee9rDD;IACE,oBAAA;GfgsDD;EejsDD;IACE,WAAA;GfmsDD;EepsDD;IACE,oBAAA;GfssDD;EevsDD;IACE,oBAAA;GfysDD;Ee1sDD;IACE,WAAA;Gf4sDD;Ee7sDD;IACE,oBAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,WAAA;GfqtDD;EettDD;IACE,oBAAA;GfwtDD;EeztDD;IACE,mBAAA;Gf2tDD;Ee7sDD;IACE,YAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,oBAAA;GfqtDD;EettDD;IACE,WAAA;GfwtDD;EeztDD;IACE,oBAAA;Gf2tDD;Ee5tDD;IACE,oBAAA;Gf8tDD;Ee/tDD;IACE,WAAA;GfiuDD;EeluDD;IACE,oBAAA;GfouDD;EeruDD;IACE,oBAAA;GfuuDD;EexuDD;IACE,WAAA;Gf0uDD;Ee3uDD;IACE,oBAAA;Gf6uDD;Ee9uDD;IACE,mBAAA;GfgvDD;Ee5uDD;IACE,YAAA;Gf8uDD;Ee9vDD;IACE,WAAA;GfgwDD;EejwDD;IACE,mBAAA;GfmwDD;EepwDD;IACE,mBAAA;GfswDD;EevwDD;IACE,UAAA;GfywDD;Ee1wDD;IACE,mBAAA;Gf4wDD;Ee7wDD;IACE,mBAAA;Gf+wDD;EehxDD;IACE,UAAA;GfkxDD;EenxDD;IACE,mBAAA;GfqxDD;EetxDD;IACE,mBAAA;GfwxDD;EezxDD;IACE,UAAA;Gf2xDD;Ee5xDD;IACE,mBAAA;Gf8xDD;Ee/xDD;IACE,kBAAA;GfiyDD;Ee7xDD;IACE,WAAA;Gf+xDD;EejxDD;IACE,kBAAA;GfmxDD;EepxDD;IACE,0BAAA;GfsxDD;EevxDD;IACE,0BAAA;GfyxDD;Ee1xDD;IACE,iBAAA;Gf4xDD;Ee7xDD;IACE,0BAAA;Gf+xDD;EehyDD;IACE,0BAAA;GfkyDD;EenyDD;IACE,iBAAA;GfqyDD;EetyDD;IACE,0BAAA;GfwyDD;EezyDD;IACE,0BAAA;Gf2yDD;Ee5yDD;IACE,iBAAA;Gf8yDD;Ee/yDD;IACE,0BAAA;GfizDD;EelzDD;IACE,yBAAA;GfozDD;EerzDD;IACE,gBAAA;GfuzDD;CACF;Aa/yDD;EE3CI;IACE,YAAA;Gf61DH;Eet1DD;IACE,YAAA;Gfw1DD;Eez1DD;IACE,oBAAA;Gf21DD;Ee51DD;IACE,oBAAA;Gf81DD;Ee/1DD;IACE,WAAA;Gfi2DD;Eel2DD;IACE,oBAAA;Gfo2DD;Eer2DD;IACE,oBAAA;Gfu2DD;Eex2DD;IACE,WAAA;Gf02DD;Ee32DD;IACE,oBAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,WAAA;Gfm3DD;Eep3DD;IACE,oBAAA;Gfs3DD;Eev3DD;IACE,mBAAA;Gfy3DD;Ee32DD;IACE,YAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,oBAAA;Gfm3DD;Eep3DD;IACE,WAAA;Gfs3DD;Eev3DD;IACE,oBAAA;Gfy3DD;Ee13DD;IACE,oBAAA;Gf43DD;Ee73DD;IACE,WAAA;Gf+3DD;Eeh4DD;IACE,oBAAA;Gfk4DD;Een4DD;IACE,oBAAA;Gfq4DD;Eet4DD;IACE,WAAA;Gfw4DD;Eez4DD;IACE,oBAAA;Gf24DD;Ee54DD;IACE,mBAAA;Gf84DD;Ee14DD;IACE,YAAA;Gf44DD;Ee55DD;IACE,WAAA;Gf85DD;Ee/5DD;IACE,mBAAA;Gfi6DD;Eel6DD;IACE,mBAAA;Gfo6DD;Eer6DD;IACE,UAAA;Gfu6DD;Eex6DD;IACE,mBAAA;Gf06DD;Ee36DD;IACE,mBAAA;Gf66DD;Ee96DD;IACE,UAAA;Gfg7DD;Eej7DD;IACE,mBAAA;Gfm7DD;Eep7DD;IACE,mBAAA;Gfs7DD;Eev7DD;IACE,UAAA;Gfy7DD;Ee17DD;IACE,mBAAA;Gf47DD;Ee77DD;IACE,kBAAA;Gf+7DD;Ee37DD;IACE,WAAA;Gf67DD;Ee/6DD;IACE,kBAAA;Gfi7DD;Eel7DD;IACE,0BAAA;Gfo7DD;Eer7DD;IACE,0BAAA;Gfu7DD;Eex7DD;IACE,iBAAA;Gf07DD;Ee37DD;IACE,0BAAA;Gf67DD;Ee97DD;IACE,0BAAA;Gfg8DD;Eej8DD;IACE,iBAAA;Gfm8DD;Eep8DD;IACE,0BAAA;Gfs8DD;Eev8DD;IACE,0BAAA;Gfy8DD;Ee18DD;IACE,iBAAA;Gf48DD;Ee78DD;IACE,0BAAA;Gf+8DD;Eeh9DD;IACE,yBAAA;Gfk9DD;Een9DD;IACE,gBAAA;Gfq9DD;CACF;Aa18DD;EE9CI;IACE,YAAA;Gf2/DH;Eep/DD;IACE,YAAA;Gfs/DD;Eev/DD;IACE,oBAAA;Gfy/DD;Ee1/DD;IACE,oBAAA;Gf4/DD;Ee7/DD;IACE,WAAA;Gf+/DD;EehgED;IACE,oBAAA;GfkgED;EengED;IACE,oBAAA;GfqgED;EetgED;IACE,WAAA;GfwgED;EezgED;IACE,oBAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,WAAA;GfihED;EelhED;IACE,oBAAA;GfohED;EerhED;IACE,mBAAA;GfuhED;EezgED;IACE,YAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,oBAAA;GfihED;EelhED;IACE,WAAA;GfohED;EerhED;IACE,oBAAA;GfuhED;EexhED;IACE,oBAAA;Gf0hED;Ee3hED;IACE,WAAA;Gf6hED;Ee9hED;IACE,oBAAA;GfgiED;EejiED;IACE,oBAAA;GfmiED;EepiED;IACE,WAAA;GfsiED;EeviED;IACE,oBAAA;GfyiED;Ee1iED;IACE,mBAAA;Gf4iED;EexiED;IACE,YAAA;Gf0iED;Ee1jED;IACE,WAAA;Gf4jED;Ee7jED;IACE,mBAAA;Gf+jED;EehkED;IACE,mBAAA;GfkkED;EenkED;IACE,UAAA;GfqkED;EetkED;IACE,mBAAA;GfwkED;EezkED;IACE,mBAAA;Gf2kED;Ee5kED;IACE,UAAA;Gf8kED;Ee/kED;IACE,mBAAA;GfilED;EellED;IACE,mBAAA;GfolED;EerlED;IACE,UAAA;GfulED;EexlED;IACE,mBAAA;Gf0lED;Ee3lED;IACE,kBAAA;Gf6lED;EezlED;IACE,WAAA;Gf2lED;Ee7kED;IACE,kBAAA;Gf+kED;EehlED;IACE,0BAAA;GfklED;EenlED;IACE,0BAAA;GfqlED;EetlED;IACE,iBAAA;GfwlED;EezlED;IACE,0BAAA;Gf2lED;Ee5lED;IACE,0BAAA;Gf8lED;Ee/lED;IACE,iBAAA;GfimED;EelmED;IACE,0BAAA;GfomED;EermED;IACE,0BAAA;GfumED;EexmED;IACE,iBAAA;Gf0mED;Ee3mED;IACE,0BAAA;Gf6mED;Ee9mED;IACE,yBAAA;GfgnED;EejnED;IACE,gBAAA;GfmnED;CACF;AgBvrED;EACE,8BAAA;ChByrED;AgBvrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChByrED;AgBvrED;EACE,iBAAA;ChByrED;AgBnrED;EACE,YAAA;EACA,gBAAA;EACA,oBAAA;ChBqrED;AgBxrED;;;;;;EAWQ,aAAA;EACA,wBAAA;EACA,oBAAA;EACA,2BAAA;ChBqrEP;AgBnsED;EAoBI,uBAAA;EACA,8BAAA;ChBkrEH;AgBvsED;;;;;;EA8BQ,cAAA;ChBirEP;AgB/sED;EAoCI,2BAAA;ChB8qEH;AgBltED;EAyCI,uBAAA;ChB4qEH;AgBrqED;;;;;;EAOQ,aAAA;ChBsqEP;AgB3pED;EACE,uBAAA;ChB6pED;AgB9pED;;;;;;EAQQ,uBAAA;ChB8pEP;AgBtqED;;EAeM,yBAAA;ChB2pEL;AgBjpED;EAEI,0BAAA;ChBkpEH;AgBzoED;EAEI,0BAAA;ChB0oEH;AgBjoED;EACE,iBAAA;EACA,YAAA;EACA,sBAAA;ChBmoED;AgB9nEG;;EACE,iBAAA;EACA,YAAA;EACA,oBAAA;ChBioEL;AiB7wEC;;;;;;;;;;;;EAOI,0BAAA;CjBoxEL;AiB9wEC;;;;;EAMI,0BAAA;CjB+wEL;AiBlyEC;;;;;;;;;;;;EAOI,0BAAA;CjByyEL;AiBnyEC;;;;;EAMI,0BAAA;CjBoyEL;AiBvzEC;;;;;;;;;;;;EAOI,0BAAA;CjB8zEL;AiBxzEC;;;;;EAMI,0BAAA;CjByzEL;AiB50EC;;;;;;;;;;;;EAOI,0BAAA;CjBm1EL;AiB70EC;;;;;EAMI,0BAAA;CjB80EL;AiBj2EC;;;;;;;;;;;;EAOI,0BAAA;CjBw2EL;AiBl2EC;;;;;EAMI,0BAAA;CjBm2EL;AgBjtED;EACE,iBAAA;EACA,kBAAA;ChBmtED;AgBtpED;EACA;IA3DI,YAAA;IACA,oBAAA;IACA,mBAAA;IACA,6CAAA;IACA,uBAAA;GhBotED;EgB7pEH;IAnDM,iBAAA;GhBmtEH;EgBhqEH;;;;;;IA1CY,oBAAA;GhBktET;EgBxqEH;IAlCM,UAAA;GhB6sEH;EgB3qEH;;;;;;IAzBY,eAAA;GhB4sET;EgBnrEH;;;;;;IArBY,gBAAA;GhBgtET;EgB3rEH;;;;IARY,iBAAA;GhBysET;CACF;AkBn6ED;EACE,WAAA;EACA,UAAA;EACA,UAAA;EAIA,aAAA;ClBk6ED;AkB/5ED;EACE,eAAA;EACA,YAAA;EACA,WAAA;EACA,oBAAA;EACA,gBAAA;EACA,qBAAA;EACA,eAAA;EACA,UAAA;EACA,iCAAA;ClBi6ED;AkB95ED;EACE,sBAAA;EACA,gBAAA;EACA,mBAAA;EACA,kBAAA;ClBg6ED;AkBr5ED;Eb4BE,+BAAA;EACG,4BAAA;EACK,uBAAA;CL43ET;AkBr5ED;;EAEE,gBAAA;EACA,mBAAA;EACA,oBAAA;ClBu5ED;AkBp5ED;EACE,eAAA;ClBs5ED;AkBl5ED;EACE,eAAA;EACA,YAAA;ClBo5ED;AkBh5ED;;EAEE,aAAA;ClBk5ED;AkB94ED;;;EZrEE,2CAAA;EACA,qBAAA;CNw9ED;AkB74ED;EACE,eAAA;EACA,iBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;ClB+4ED;AkBr3ED;EACE,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;EbxDA,yDAAA;EACQ,iDAAA;EAyHR,uFAAA;EACK,0EAAA;EACG,uEAAA;CLwzET;AmBh8EC;EACE,sBAAA;EACA,WAAA;EdUF,uFAAA;EACQ,+EAAA;CLy7ET;AKx5EC;EACE,YAAA;EACA,WAAA;CL05EH;AKx5EC;EAA0B,YAAA;CL25E3B;AK15EC;EAAgC,YAAA;CL65EjC;AkBj4EC;EACE,UAAA;EACA,8BAAA;ClBm4EH;AkB33EC;;;EAGE,0BAAA;EACA,WAAA;ClB63EH;AkB13EC;;EAEE,oBAAA;ClB43EH;AkBx3EC;EACE,aAAA;ClB03EH;AkB92ED;EACE,yBAAA;ClBg3ED;AkBx0ED;EAtBI;;;;IACE,kBAAA;GlBo2EH;EkBj2EC;;;;;;;;IAEE,kBAAA;GlBy2EH;EkBt2EC;;;;;;;;IAEE,kBAAA;GlB82EH;CACF;AkBp2ED;EACE,oBAAA;ClBs2ED;AkB91ED;;EAEE,mBAAA;EACA,eAAA;EACA,iBAAA;EACA,oBAAA;ClBg2ED;AkBr2ED;;EAQI,iBAAA;EACA,mBAAA;EACA,iBAAA;EACA,oBAAA;EACA,gBAAA;ClBi2EH;AkB91ED;;;;EAIE,mBAAA;EACA,mBAAA;EACA,mBAAA;ClBg2ED;AkB71ED;;EAEE,iBAAA;ClB+1ED;AkB31ED;;EAEE,mBAAA;EACA,sBAAA;EACA,mBAAA;EACA,iBAAA;EACA,uBAAA;EACA,oBAAA;EACA,gBAAA;ClB61ED;AkB31ED;;EAEE,cAAA;EACA,kBAAA;ClB61ED;AkBp1EC;;;;;;EAGE,oBAAA;ClBy1EH;AkBn1EC;;;;EAEE,oBAAA;ClBu1EH;AkBj1EC;;;;EAGI,oBAAA;ClBo1EL;AkBz0ED;EAEE,iBAAA;EACA,oBAAA;EAEA,iBAAA;EACA,iBAAA;ClBy0ED;AkBv0EC;;EAEE,gBAAA;EACA,iBAAA;ClBy0EH;AkB5zED;ECnQE,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CnBkkFD;AmBhkFC;EACE,aAAA;EACA,kBAAA;CnBkkFH;AmB/jFC;;EAEE,aAAA;CnBikFH;AkBx0ED;EAEI,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;ClBy0EH;AkB/0ED;EASI,aAAA;EACA,kBAAA;ClBy0EH;AkBn1ED;;EAcI,aAAA;ClBy0EH;AkBv1ED;EAiBI,aAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;ClBy0EH;AkBr0ED;EC/RE,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CnBumFD;AmBrmFC;EACE,aAAA;EACA,kBAAA;CnBumFH;AmBpmFC;;EAEE,aAAA;CnBsmFH;AkBj1ED;EAEI,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;ClBk1EH;AkBx1ED;EASI,aAAA;EACA,kBAAA;ClBk1EH;AkB51ED;;EAcI,aAAA;ClBk1EH;AkBh2ED;EAiBI,aAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;ClBk1EH;AkBz0ED;EAEE,mBAAA;ClB00ED;AkB50ED;EAMI,sBAAA;ClBy0EH;AkBr0ED;EACE,mBAAA;EACA,OAAA;EACA,SAAA;EACA,WAAA;EACA,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,mBAAA;EACA,qBAAA;ClBu0ED;AkBr0ED;;;EAGE,YAAA;EACA,aAAA;EACA,kBAAA;ClBu0ED;AkBr0ED;;;EAGE,YAAA;EACA,aAAA;EACA,kBAAA;ClBu0ED;AkBn0ED;;;;;;;;;;EC1ZI,eAAA;CnByuFH;AkB/0ED;ECtZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CL0rFT;AmBxuFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL+rFT;AkBz1ED;EC5YI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBwuFH;AkB91ED;ECtYI,eAAA;CnBuuFH;AkB91ED;;;;;;;;;;EC7ZI,eAAA;CnBuwFH;AkB12ED;ECzZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CLwtFT;AmBtwFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL6tFT;AkBp3ED;EC/YI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBswFH;AkBz3ED;ECzYI,eAAA;CnBqwFH;AkBz3ED;;;;;;;;;;EChaI,eAAA;CnBqyFH;AkBr4ED;EC5ZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CLsvFT;AmBpyFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL2vFT;AkB/4ED;EClZI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBoyFH;AkBp5ED;EC5YI,eAAA;CnBmyFH;AkBh5EC;EACE,UAAA;ClBk5EH;AkBh5EC;EACE,OAAA;ClBk5EH;AkBx4ED;EACE,eAAA;EACA,gBAAA;EACA,oBAAA;EACA,eAAA;ClB04ED;AkBvzED;EAwEA;IAtIM,sBAAA;IACA,iBAAA;IACA,uBAAA;GlBy3EH;EkBrvEH;IA/HM,sBAAA;IACA,YAAA;IACA,uBAAA;GlBu3EH;EkB1vEH;IAxHM,sBAAA;GlBq3EH;EkB7vEH;IApHM,sBAAA;IACA,uBAAA;GlBo3EH;EkBjwEH;;;IA9GQ,YAAA;GlBo3EL;EkBtwEH;IAxGM,YAAA;GlBi3EH;EkBzwEH;IApGM,iBAAA;IACA,uBAAA;GlBg3EH;EkB7wEH;;IA5FM,sBAAA;IACA,cAAA;IACA,iBAAA;IACA,uBAAA;GlB62EH;EkBpxEH;;IAtFQ,gBAAA;GlB82EL;EkBxxEH;;IAjFM,mBAAA;IACA,eAAA;GlB62EH;EkB7xEH;IA3EM,OAAA;GlB22EH;CACF;AkBj2ED;;;;EASI,cAAA;EACA,iBAAA;EACA,iBAAA;ClB81EH;AkBz2ED;;EAiBI,iBAAA;ClB41EH;AkB72ED;EJthBE,mBAAA;EACA,oBAAA;Cds4FD;AkB10EC;EAyBF;IAnCM,kBAAA;IACA,iBAAA;IACA,iBAAA;GlBw1EH;CACF;AkBx3ED;EAwCI,YAAA;ClBm1EH;AkBr0EC;EAUF;IAdQ,kBAAA;IACA,gBAAA;GlB60EL;CACF;AkBn0EC;EAEF;IANQ,iBAAA;IACA,gBAAA;GlB20EL;CACF;AoBp6FD;EACE,sBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,uBAAA;EACA,+BAAA;MAAA,2BAAA;EACA,gBAAA;EACA,uBAAA;EACA,8BAAA;EACA,oBAAA;EC0CA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,mBAAA;EhB+JA,0BAAA;EACG,uBAAA;EACC,sBAAA;EACI,kBAAA;CL+tFT;AoBv6FG;;;;;;EdnBF,2CAAA;EACA,qBAAA;CNk8FD;AoB16FC;;;EAGE,YAAA;EACA,sBAAA;CpB46FH;AoBz6FC;;EAEE,WAAA;EACA,uBAAA;Ef2BF,yDAAA;EACQ,iDAAA;CLi5FT;AoBz6FC;;;EAGE,oBAAA;EE7CF,cAAA;EAGA,0BAAA;EjB8DA,yBAAA;EACQ,iBAAA;CL05FT;AoBz6FG;;EAEE,qBAAA;CpB26FL;AoBl6FD;EC3DE,YAAA;EACA,uBAAA;EACA,mBAAA;CrBg+FD;AqB99FC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBs+FT;AqBn+FC;;;EAGE,uBAAA;CrBq+FH;AqBh+FG;;;;;;;;;EAGE,uBAAA;EACI,mBAAA;CrBw+FT;AoBv9FD;ECZI,YAAA;EACA,uBAAA;CrBs+FH;AoBx9FD;EC9DE,YAAA;EACA,0BAAA;EACA,sBAAA;CrByhGD;AqBvhGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB+hGT;AqB5hGC;;;EAGE,uBAAA;CrB8hGH;AqBzhGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBiiGT;AoB7gGD;ECfI,eAAA;EACA,uBAAA;CrB+hGH;AoB7gGD;EClEE,YAAA;EACA,0BAAA;EACA,sBAAA;CrBklGD;AqBhlGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBwlGT;AqBrlGC;;;EAGE,uBAAA;CrBulGH;AqBllGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrB0lGT;AoBlkGD;ECnBI,eAAA;EACA,uBAAA;CrBwlGH;AoBlkGD;ECtEE,YAAA;EACA,0BAAA;EACA,sBAAA;CrB2oGD;AqBzoGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBipGT;AqB9oGC;;;EAGE,uBAAA;CrBgpGH;AqB3oGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBmpGT;AoBvnGD;ECvBI,eAAA;EACA,uBAAA;CrBipGH;AoBvnGD;EC1EE,YAAA;EACA,0BAAA;EACA,sBAAA;CrBosGD;AqBlsGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB0sGT;AqBvsGC;;;EAGE,uBAAA;CrBysGH;AqBpsGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrB4sGT;AoB5qGD;EC3BI,eAAA;EACA,uBAAA;CrB0sGH;AoB5qGD;EC9EE,YAAA;EACA,0BAAA;EACA,sBAAA;CrB6vGD;AqB3vGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBmwGT;AqBhwGC;;;EAGE,uBAAA;CrBkwGH;AqB7vGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBqwGT;AoBjuGD;EC/BI,eAAA;EACA,uBAAA;CrBmwGH;AoB5tGD;EACE,eAAA;EACA,oBAAA;EACA,iBAAA;CpB8tGD;AoB5tGC;;;;;EAKE,8BAAA;EfnCF,yBAAA;EACQ,iBAAA;CLkwGT;AoB7tGC;;;;EAIE,0BAAA;CpB+tGH;AoB7tGC;;EAEE,eAAA;EACA,2BAAA;EACA,8BAAA;CpB+tGH;AoB3tGG;;;;EAEE,eAAA;EACA,sBAAA;CpB+tGL;AoBttGD;;ECxEE,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CrBkyGD;AoBztGD;;EC5EE,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CrByyGD;AoB5tGD;;EChFE,iBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CrBgzGD;AoB3tGD;EACE,eAAA;EACA,YAAA;CpB6tGD;AoBztGD;EACE,gBAAA;CpB2tGD;AoBptGC;;;EACE,YAAA;CpBwtGH;AuBl3GD;EACE,WAAA;ElBoLA,yCAAA;EACK,oCAAA;EACG,iCAAA;CLisGT;AuBr3GC;EACE,WAAA;CvBu3GH;AuBn3GD;EACE,cAAA;CvBq3GD;AuBn3GC;EAAY,eAAA;CvBs3Gb;AuBr3GC;EAAY,mBAAA;CvBw3Gb;AuBv3GC;EAAY,yBAAA;CvB03Gb;AuBv3GD;EACE,mBAAA;EACA,UAAA;EACA,iBAAA;ElBuKA,gDAAA;EACQ,2CAAA;KAAA,wCAAA;EAOR,mCAAA;EACQ,8BAAA;KAAA,2BAAA;EAGR,yCAAA;EACQ,oCAAA;KAAA,iCAAA;CL2sGT;AwBr5GD;EACE,sBAAA;EACA,SAAA;EACA,UAAA;EACA,iBAAA;EACA,uBAAA;EACA,uBAAA;EACA,yBAAA;EACA,oCAAA;EACA,mCAAA;CxBu5GD;AwBn5GD;;EAEE,mBAAA;CxBq5GD;AwBj5GD;EACE,WAAA;CxBm5GD;AwB/4GD;EACE,mBAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,cAAA;EACA,YAAA;EACA,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,iBAAA;EACA,uBAAA;EACA,uBAAA;EACA,sCAAA;EACA,mBAAA;EnBsBA,oDAAA;EACQ,4CAAA;EmBrBR,qCAAA;UAAA,6BAAA;CxBk5GD;AwB74GC;EACE,SAAA;EACA,WAAA;CxB+4GH;AwBx6GD;ECzBE,YAAA;EACA,cAAA;EACA,iBAAA;EACA,0BAAA;CzBo8GD;AwB96GD;EAmCI,eAAA;EACA,kBAAA;EACA,YAAA;EACA,oBAAA;EACA,wBAAA;EACA,eAAA;EACA,oBAAA;CxB84GH;AwBx4GC;;EAEE,sBAAA;EACA,eAAA;EACA,0BAAA;CxB04GH;AwBp4GC;;;EAGE,YAAA;EACA,sBAAA;EACA,WAAA;EACA,0BAAA;CxBs4GH;AwB73GC;;;EAGE,eAAA;CxB+3GH;AwB33GC;;EAEE,sBAAA;EACA,8BAAA;EACA,uBAAA;EE3GF,oEAAA;EF6GE,oBAAA;CxB63GH;AwBx3GD;EAGI,eAAA;CxBw3GH;AwB33GD;EAQI,WAAA;CxBs3GH;AwB92GD;EACE,WAAA;EACA,SAAA;CxBg3GD;AwBx2GD;EACE,QAAA;EACA,YAAA;CxB02GD;AwBt2GD;EACE,eAAA;EACA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,oBAAA;CxBw2GD;AwBp2GD;EACE,gBAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,OAAA;EACA,aAAA;CxBs2GD;AwBl2GD;EACE,SAAA;EACA,WAAA;CxBo2GD;AwB51GD;;EAII,cAAA;EACA,0BAAA;EACA,4BAAA;EACA,YAAA;CxB41GH;AwBn2GD;;EAWI,UAAA;EACA,aAAA;EACA,mBAAA;CxB41GH;AwBv0GD;EAXE;IApEA,WAAA;IACA,SAAA;GxB05GC;EwBv1GD;IA1DA,QAAA;IACA,YAAA;GxBo5GC;CACF;A2BpiHD;;EAEE,mBAAA;EACA,sBAAA;EACA,uBAAA;C3BsiHD;A2B1iHD;;EAMI,mBAAA;EACA,YAAA;C3BwiHH;A2BtiHG;;;;;;;;EAIE,WAAA;C3B4iHL;A2BtiHD;;;;EAKI,kBAAA;C3BuiHH;A2BliHD;EACE,kBAAA;C3BoiHD;A2BriHD;;;EAOI,YAAA;C3BmiHH;A2B1iHD;;;EAYI,iBAAA;C3BmiHH;A2B/hHD;EACE,iBAAA;C3BiiHD;A2B7hHD;EACE,eAAA;C3B+hHD;A2B9hHC;EClDA,8BAAA;EACG,2BAAA;C5BmlHJ;A2B7hHD;;EC/CE,6BAAA;EACG,0BAAA;C5BglHJ;A2B5hHD;EACE,YAAA;C3B8hHD;A2B5hHD;EACE,iBAAA;C3B8hHD;A2B5hHD;;ECnEE,8BAAA;EACG,2BAAA;C5BmmHJ;A2B3hHD;ECjEE,6BAAA;EACG,0BAAA;C5B+lHJ;A2B1hHD;;EAEE,WAAA;C3B4hHD;A2B3gHD;EACE,kBAAA;EACA,mBAAA;C3B6gHD;A2B3gHD;EACE,mBAAA;EACA,oBAAA;C3B6gHD;A2BxgHD;EtB/CE,yDAAA;EACQ,iDAAA;CL0jHT;A2BxgHC;EtBnDA,yBAAA;EACQ,iBAAA;CL8jHT;A2BrgHD;EACE,eAAA;C3BugHD;A2BpgHD;EACE,wBAAA;EACA,uBAAA;C3BsgHD;A2BngHD;EACE,wBAAA;C3BqgHD;A2B9/GD;;;EAII,eAAA;EACA,YAAA;EACA,YAAA;EACA,gBAAA;C3B+/GH;A2BtgHD;EAcM,YAAA;C3B2/GL;A2BzgHD;;;;EAsBI,iBAAA;EACA,eAAA;C3By/GH;A2Bp/GC;EACE,iBAAA;C3Bs/GH;A2Bp/GC;EC3KA,6BAAA;EACC,4BAAA;EAOD,8BAAA;EACC,6BAAA;C5B4pHF;A2Bt/GC;EC/KA,2BAAA;EACC,0BAAA;EAOD,gCAAA;EACC,+BAAA;C5BkqHF;A2Bv/GD;EACE,iBAAA;C3By/GD;A2Bv/GD;;EC/KE,8BAAA;EACC,6BAAA;C5B0qHF;A2Bt/GD;EC7LE,2BAAA;EACC,0BAAA;C5BsrHF;A2Bl/GD;EACE,eAAA;EACA,YAAA;EACA,oBAAA;EACA,0BAAA;C3Bo/GD;A2Bx/GD;;EAOI,YAAA;EACA,oBAAA;EACA,UAAA;C3Bq/GH;A2B9/GD;EAYI,YAAA;C3Bq/GH;A2BjgHD;EAgBI,WAAA;C3Bo/GH;A2Bn+GD;;;;EAKM,mBAAA;EACA,uBAAA;EACA,qBAAA;C3Bo+GL;A6B9sHD;EACE,mBAAA;EACA,eAAA;EACA,0BAAA;C7BgtHD;A6B7sHC;EACE,YAAA;EACA,gBAAA;EACA,iBAAA;C7B+sHH;A6BxtHD;EAeI,mBAAA;EACA,WAAA;EAKA,YAAA;EAEA,YAAA;EACA,iBAAA;C7BusHH;A6BrsHG;EACE,WAAA;C7BusHL;A6B7rHD;;;EV0BE,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CnBwqHD;AmBtqHC;;;EACE,aAAA;EACA,kBAAA;CnB0qHH;AmBvqHC;;;;;;EAEE,aAAA;CnB6qHH;A6B/sHD;;;EVqBE,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CnB+rHD;AmB7rHC;;;EACE,aAAA;EACA,kBAAA;CnBisHH;AmB9rHC;;;;;;EAEE,aAAA;CnBosHH;A6B7tHD;;;EAGE,oBAAA;C7B+tHD;A6B7tHC;;;EACE,iBAAA;C7BiuHH;A6B7tHD;;EAEE,UAAA;EACA,oBAAA;EACA,uBAAA;C7B+tHD;A6B1tHD;EACE,kBAAA;EACA,gBAAA;EACA,oBAAA;EACA,eAAA;EACA,eAAA;EACA,mBAAA;EACA,0BAAA;EACA,uBAAA;EACA,mBAAA;C7B4tHD;A6BztHC;EACE,kBAAA;EACA,gBAAA;EACA,mBAAA;C7B2tHH;A6BztHC;EACE,mBAAA;EACA,gBAAA;EACA,mBAAA;C7B2tHH;A6B/uHD;;EA0BI,cAAA;C7BytHH;A6BptHD;;;;;;;EDpGE,8BAAA;EACG,2BAAA;C5Bi0HJ;A6BrtHD;EACE,gBAAA;C7ButHD;A6BrtHD;;;;;;;EDxGE,6BAAA;EACG,0BAAA;C5Bs0HJ;A6BttHD;EACE,eAAA;C7BwtHD;A6BntHD;EACE,mBAAA;EAGA,aAAA;EACA,oBAAA;C7BmtHD;A6BxtHD;EAUI,mBAAA;C7BitHH;A6B3tHD;EAYM,kBAAA;C7BktHL;A6B/sHG;;;EAGE,WAAA;C7BitHL;A6B5sHC;;EAGI,mBAAA;C7B6sHL;A6B1sHC;;EAGI,WAAA;EACA,kBAAA;C7B2sHL;A8B12HD;EACE,iBAAA;EACA,gBAAA;EACA,iBAAA;C9B42HD;A8B/2HD;EAOI,mBAAA;EACA,eAAA;C9B22HH;A8Bn3HD;EAWM,mBAAA;EACA,eAAA;EACA,mBAAA;C9B22HL;A8B12HK;;EAEE,sBAAA;EACA,0BAAA;C9B42HP;A8Bv2HG;EACE,eAAA;C9By2HL;A8Bv2HK;;EAEE,eAAA;EACA,sBAAA;EACA,8BAAA;EACA,oBAAA;C9By2HP;A8Bl2HG;;;EAGE,0BAAA;EACA,sBAAA;C9Bo2HL;A8B74HD;ELHE,YAAA;EACA,cAAA;EACA,iBAAA;EACA,0BAAA;CzBm5HD;A8Bn5HD;EA0DI,gBAAA;C9B41HH;A8Bn1HD;EACE,8BAAA;C9Bq1HD;A8Bt1HD;EAGI,YAAA;EAEA,oBAAA;C9Bq1HH;A8B11HD;EASM,kBAAA;EACA,wBAAA;EACA,8BAAA;EACA,2BAAA;C9Bo1HL;A8Bn1HK;EACE,mCAAA;C9Bq1HP;A8B/0HK;;;EAGE,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,iCAAA;EACA,gBAAA;C9Bi1HP;A8B50HC;EAqDA,YAAA;EA8BA,iBAAA;C9B6vHD;A8Bh1HC;EAwDE,YAAA;C9B2xHH;A8Bn1HC;EA0DI,mBAAA;EACA,mBAAA;C9B4xHL;A8Bv1HC;EAgEE,UAAA;EACA,WAAA;C9B0xHH;A8B9wHD;EA0DA;IAjEM,oBAAA;IACA,UAAA;G9ByxHH;E8BztHH;IA9DQ,iBAAA;G9B0xHL;CACF;A8Bp2HC;EAuFE,gBAAA;EACA,mBAAA;C9BgxHH;A8Bx2HC;;;EA8FE,uBAAA;C9B+wHH;A8BjwHD;EA2BA;IApCM,8BAAA;IACA,2BAAA;G9B8wHH;E8B3uHH;;;IA9BM,0BAAA;G9B8wHH;CACF;A8B/2HD;EAEI,YAAA;C9Bg3HH;A8Bl3HD;EAMM,mBAAA;C9B+2HL;A8Br3HD;EASM,iBAAA;C9B+2HL;A8B12HK;;;EAGE,YAAA;EACA,0BAAA;C9B42HP;A8Bp2HD;EAEI,YAAA;C9Bq2HH;A8Bv2HD;EAIM,gBAAA;EACA,eAAA;C9Bs2HL;A8B11HD;EACE,YAAA;C9B41HD;A8B71HD;EAII,YAAA;C9B41HH;A8Bh2HD;EAMM,mBAAA;EACA,mBAAA;C9B61HL;A8Bp2HD;EAYI,UAAA;EACA,WAAA;C9B21HH;A8B/0HD;EA0DA;IAjEM,oBAAA;IACA,UAAA;G9B01HH;E8B1xHH;IA9DQ,iBAAA;G9B21HL;CACF;A8Bn1HD;EACE,iBAAA;C9Bq1HD;A8Bt1HD;EAKI,gBAAA;EACA,mBAAA;C9Bo1HH;A8B11HD;;;EAYI,uBAAA;C9Bm1HH;A8Br0HD;EA2BA;IApCM,8BAAA;IACA,2BAAA;G9Bk1HH;E8B/yHH;;;IA9BM,0BAAA;G9Bk1HH;CACF;A8Bz0HD;EAEI,cAAA;C9B00HH;A8B50HD;EAKI,eAAA;C9B00HH;A8Bj0HD;EAEE,iBAAA;EF3OA,2BAAA;EACC,0BAAA;C5B8iIF;A+BxiID;EACE,mBAAA;EACA,iBAAA;EACA,oBAAA;EACA,8BAAA;C/B0iID;A+BliID;EA8nBA;IAhoBI,mBAAA;G/BwiID;CACF;A+BzhID;EAgnBA;IAlnBI,YAAA;G/B+hID;CACF;A+BjhID;EACE,oBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kCAAA;EACA,2DAAA;UAAA,mDAAA;EAEA,kCAAA;C/BkhID;A+BhhIC;EACE,iBAAA;C/BkhIH;A+Bt/HD;EA6jBA;IArlBI,YAAA;IACA,cAAA;IACA,yBAAA;YAAA,iBAAA;G/BkhID;E+BhhIC;IACE,0BAAA;IACA,wBAAA;IACA,kBAAA;IACA,6BAAA;G/BkhIH;E+B/gIC;IACE,oBAAA;G/BihIH;E+B5gIC;;;IAGE,gBAAA;IACA,iBAAA;G/B8gIH;CACF;A+B1gID;;EAGI,kBAAA;C/B2gIH;A+BtgIC;EAmjBF;;IArjBM,kBAAA;G/B6gIH;CACF;A+BpgID;;;;EAII,oBAAA;EACA,mBAAA;C/BsgIH;A+BhgIC;EAgiBF;;;;IAniBM,gBAAA;IACA,eAAA;G/B0gIH;CACF;A+B9/HD;EACE,cAAA;EACA,sBAAA;C/BggID;A+B3/HD;EA8gBA;IAhhBI,iBAAA;G/BigID;CACF;A+B7/HD;;EAEE,gBAAA;EACA,SAAA;EACA,QAAA;EACA,cAAA;C/B+/HD;A+Bz/HD;EAggBA;;IAlgBI,iBAAA;G/BggID;CACF;A+B9/HD;EACE,OAAA;EACA,sBAAA;C/BggID;A+B9/HD;EACE,UAAA;EACA,iBAAA;EACA,sBAAA;C/BggID;A+B1/HD;EACE,YAAA;EACA,mBAAA;EACA,gBAAA;EACA,kBAAA;EACA,aAAA;C/B4/HD;A+B1/HC;;EAEE,sBAAA;C/B4/HH;A+BrgID;EAaI,eAAA;C/B2/HH;A+Bl/HD;EALI;;IAEE,mBAAA;G/B0/HH;CACF;A+Bh/HD;EACE,mBAAA;EACA,aAAA;EACA,mBAAA;EACA,kBAAA;EC9LA,gBAAA;EACA,mBAAA;ED+LA,8BAAA;EACA,uBAAA;EACA,8BAAA;EACA,mBAAA;C/Bm/HD;A+B/+HC;EACE,WAAA;C/Bi/HH;A+B//HD;EAmBI,eAAA;EACA,YAAA;EACA,YAAA;EACA,mBAAA;C/B++HH;A+BrgID;EAyBI,gBAAA;C/B++HH;A+Bz+HD;EAqbA;IAvbI,cAAA;G/B++HD;CACF;A+Bt+HD;EACE,oBAAA;C/Bw+HD;A+Bz+HD;EAII,kBAAA;EACA,qBAAA;EACA,kBAAA;C/Bw+HH;A+B58HC;EA2YF;IAjaM,iBAAA;IACA,YAAA;IACA,YAAA;IACA,cAAA;IACA,8BAAA;IACA,UAAA;IACA,yBAAA;YAAA,iBAAA;G/Bs+HH;E+B3kHH;;IAxZQ,2BAAA;G/Bu+HL;E+B/kHH;IArZQ,kBAAA;G/Bu+HL;E+Bt+HK;;IAEE,uBAAA;G/Bw+HP;CACF;A+Bt9HD;EA+XA;IA1YI,YAAA;IACA,UAAA;G/Bq+HD;E+B5lHH;IAtYM,YAAA;G/Bq+HH;E+B/lHH;IApYQ,kBAAA;IACA,qBAAA;G/Bs+HL;CACF;A+B39HD;EACE,mBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kCAAA;EACA,qCAAA;E1B9NA,6FAAA;EACQ,qFAAA;E2B/DR,gBAAA;EACA,mBAAA;ChC4vID;AkBtuHD;EAwEA;IAtIM,sBAAA;IACA,iBAAA;IACA,uBAAA;GlBwyHH;EkBpqHH;IA/HM,sBAAA;IACA,YAAA;IACA,uBAAA;GlBsyHH;EkBzqHH;IAxHM,sBAAA;GlBoyHH;EkB5qHH;IApHM,sBAAA;IACA,uBAAA;GlBmyHH;EkBhrHH;;;IA9GQ,YAAA;GlBmyHL;EkBrrHH;IAxGM,YAAA;GlBgyHH;EkBxrHH;IApGM,iBAAA;IACA,uBAAA;GlB+xHH;EkB5rHH;;IA5FM,sBAAA;IACA,cAAA;IACA,iBAAA;IACA,uBAAA;GlB4xHH;EkBnsHH;;IAtFQ,gBAAA;GlB6xHL;EkBvsHH;;IAjFM,mBAAA;IACA,eAAA;GlB4xHH;EkB5sHH;IA3EM,OAAA;GlB0xHH;CACF;A+BpgIC;EAmWF;IAzWM,mBAAA;G/B8gIH;E+B5gIG;IACE,iBAAA;G/B8gIL;CACF;A+B7/HD;EAoVA;IA5VI,YAAA;IACA,UAAA;IACA,eAAA;IACA,gBAAA;IACA,eAAA;IACA,kBAAA;I1BzPF,yBAAA;IACQ,iBAAA;GLmwIP;CACF;A+BngID;EACE,cAAA;EHpUA,2BAAA;EACC,0BAAA;C5B00IF;A+BngID;EACE,iBAAA;EHzUA,6BAAA;EACC,4BAAA;EAOD,8BAAA;EACC,6BAAA;C5By0IF;A+B//HD;EChVE,gBAAA;EACA,mBAAA;ChCk1ID;A+BhgIC;ECnVA,iBAAA;EACA,oBAAA;ChCs1ID;A+BjgIC;ECtVA,iBAAA;EACA,oBAAA;ChC01ID;A+B3/HD;EChWE,iBAAA;EACA,oBAAA;ChC81ID;A+Bv/HD;EAsSA;IA1SI,YAAA;IACA,kBAAA;IACA,mBAAA;G/B+/HD;CACF;A+Bl+HD;EAhBE;IExWA,uBAAA;GjC81IC;E+Br/HD;IE5WA,wBAAA;IF8WE,oBAAA;G/Bu/HD;E+Bz/HD;IAKI,gBAAA;G/Bu/HH;CACF;A+B9+HD;EACE,0BAAA;EACA,sBAAA;C/Bg/HD;A+Bl/HD;EAKI,YAAA;C/Bg/HH;A+B/+HG;;EAEE,eAAA;EACA,8BAAA;C/Bi/HL;A+B1/HD;EAcI,YAAA;C/B++HH;A+B7/HD;EAmBM,YAAA;C/B6+HL;A+B3+HK;;EAEE,YAAA;EACA,8BAAA;C/B6+HP;A+Bz+HK;;;EAGE,YAAA;EACA,0BAAA;C/B2+HP;A+Bv+HK;;;EAGE,YAAA;EACA,8BAAA;C/By+HP;A+BjhID;EA8CI,mBAAA;C/Bs+HH;A+Br+HG;;EAEE,uBAAA;C/Bu+HL;A+BxhID;EAoDM,uBAAA;C/Bu+HL;A+B3hID;;EA0DI,sBAAA;C/Bq+HH;A+B99HK;;;EAGE,0BAAA;EACA,YAAA;C/Bg+HP;A+B/7HC;EAoKF;IA7LU,YAAA;G/B49HP;E+B39HO;;IAEE,YAAA;IACA,8BAAA;G/B69HT;E+Bz9HO;;;IAGE,YAAA;IACA,0BAAA;G/B29HT;E+Bv9HO;;;IAGE,YAAA;IACA,8BAAA;G/By9HT;CACF;A+B3jID;EA8GI,YAAA;C/Bg9HH;A+B/8HG;EACE,YAAA;C/Bi9HL;A+BjkID;EAqHI,YAAA;C/B+8HH;A+B98HG;;EAEE,YAAA;C/Bg9HL;A+B58HK;;;;EAEE,YAAA;C/Bg9HP;A+Bx8HD;EACE,uBAAA;EACA,sBAAA;C/B08HD;A+B58HD;EAKI,eAAA;C/B08HH;A+Bz8HG;;EAEE,YAAA;EACA,8BAAA;C/B28HL;A+Bp9HD;EAcI,eAAA;C/By8HH;A+Bv9HD;EAmBM,eAAA;C/Bu8HL;A+Br8HK;;EAEE,YAAA;EACA,8BAAA;C/Bu8HP;A+Bn8HK;;;EAGE,YAAA;EACA,0BAAA;C/Bq8HP;A+Bj8HK;;;EAGE,YAAA;EACA,8BAAA;C/Bm8HP;A+B3+HD;EA+CI,mBAAA;C/B+7HH;A+B97HG;;EAEE,uBAAA;C/Bg8HL;A+Bl/HD;EAqDM,uBAAA;C/Bg8HL;A+Br/HD;;EA2DI,sBAAA;C/B87HH;A+Bx7HK;;;EAGE,0BAAA;EACA,YAAA;C/B07HP;A+Bn5HC;EAwBF;IAvDU,sBAAA;G/Bs7HP;E+B/3HH;IApDU,0BAAA;G/Bs7HP;E+Bl4HH;IAjDU,eAAA;G/Bs7HP;E+Br7HO;;IAEE,YAAA;IACA,8BAAA;G/Bu7HT;E+Bn7HO;;;IAGE,YAAA;IACA,0BAAA;G/Bq7HT;E+Bj7HO;;;IAGE,YAAA;IACA,8BAAA;G/Bm7HT;CACF;A+B3hID;EA+GI,eAAA;C/B+6HH;A+B96HG;EACE,YAAA;C/Bg7HL;A+BjiID;EAsHI,eAAA;C/B86HH;A+B76HG;;EAEE,YAAA;C/B+6HL;A+B36HK;;;;EAEE,YAAA;C/B+6HP;AkCzjJD;EACE,kBAAA;EACA,oBAAA;EACA,iBAAA;EACA,0BAAA;EACA,mBAAA;ClC2jJD;AkChkJD;EAQI,sBAAA;ClC2jJH;AkCnkJD;EAWM,kBAAA;EACA,eAAA;EACA,YAAA;ClC2jJL;AkCxkJD;EAkBI,eAAA;ClCyjJH;AmC7kJD;EACE,sBAAA;EACA,gBAAA;EACA,eAAA;EACA,mBAAA;CnC+kJD;AmCnlJD;EAOI,gBAAA;CnC+kJH;AmCtlJD;;EAUM,mBAAA;EACA,YAAA;EACA,kBAAA;EACA,wBAAA;EACA,sBAAA;EACA,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,kBAAA;CnCglJL;AmC9kJG;;EAGI,eAAA;EPXN,+BAAA;EACG,4BAAA;C5B2lJJ;AmC7kJG;;EPvBF,gCAAA;EACG,6BAAA;C5BwmJJ;AmCxkJG;;;;EAEE,WAAA;EACA,eAAA;EACA,0BAAA;EACA,mBAAA;CnC4kJL;AmCtkJG;;;;;;EAGE,WAAA;EACA,YAAA;EACA,0BAAA;EACA,sBAAA;EACA,gBAAA;CnC2kJL;AmCloJD;;;;;;EAkEM,eAAA;EACA,uBAAA;EACA,mBAAA;EACA,oBAAA;CnCwkJL;AmC/jJD;;EC3EM,mBAAA;EACA,gBAAA;EACA,uBAAA;CpC8oJL;AoC5oJG;;ERKF,+BAAA;EACG,4BAAA;C5B2oJJ;AoC3oJG;;ERTF,gCAAA;EACG,6BAAA;C5BwpJJ;AmC1kJD;;EChFM,kBAAA;EACA,gBAAA;EACA,iBAAA;CpC8pJL;AoC5pJG;;ERKF,+BAAA;EACG,4BAAA;C5B2pJJ;AoC3pJG;;ERTF,gCAAA;EACG,6BAAA;C5BwqJJ;AqC3qJD;EACE,gBAAA;EACA,eAAA;EACA,iBAAA;EACA,mBAAA;CrC6qJD;AqCjrJD;EAOI,gBAAA;CrC6qJH;AqCprJD;;EAUM,sBAAA;EACA,kBAAA;EACA,uBAAA;EACA,uBAAA;EACA,oBAAA;CrC8qJL;AqC5rJD;;EAmBM,sBAAA;EACA,0BAAA;CrC6qJL;AqCjsJD;;EA2BM,aAAA;CrC0qJL;AqCrsJD;;EAkCM,YAAA;CrCuqJL;AqCzsJD;;;;EA2CM,eAAA;EACA,uBAAA;EACA,oBAAA;CrCoqJL;AsCltJD;EACE,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,kBAAA;EACA,eAAA;EACA,YAAA;EACA,mBAAA;EACA,oBAAA;EACA,yBAAA;EACA,qBAAA;CtCotJD;AsChtJG;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;CtCktJL;AsC7sJC;EACE,cAAA;CtC+sJH;AsC3sJC;EACE,mBAAA;EACA,UAAA;CtC6sJH;AsCtsJD;ECtCE,0BAAA;CvC+uJD;AuC5uJG;;EAEE,0BAAA;CvC8uJL;AsCzsJD;EC1CE,0BAAA;CvCsvJD;AuCnvJG;;EAEE,0BAAA;CvCqvJL;AsC5sJD;EC9CE,0BAAA;CvC6vJD;AuC1vJG;;EAEE,0BAAA;CvC4vJL;AsC/sJD;EClDE,0BAAA;CvCowJD;AuCjwJG;;EAEE,0BAAA;CvCmwJL;AsCltJD;ECtDE,0BAAA;CvC2wJD;AuCxwJG;;EAEE,0BAAA;CvC0wJL;AsCrtJD;EC1DE,0BAAA;CvCkxJD;AuC/wJG;;EAEE,0BAAA;CvCixJL;AwCnxJD;EACE,sBAAA;EACA,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,kBAAA;EACA,YAAA;EACA,eAAA;EACA,uBAAA;EACA,oBAAA;EACA,mBAAA;EACA,0BAAA;EACA,oBAAA;CxCqxJD;AwClxJC;EACE,cAAA;CxCoxJH;AwChxJC;EACE,mBAAA;EACA,UAAA;CxCkxJH;AwC/wJC;;EAEE,OAAA;EACA,iBAAA;CxCixJH;AwC5wJG;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;CxC8wJL;AwCzwJC;;EAEE,eAAA;EACA,uBAAA;CxC2wJH;AwCxwJC;EACE,aAAA;CxC0wJH;AwCvwJC;EACE,kBAAA;CxCywJH;AwCtwJC;EACE,iBAAA;CxCwwJH;AyCl0JD;EACE,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,eAAA;EACA,0BAAA;CzCo0JD;AyCz0JD;;EASI,eAAA;CzCo0JH;AyC70JD;EAaI,oBAAA;EACA,gBAAA;EACA,iBAAA;CzCm0JH;AyCl1JD;EAmBI,0BAAA;CzCk0JH;AyC/zJC;;EAEE,mBAAA;EACA,mBAAA;EACA,oBAAA;CzCi0JH;AyC31JD;EA8BI,gBAAA;CzCg0JH;AyC9yJD;EACA;IAfI,kBAAA;IACA,qBAAA;GzCg0JD;EyC9zJC;;IAEE,mBAAA;IACA,oBAAA;GzCg0JH;EyCvzJH;;IAJM,gBAAA;GzC+zJH;CACF;A0C52JD;EACE,eAAA;EACA,aAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;ErCiLA,4CAAA;EACK,uCAAA;EACG,oCAAA;CL8rJT;A0Cx3JD;;EAaI,kBAAA;EACA,mBAAA;C1C+2JH;A0C32JC;;;EAGE,sBAAA;C1C62JH;A0Cl4JD;EA0BI,aAAA;EACA,eAAA;C1C22JH;A2Cp4JD;EACE,cAAA;EACA,oBAAA;EACA,8BAAA;EACA,mBAAA;C3Cs4JD;A2C14JD;EAQI,cAAA;EAEA,eAAA;C3Co4JH;A2C94JD;EAeI,kBAAA;C3Ck4JH;A2Cj5JD;;EAqBI,iBAAA;C3Cg4JH;A2Cr5JD;EAyBI,gBAAA;C3C+3JH;A2Cv3JD;;EAEE,oBAAA;C3Cy3JD;A2C33JD;;EAMI,mBAAA;EACA,UAAA;EACA,aAAA;EACA,eAAA;C3Cy3JH;A2Cj3JD;ECvDE,0BAAA;EACA,sBAAA;EACA,eAAA;C5C26JD;A2Ct3JD;EClDI,0BAAA;C5C26JH;A2Cz3JD;EC/CI,eAAA;C5C26JH;A2Cx3JD;EC3DE,0BAAA;EACA,sBAAA;EACA,eAAA;C5Cs7JD;A2C73JD;ECtDI,0BAAA;C5Cs7JH;A2Ch4JD;ECnDI,eAAA;C5Cs7JH;A2C/3JD;EC/DE,0BAAA;EACA,sBAAA;EACA,eAAA;C5Ci8JD;A2Cp4JD;EC1DI,0BAAA;C5Ci8JH;A2Cv4JD;ECvDI,eAAA;C5Ci8JH;A2Ct4JD;ECnEE,0BAAA;EACA,sBAAA;EACA,eAAA;C5C48JD;A2C34JD;EC9DI,0BAAA;C5C48JH;A2C94JD;EC3DI,eAAA;C5C48JH;A6C98JD;EACE;IAAQ,4BAAA;G7Ci9JP;E6Ch9JD;IAAQ,yBAAA;G7Cm9JP;CACF;A6Ch9JD;EACE;IAAQ,4BAAA;G7Cm9JP;E6Cl9JD;IAAQ,yBAAA;G7Cq9JP;CACF;A6Cx9JD;EACE;IAAQ,4BAAA;G7Cm9JP;E6Cl9JD;IAAQ,yBAAA;G7Cq9JP;CACF;A6C98JD;EACE,iBAAA;EACA,aAAA;EACA,oBAAA;EACA,0BAAA;EACA,mBAAA;ExCsCA,uDAAA;EACQ,+CAAA;CL26JT;A6C78JD;EACE,YAAA;EACA,UAAA;EACA,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,YAAA;EACA,mBAAA;EACA,0BAAA;ExCyBA,uDAAA;EACQ,+CAAA;EAyHR,oCAAA;EACK,+BAAA;EACG,4BAAA;CL+zJT;A6C18JD;;ECCI,8MAAA;EACA,yMAAA;EACA,sMAAA;EDAF,mCAAA;UAAA,2BAAA;C7C88JD;A6Cv8JD;;ExC5CE,2DAAA;EACK,sDAAA;EACG,mDAAA;CLu/JT;A6Cp8JD;EErEE,0BAAA;C/C4gKD;A+CzgKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9C49JH;A6Cx8JD;EEzEE,0BAAA;C/CohKD;A+CjhKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9Co+JH;A6C58JD;EE7EE,0BAAA;C/C4hKD;A+CzhKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9C4+JH;A6Ch9JD;EEjFE,0BAAA;C/CoiKD;A+CjiKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9Co/JH;AgD5iKD;EAEE,iBAAA;ChD6iKD;AgD3iKC;EACE,cAAA;ChD6iKH;AgDziKD;;EAEE,QAAA;EACA,iBAAA;ChD2iKD;AgDxiKD;EACE,eAAA;ChD0iKD;AgDviKD;EACE,eAAA;ChDyiKD;AgDtiKC;EACE,gBAAA;ChDwiKH;AgDpiKD;;EAEE,mBAAA;ChDsiKD;AgDniKD;;EAEE,oBAAA;ChDqiKD;AgDliKD;;;EAGE,oBAAA;EACA,oBAAA;ChDoiKD;AgDjiKD;EACE,uBAAA;ChDmiKD;AgDhiKD;EACE,uBAAA;ChDkiKD;AgD9hKD;EACE,cAAA;EACA,mBAAA;ChDgiKD;AgD1hKD;EACE,gBAAA;EACA,iBAAA;ChD4hKD;AiDnlKD;EAEE,oBAAA;EACA,gBAAA;CjDolKD;AiD5kKD;EACE,mBAAA;EACA,eAAA;EACA,mBAAA;EAEA,oBAAA;EACA,uBAAA;EACA,uBAAA;CjD6kKD;AiD1kKC;ErB3BA,6BAAA;EACC,4BAAA;C5BwmKF;AiD3kKC;EACE,iBAAA;ErBvBF,gCAAA;EACC,+BAAA;C5BqmKF;AiDpkKD;;EAEE,YAAA;CjDskKD;AiDxkKD;;EAKI,YAAA;CjDukKH;AiDnkKC;;;;EAEE,sBAAA;EACA,YAAA;EACA,0BAAA;CjDukKH;AiDnkKD;EACE,YAAA;EACA,iBAAA;CjDqkKD;AiDhkKC;;;EAGE,0BAAA;EACA,eAAA;EACA,oBAAA;CjDkkKH;AiDvkKC;;;EASI,eAAA;CjDmkKL;AiD5kKC;;;EAYI,eAAA;CjDqkKL;AiDhkKC;;;EAGE,WAAA;EACA,YAAA;EACA,0BAAA;EACA,sBAAA;CjDkkKH;AiDxkKC;;;;;;;;;EAYI,eAAA;CjDukKL;AiDnlKC;;;EAeI,eAAA;CjDykKL;AkD3qKC;EACE,eAAA;EACA,0BAAA;ClD6qKH;AkD3qKG;;EAEE,eAAA;ClD6qKL;AkD/qKG;;EAKI,eAAA;ClD8qKP;AkD3qKK;;;;EAEE,eAAA;EACA,0BAAA;ClD+qKP;AkD7qKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClDkrKP;AkDxsKC;EACE,eAAA;EACA,0BAAA;ClD0sKH;AkDxsKG;;EAEE,eAAA;ClD0sKL;AkD5sKG;;EAKI,eAAA;ClD2sKP;AkDxsKK;;;;EAEE,eAAA;EACA,0BAAA;ClD4sKP;AkD1sKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClD+sKP;AkDruKC;EACE,eAAA;EACA,0BAAA;ClDuuKH;AkDruKG;;EAEE,eAAA;ClDuuKL;AkDzuKG;;EAKI,eAAA;ClDwuKP;AkDruKK;;;;EAEE,eAAA;EACA,0BAAA;ClDyuKP;AkDvuKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClD4uKP;AkDlwKC;EACE,eAAA;EACA,0BAAA;ClDowKH;AkDlwKG;;EAEE,eAAA;ClDowKL;AkDtwKG;;EAKI,eAAA;ClDqwKP;AkDlwKK;;;;EAEE,eAAA;EACA,0BAAA;ClDswKP;AkDpwKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClDywKP;AiDxqKD;EACE,cAAA;EACA,mBAAA;CjD0qKD;AiDxqKD;EACE,iBAAA;EACA,iBAAA;CjD0qKD;AmDpyKD;EACE,oBAAA;EACA,uBAAA;EACA,8BAAA;EACA,mBAAA;E9C0DA,kDAAA;EACQ,0CAAA;CL6uKT;AmDnyKD;EACE,cAAA;CnDqyKD;AmDhyKD;EACE,mBAAA;EACA,qCAAA;EvBpBA,6BAAA;EACC,4BAAA;C5BuzKF;AmDtyKD;EAMI,eAAA;CnDmyKH;AmD9xKD;EACE,cAAA;EACA,iBAAA;EACA,gBAAA;EACA,eAAA;CnDgyKD;AmDpyKD;;;;;EAWI,eAAA;CnDgyKH;AmD3xKD;EACE,mBAAA;EACA,0BAAA;EACA,2BAAA;EvBxCA,gCAAA;EACC,+BAAA;C5Bs0KF;AmDrxKD;;EAGI,iBAAA;CnDsxKH;AmDzxKD;;EAMM,oBAAA;EACA,iBAAA;CnDuxKL;AmDnxKG;;EAEI,cAAA;EvBvEN,6BAAA;EACC,4BAAA;C5B61KF;AmDjxKG;;EAEI,iBAAA;EvBvEN,gCAAA;EACC,+BAAA;C5B21KF;AmD1yKD;EvB1DE,2BAAA;EACC,0BAAA;C5Bu2KF;AmD7wKD;EAEI,oBAAA;CnD8wKH;AmD3wKD;EACE,oBAAA;CnD6wKD;AmDrwKD;;;EAII,iBAAA;CnDswKH;AmD1wKD;;;EAOM,mBAAA;EACA,oBAAA;CnDwwKL;AmDhxKD;;EvBzGE,6BAAA;EACC,4BAAA;C5B63KF;AmDrxKD;;;;EAmBQ,4BAAA;EACA,6BAAA;CnDwwKP;AmD5xKD;;;;;;;;EAwBU,4BAAA;CnD8wKT;AmDtyKD;;;;;;;;EA4BU,6BAAA;CnDoxKT;AmDhzKD;;EvBjGE,gCAAA;EACC,+BAAA;C5Bq5KF;AmDrzKD;;;;EAyCQ,+BAAA;EACA,gCAAA;CnDkxKP;AmD5zKD;;;;;;;;EA8CU,+BAAA;CnDwxKT;AmDt0KD;;;;;;;;EAkDU,gCAAA;CnD8xKT;AmDh1KD;;;;EA2DI,2BAAA;CnD2xKH;AmDt1KD;;EA+DI,cAAA;CnD2xKH;AmD11KD;;EAmEI,UAAA;CnD2xKH;AmD91KD;;;;;;;;;;;;EA0EU,eAAA;CnDkyKT;AmD52KD;;;;;;;;;;;;EA8EU,gBAAA;CnD4yKT;AmD13KD;;;;;;;;EAuFU,iBAAA;CnD6yKT;AmDp4KD;;;;;;;;EAgGU,iBAAA;CnD8yKT;AmD94KD;EAsGI,UAAA;EACA,iBAAA;CnD2yKH;AmDjyKD;EACE,oBAAA;CnDmyKD;AmDpyKD;EAKI,iBAAA;EACA,mBAAA;CnDkyKH;AmDxyKD;EASM,gBAAA;CnDkyKL;AmD3yKD;EAcI,iBAAA;CnDgyKH;AmD9yKD;;EAkBM,2BAAA;CnDgyKL;AmDlzKD;EAuBI,cAAA;CnD8xKH;AmDrzKD;EAyBM,8BAAA;CnD+xKL;AmDxxKD;EC1PE,mBAAA;CpDqhLD;AoDnhLC;EACE,eAAA;EACA,0BAAA;EACA,mBAAA;CpDqhLH;AoDxhLC;EAMI,uBAAA;CpDqhLL;AoD3hLC;EASI,eAAA;EACA,0BAAA;CpDqhLL;AoDlhLC;EAEI,0BAAA;CpDmhLL;AmDvyKD;EC7PE,sBAAA;CpDuiLD;AoDriLC;EACE,YAAA;EACA,0BAAA;EACA,sBAAA;CpDuiLH;AoD1iLC;EAMI,0BAAA;CpDuiLL;AoD7iLC;EASI,eAAA;EACA,uBAAA;CpDuiLL;AoDpiLC;EAEI,6BAAA;CpDqiLL;AmDtzKD;EChQE,sBAAA;CpDyjLD;AoDvjLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpDyjLH;AoD5jLC;EAMI,0BAAA;CpDyjLL;AoD/jLC;EASI,eAAA;EACA,0BAAA;CpDyjLL;AoDtjLC;EAEI,6BAAA;CpDujLL;AmDr0KD;ECnQE,sBAAA;CpD2kLD;AoDzkLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD2kLH;AoD9kLC;EAMI,0BAAA;CpD2kLL;AoDjlLC;EASI,eAAA;EACA,0BAAA;CpD2kLL;AoDxkLC;EAEI,6BAAA;CpDykLL;AmDp1KD;ECtQE,sBAAA;CpD6lLD;AoD3lLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD6lLH;AoDhmLC;EAMI,0BAAA;CpD6lLL;AoDnmLC;EASI,eAAA;EACA,0BAAA;CpD6lLL;AoD1lLC;EAEI,6BAAA;CpD2lLL;AmDn2KD;ECzQE,sBAAA;CpD+mLD;AoD7mLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD+mLH;AoDlnLC;EAMI,0BAAA;CpD+mLL;AoDrnLC;EASI,eAAA;EACA,0BAAA;CpD+mLL;AoD5mLC;EAEI,6BAAA;CpD6mLL;AqD7nLD;EACE,mBAAA;EACA,eAAA;EACA,UAAA;EACA,WAAA;EACA,iBAAA;CrD+nLD;AqDpoLD;;;;;EAYI,mBAAA;EACA,OAAA;EACA,QAAA;EACA,UAAA;EACA,aAAA;EACA,YAAA;EACA,UAAA;CrD+nLH;AqD1nLD;EACE,uBAAA;CrD4nLD;AqDxnLD;EACE,oBAAA;CrD0nLD;AsDrpLD;EACE,iBAAA;EACA,cAAA;EACA,oBAAA;EACA,0BAAA;EACA,0BAAA;EACA,mBAAA;EjDwDA,wDAAA;EACQ,gDAAA;CLgmLT;AsD/pLD;EASI,mBAAA;EACA,kCAAA;CtDypLH;AsDppLD;EACE,cAAA;EACA,mBAAA;CtDspLD;AsDppLD;EACE,aAAA;EACA,mBAAA;CtDspLD;AuD5qLD;EACE,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,eAAA;EACA,YAAA;EACA,0BAAA;EjCRA,aAAA;EAGA,0BAAA;CtBqrLD;AuD7qLC;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;EjCfF,aAAA;EAGA,0BAAA;CtB6rLD;AuDzqLC;EACE,WAAA;EACA,gBAAA;EACA,wBAAA;EACA,UAAA;EACA,yBAAA;CvD2qLH;AwDhsLD;EACE,iBAAA;CxDksLD;AwD9rLD;EACE,cAAA;EACA,iBAAA;EACA,gBAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,kCAAA;EAIA,WAAA;CxD6rLD;AwD1rLC;EnD+GA,sCAAA;EACI,kCAAA;EACC,iCAAA;EACG,8BAAA;EAkER,oDAAA;EAEK,0CAAA;EACG,oCAAA;CL6gLT;AwDhsLC;EnD2GA,mCAAA;EACI,+BAAA;EACC,8BAAA;EACG,2BAAA;CLwlLT;AwDpsLD;EACE,mBAAA;EACA,iBAAA;CxDssLD;AwDlsLD;EACE,mBAAA;EACA,YAAA;EACA,aAAA;CxDosLD;AwDhsLD;EACE,mBAAA;EACA,uBAAA;EACA,uBAAA;EACA,qCAAA;EACA,mBAAA;EnDaA,iDAAA;EACQ,yCAAA;EmDZR,qCAAA;UAAA,6BAAA;EAEA,WAAA;CxDksLD;AwD9rLD;EACE,gBAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,uBAAA;CxDgsLD;AwD9rLC;ElCrEA,WAAA;EAGA,yBAAA;CtBowLD;AwDjsLC;ElCtEA,aAAA;EAGA,0BAAA;CtBwwLD;AwDhsLD;EACE,cAAA;EACA,iCAAA;CxDksLD;AwD9rLD;EACE,iBAAA;CxDgsLD;AwD5rLD;EACE,UAAA;EACA,wBAAA;CxD8rLD;AwDzrLD;EACE,mBAAA;EACA,cAAA;CxD2rLD;AwDvrLD;EACE,cAAA;EACA,kBAAA;EACA,8BAAA;CxDyrLD;AwD5rLD;EAQI,iBAAA;EACA,iBAAA;CxDurLH;AwDhsLD;EAaI,kBAAA;CxDsrLH;AwDnsLD;EAiBI,eAAA;CxDqrLH;AwDhrLD;EACE,mBAAA;EACA,aAAA;EACA,YAAA;EACA,aAAA;EACA,iBAAA;CxDkrLD;AwDhqLD;EAZE;IACE,aAAA;IACA,kBAAA;GxD+qLD;EwD7qLD;InDvEA,kDAAA;IACQ,0CAAA;GLuvLP;EwD5qLD;IAAY,aAAA;GxD+qLX;CACF;AwD1qLD;EAFE;IAAY,aAAA;GxDgrLX;CACF;AyD/zLD;EACE,mBAAA;EACA,cAAA;EACA,eAAA;ECRA,4DAAA;EAEA,mBAAA;EACA,oBAAA;EACA,uBAAA;EACA,iBAAA;EACA,wBAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;EDHA,gBAAA;EnCVA,WAAA;EAGA,yBAAA;CtBs1LD;AyD30LC;EnCdA,aAAA;EAGA,0BAAA;CtB01LD;AyD90LC;EAAW,iBAAA;EAAmB,eAAA;CzDk1L/B;AyDj1LC;EAAW,iBAAA;EAAmB,eAAA;CzDq1L/B;AyDp1LC;EAAW,gBAAA;EAAmB,eAAA;CzDw1L/B;AyDv1LC;EAAW,kBAAA;EAAmB,eAAA;CzD21L/B;AyDv1LD;EACE,iBAAA;EACA,iBAAA;EACA,YAAA;EACA,mBAAA;EACA,uBAAA;EACA,mBAAA;CzDy1LD;AyDr1LD;EACE,mBAAA;EACA,SAAA;EACA,UAAA;EACA,0BAAA;EACA,oBAAA;CzDu1LD;AyDn1LC;EACE,UAAA;EACA,UAAA;EACA,kBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,UAAA;EACA,WAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,UAAA;EACA,UAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,SAAA;EACA,QAAA;EACA,iBAAA;EACA,4BAAA;EACA,yBAAA;CzDq1LH;AyDn1LC;EACE,SAAA;EACA,SAAA;EACA,iBAAA;EACA,4BAAA;EACA,wBAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,UAAA;EACA,kBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,WAAA;EACA,iBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,UAAA;EACA,iBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;A2Dl7LD;EACE,mBAAA;EACA,OAAA;EACA,QAAA;EACA,cAAA;EACA,cAAA;EACA,iBAAA;EACA,aAAA;EDXA,4DAAA;EAEA,mBAAA;EACA,oBAAA;EACA,uBAAA;EACA,iBAAA;EACA,wBAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;ECAA,gBAAA;EAEA,uBAAA;EACA,qCAAA;UAAA,6BAAA;EACA,uBAAA;EACA,qCAAA;EACA,mBAAA;EtD8CA,kDAAA;EACQ,0CAAA;CLk5LT;A2D77LC;EAAY,kBAAA;C3Dg8Lb;A2D/7LC;EAAY,kBAAA;C3Dk8Lb;A2Dj8LC;EAAY,iBAAA;C3Do8Lb;A2Dn8LC;EAAY,mBAAA;C3Ds8Lb;A2Dn8LD;EACE,UAAA;EACA,kBAAA;EACA,gBAAA;EACA,0BAAA;EACA,iCAAA;EACA,2BAAA;C3Dq8LD;A2Dl8LD;EACE,kBAAA;C3Do8LD;A2D57LC;;EAEE,mBAAA;EACA,eAAA;EACA,SAAA;EACA,UAAA;EACA,0BAAA;EACA,oBAAA;C3D87LH;A2D37LD;EACE,mBAAA;C3D67LD;A2D37LD;EACE,mBAAA;EACA,YAAA;C3D67LD;A2Dz7LC;EACE,UAAA;EACA,mBAAA;EACA,uBAAA;EACA,0BAAA;EACA,sCAAA;EACA,cAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,YAAA;EACA,mBAAA;EACA,uBAAA;EACA,uBAAA;C3D47LL;A2Dz7LC;EACE,SAAA;EACA,YAAA;EACA,kBAAA;EACA,qBAAA;EACA,4BAAA;EACA,wCAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,UAAA;EACA,cAAA;EACA,qBAAA;EACA,yBAAA;C3D47LL;A2Dz7LC;EACE,UAAA;EACA,mBAAA;EACA,oBAAA;EACA,6BAAA;EACA,yCAAA;EACA,WAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,SAAA;EACA,mBAAA;EACA,oBAAA;EACA,0BAAA;C3D47LL;A2Dx7LC;EACE,SAAA;EACA,aAAA;EACA,kBAAA;EACA,sBAAA;EACA,2BAAA;EACA,uCAAA;C3D07LH;A2Dz7LG;EACE,aAAA;EACA,WAAA;EACA,sBAAA;EACA,wBAAA;EACA,cAAA;C3D27LL;A4DpjMD;EACE,mBAAA;C5DsjMD;A4DnjMD;EACE,mBAAA;EACA,iBAAA;EACA,YAAA;C5DqjMD;A4DxjMD;EAMI,cAAA;EACA,mBAAA;EvD6KF,0CAAA;EACK,qCAAA;EACG,kCAAA;CLy4LT;A4D/jMD;;EAcM,eAAA;C5DqjML;A4D3hMC;EA4NF;IvD3DE,uDAAA;IAEK,6CAAA;IACG,uCAAA;IA7JR,oCAAA;IAEQ,4BAAA;IA+GR,4BAAA;IAEQ,oBAAA;GL86LP;E4DzjMG;;IvDmHJ,2CAAA;IACQ,mCAAA;IuDjHF,QAAA;G5D4jML;E4D1jMG;;IvD8GJ,4CAAA;IACQ,oCAAA;IuD5GF,QAAA;G5D6jML;E4D3jMG;;;IvDyGJ,wCAAA;IACQ,gCAAA;IuDtGF,QAAA;G5D8jML;CACF;A4DpmMD;;;EA6CI,eAAA;C5D4jMH;A4DzmMD;EAiDI,QAAA;C5D2jMH;A4D5mMD;;EAsDI,mBAAA;EACA,OAAA;EACA,YAAA;C5D0jMH;A4DlnMD;EA4DI,WAAA;C5DyjMH;A4DrnMD;EA+DI,YAAA;C5DyjMH;A4DxnMD;;EAmEI,QAAA;C5DyjMH;A4D5nMD;EAuEI,YAAA;C5DwjMH;A4D/nMD;EA0EI,WAAA;C5DwjMH;A4DhjMD;EACE,mBAAA;EACA,OAAA;EACA,QAAA;EACA,UAAA;EACA,WAAA;EtC9FA,aAAA;EAGA,0BAAA;EsC6FA,gBAAA;EACA,YAAA;EACA,mBAAA;EACA,0CAAA;EACA,mCAAA;C5DmjMD;A4D9iMC;EdnGE,mGAAA;EACA,8FAAA;EACA,qHAAA;EAAA,+FAAA;EACA,4BAAA;EACA,uHAAA;C9CopMH;A4DljMC;EACE,WAAA;EACA,SAAA;EdxGA,mGAAA;EACA,8FAAA;EACA,qHAAA;EAAA,+FAAA;EACA,4BAAA;EACA,uHAAA;C9C6pMH;A4DpjMC;;EAEE,WAAA;EACA,YAAA;EACA,sBAAA;EtCvHF,aAAA;EAGA,0BAAA;CtB4qMD;A4DtlMD;;;;EAuCI,mBAAA;EACA,SAAA;EACA,kBAAA;EACA,WAAA;EACA,sBAAA;C5DqjMH;A4DhmMD;;EA+CI,UAAA;EACA,mBAAA;C5DqjMH;A4DrmMD;;EAoDI,WAAA;EACA,oBAAA;C5DqjMH;A4D1mMD;;EAyDI,YAAA;EACA,aAAA;EACA,eAAA;EACA,mBAAA;C5DqjMH;A4DhjMG;EACE,iBAAA;C5DkjML;A4D9iMG;EACE,iBAAA;C5DgjML;A4DtiMD;EACE,mBAAA;EACA,aAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;C5DwiMD;A4DjjMD;EAYI,sBAAA;EACA,YAAA;EACA,aAAA;EACA,YAAA;EACA,oBAAA;EACA,uBAAA;EACA,oBAAA;EACA,gBAAA;EAWA,0BAAA;EACA,mCAAA;C5D8hMH;A4D7jMD;EAkCI,UAAA;EACA,YAAA;EACA,aAAA;EACA,uBAAA;C5D8hMH;A4DvhMD;EACE,mBAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,YAAA;EACA,kBAAA;EACA,qBAAA;EACA,YAAA;EACA,mBAAA;EACA,0CAAA;C5DyhMD;A4DxhMC;EACE,kBAAA;C5D0hMH;A4Dj/LD;EAhCE;;;;IAKI,YAAA;IACA,aAAA;IACA,kBAAA;IACA,gBAAA;G5DmhMH;E4D3hMD;;IAYI,mBAAA;G5DmhMH;E4D/hMD;;IAgBI,oBAAA;G5DmhMH;E4D9gMD;IACE,UAAA;IACA,WAAA;IACA,qBAAA;G5DghMD;E4D5gMD;IACE,aAAA;G5D8gMD;CACF;A6D7wMC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEE,aAAA;EACA,eAAA;C7D6yMH;A6D3yMC;;;;;;;;;;;;;;;;EACE,YAAA;C7D4zMH;AiCp0MD;E6BRE,eAAA;EACA,kBAAA;EACA,mBAAA;C9D+0MD;AiCt0MD;EACE,wBAAA;CjCw0MD;AiCt0MD;EACE,uBAAA;CjCw0MD;AiCh0MD;EACE,yBAAA;CjCk0MD;AiCh0MD;EACE,0BAAA;CjCk0MD;AiCh0MD;EACE,mBAAA;CjCk0MD;AiCh0MD;E8BzBE,YAAA;EACA,mBAAA;EACA,kBAAA;EACA,8BAAA;EACA,UAAA;C/D41MD;AiC9zMD;EACE,yBAAA;CjCg0MD;AiCzzMD;EACE,gBAAA;CjC2zMD;AgE51MD;EACE,oBAAA;ChE81MD;AgEx1MD;;;;ECdE,yBAAA;CjE42MD;AgEv1MD;;;;;;;;;;;;EAYE,yBAAA;ChEy1MD;AgEl1MD;EA6IA;IC7LE,0BAAA;GjEs4MC;EiEr4MD;IAAU,0BAAA;GjEw4MT;EiEv4MD;IAAU,8BAAA;GjE04MT;EiEz4MD;;IACU,+BAAA;GjE44MT;CACF;AgE51MD;EAwIA;IA1II,0BAAA;GhEk2MD;CACF;AgE51MD;EAmIA;IArII,2BAAA;GhEk2MD;CACF;AgE51MD;EA8HA;IAhII,iCAAA;GhEk2MD;CACF;AgE31MD;EAwHA;IC7LE,0BAAA;GjEo6MC;EiEn6MD;IAAU,0BAAA;GjEs6MT;EiEr6MD;IAAU,8BAAA;GjEw6MT;EiEv6MD;;IACU,+BAAA;GjE06MT;CACF;AgEr2MD;EAmHA;IArHI,0BAAA;GhE22MD;CACF;AgEr2MD;EA8GA;IAhHI,2BAAA;GhE22MD;CACF;AgEr2MD;EAyGA;IA3GI,iCAAA;GhE22MD;CACF;AgEp2MD;EAmGA;IC7LE,0BAAA;GjEk8MC;EiEj8MD;IAAU,0BAAA;GjEo8MT;EiEn8MD;IAAU,8BAAA;GjEs8MT;EiEr8MD;;IACU,+BAAA;GjEw8MT;CACF;AgE92MD;EA8FA;IAhGI,0BAAA;GhEo3MD;CACF;AgE92MD;EAyFA;IA3FI,2BAAA;GhEo3MD;CACF;AgE92MD;EAoFA;IAtFI,iCAAA;GhEo3MD;CACF;AgE72MD;EA8EA;IC7LE,0BAAA;GjEg+MC;EiE/9MD;IAAU,0BAAA;GjEk+MT;EiEj+MD;IAAU,8BAAA;GjEo+MT;EiEn+MD;;IACU,+BAAA;GjEs+MT;CACF;AgEv3MD;EAyEA;IA3EI,0BAAA;GhE63MD;CACF;AgEv3MD;EAoEA;IAtEI,2BAAA;GhE63MD;CACF;AgEv3MD;EA+DA;IAjEI,iCAAA;GhE63MD;CACF;AgEt3MD;EAyDA;ICrLE,yBAAA;GjEs/MC;CACF;AgEt3MD;EAoDA;ICrLE,yBAAA;GjE2/MC;CACF;AgEt3MD;EA+CA;ICrLE,yBAAA;GjEggNC;CACF;AgEt3MD;EA0CA;ICrLE,yBAAA;GjEqgNC;CACF;AgEn3MD;ECnJE,yBAAA;CjEygND;AgEh3MD;EA4BA;IC7LE,0BAAA;GjEqhNC;EiEphND;IAAU,0BAAA;GjEuhNT;EiEthND;IAAU,8BAAA;GjEyhNT;EiExhND;;IACU,+BAAA;GjE2hNT;CACF;AgE93MD;EACE,yBAAA;ChEg4MD;AgE33MD;EAqBA;IAvBI,0BAAA;GhEi4MD;CACF;AgE/3MD;EACE,yBAAA;ChEi4MD;AgE53MD;EAcA;IAhBI,2BAAA;GhEk4MD;CACF;AgEh4MD;EACE,yBAAA;ChEk4MD;AgE73MD;EAOA;IATI,iCAAA;GhEm4MD;CACF;AgE53MD;EACA;ICrLE,yBAAA;GjEojNC;CACF","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n border: 0;\n background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #fff;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #fff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #ccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #fff;\n border: 1px solid #ddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #fff;\n border-color: #ddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #fff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #fff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n 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);\n 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);\n 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);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n 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);\n 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);\n 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);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n 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);\n 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);\n 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);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n 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);\n 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);\n 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);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n 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);\n 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);\n 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);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #fff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #fff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #fff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #fff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: floor((@gutter / 2));\n padding-right: ceil((@gutter / 2));\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Unstyle the caret on ``\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n .border-top-radius(@btn-border-radius-base);\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n .border-top-radius(0);\n .border-bottom-radius(@btn-border-radius-base);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n\n &:focus {\n z-index: 3;\n }\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @input-border-radius;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @input-border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @input-border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on

    Part of this mapping code has been kindly borrowed from Apache Ant. (borrowed from spring) + * + *