CHUKWA-746. Redesigned Chukwa dashboard. (Eric Yang)
Project: http://git-wip-us.apache.org/repos/asf/chukwa/repo Commit: http://git-wip-us.apache.org/repos/asf/chukwa/commit/dfe84a2c Tree: http://git-wip-us.apache.org/repos/asf/chukwa/tree/dfe84a2c Diff: http://git-wip-us.apache.org/repos/asf/chukwa/diff/dfe84a2c Branch: refs/heads/master Commit: dfe84a2c3721521a1007d33e8f7daa15ea99aef2 Parents: 0f9b5cf Author: Eric Yang <[email protected]> Authored: Mon May 25 17:12:10 2015 -0700 Committer: Eric Yang <[email protected]> Committed: Mon May 25 17:12:10 2015 -0700 ---------------------------------------------------------------------- CHANGES.txt | 2 + NOTICE.txt | 18 + conf/shiro.ini | 46 + pom.xml | 33 +- .../adaptor/sigar/SigarRunner.java | 14 +- .../datacollection/writer/hbase/Reporter.java | 4 +- .../chukwa/datastore/ChukwaHBaseStore.java | 91 +- .../apache/hadoop/chukwa/hicc/TimeHandler.java | 2 + .../hadoop/chukwa/hicc/bean/BarOptions.java | 31 + .../hadoop/chukwa/hicc/bean/Dashboard.java | 31 + .../chukwa/hicc/bean/SessionAttribute.java | 36 + .../apache/hadoop/chukwa/hicc/bean/Widget.java | 52 +- .../chukwa/hicc/rest/DashboardController.java | 72 + .../chukwa/hicc/rest/HeatmapController.java | 3 +- .../chukwa/hicc/rest/SessionController.java | 71 + .../chukwa/hicc/rest/WidgetController.java | 1 - .../apache/hadoop/chukwa/util/HBaseUtil.java | 14 +- src/main/web/hicc/WEB-INF/jetty.xml | 4 +- src/main/web/hicc/WEB-INF/vm/chart.vm | 9 +- src/main/web/hicc/WEB-INF/web.xml | 24 +- src/main/web/hicc/css/bootstrap-theme.css.map | 1 + src/main/web/hicc/css/bootstrap-theme.min.css | 5 + src/main/web/hicc/css/bootstrap.min.css | 5 + src/main/web/hicc/css/iframe.css | 3 +- src/main/web/hicc/css/images/bg.jpg | Bin 0 -> 206819 bytes src/main/web/hicc/css/login.css | 88 + .../hicc/fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../hicc/fonts/glyphicons-halflings-regular.svg | 288 ++ .../hicc/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 src/main/web/hicc/graph-explorer.html | 328 -- src/main/web/hicc/home/css/component.css | 620 +++ src/main/web/hicc/home/css/jquery.gridster.css | 350 ++ .../web/hicc/home/css/jquery.gridster.min.css | 2 + src/main/web/hicc/home/css/normalize.css | 18 + .../home/fonts/codropsicons/codropsicons.eot | Bin 0 -> 2244 bytes .../home/fonts/codropsicons/codropsicons.svg | 24 + .../home/fonts/codropsicons/codropsicons.ttf | Bin 0 -> 2060 bytes .../home/fonts/codropsicons/codropsicons.woff | Bin 0 -> 2072 bytes .../hicc/home/fonts/codropsicons/license.txt | 6 + .../web/hicc/home/fonts/ecoicons/Read Me.txt | 3 + .../hicc/home/fonts/ecoicons/ecoicons.dev.svg | 70 + .../web/hicc/home/fonts/ecoicons/ecoicons.eot | Bin 0 -> 3576 bytes .../web/hicc/home/fonts/ecoicons/ecoicons.svg | 70 + .../web/hicc/home/fonts/ecoicons/ecoicons.ttf | Bin 0 -> 3408 bytes .../web/hicc/home/fonts/ecoicons/ecoicons.woff | Bin 0 -> 4132 bytes .../web/hicc/home/fonts/ecoicons/license.txt | 2 + src/main/web/hicc/home/graph-explorer.html | 346 ++ src/main/web/hicc/home/help/index.html | 58 + src/main/web/hicc/home/index.html | 290 ++ src/main/web/hicc/home/js/classie.js | 80 + src/main/web/hicc/home/js/gnmenu.js | 94 + src/main/web/hicc/home/js/jquery.gridster.js | 4051 +++++++++++++++++ .../web/hicc/home/js/jquery.gridster.min.js | 2 + .../hicc/home/js/jquery.gridster.with-extras.js | 4163 ++++++++++++++++++ .../home/js/jquery.gridster.with-extras.min.js | 2 + src/main/web/hicc/home/js/jquery.js | 4 + src/main/web/hicc/home/js/modernizr.custom.js | 4 + src/main/web/hicc/home/js/typeahead.bundle.js | 1783 ++++++++ src/main/web/hicc/home/settings/index.html | 57 + src/main/web/hicc/index.html | 20 + src/main/web/hicc/index.jsp | 256 -- src/main/web/hicc/iphone.jsp | 177 - src/main/web/hicc/js/bootstrap.min.js | 7 + src/main/web/hicc/js/flot.extend.js | 13 +- src/main/web/hicc/js/jquery.flot.pack.js | 35 +- src/main/web/hicc/js/jquery.js | 4 + src/main/web/hicc/js/js-cookie.js | 137 + src/main/web/hicc/jsp/heatmap.jsp | 20 +- src/main/web/hicc/login.jsp | 52 + 71 files changed, 13268 insertions(+), 828 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index f8b4890..40f85a2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,8 @@ Trunk (unreleased changes) NEW FEATURES + CHUKWA-746. Redesigned Chukwa dashboard. (Eric Yang) + CHUKWA-736. SSL support for chukwa. (Shreyas Subramanya) CHUKWA-737. Heartbeat adaptor to push status to remote http server (Shreyas Subramanya) http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/NOTICE.txt ---------------------------------------------------------------------- diff --git a/NOTICE.txt b/NOTICE.txt index 519aada..09ea5f1 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -69,3 +69,21 @@ Copyright (c) 2009 - 2014 Jonathan Hedley ([email protected]) This product includes esapi Copyright (c) 2015 OWASP Project, https://www.owasp.org + +This product includes js-cookie.js +Copyright (c) 2006, 2015 Klaus Hartl, https://github.com/js-cookie/js-cookie + +This product includes Bootstrap +Copyright (c) 2011-2015 Twitter, Inc. + +This product includes typeahead.js +Copyright (c) 2011-2015 Twitter, Inc. + +This product includes gridster.js +Copyright (c) 2014 ducksboard, http://gridster.net/ + +This product includes Modernizr +Copyright (c) 2009-2015 modernizr.com + +This product includes bonzo +Copyright (c) 2012 Dustin Diaz, https://github.com/ded/bonzo http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/conf/shiro.ini ---------------------------------------------------------------------- diff --git a/conf/shiro.ini b/conf/shiro.ini new file mode 100644 index 0000000..a584f7e --- /dev/null +++ b/conf/shiro.ini @@ -0,0 +1,46 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# INI configuration is very powerful and flexible, while still remaining succinct. +# Please http://shiro.apache.org/configuration.html and +# http://shiro.apache.org/web.html for more. + +[main] +shiro.loginUrl = /login.jsp + +[users] +# format: username = password, role1, role2, ..., roleN +admin = admin,admin +guest = guest,guest + +[roles] +# format: roleName = permission1, permission2, ..., permissionN +admin = * + +[urls] +# The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but +# the 'authc' filter must still be specified for it so it can process that url's +# login submissions. It is 'smart' enough to allow those requests through as specified by the +# shiro.loginUrl above. +/login.jsp = authc +/logout = logout +/index.html = authc +/home/css/** = anon +/home/js/** = anon +/home/** = authc +/v1/** = authc http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 1c8d26c..49cad82 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ <package.log.dir>/var/log/chukwa</package.log.dir> <package.pid.dir>/var/run/chukwa</package.pid.dir> <package.release>1</package.release> - <package.version>0.6.0</package.version> + <package.version>0.7.0</package.version> <final.name>${project.artifactId}-${package.version}</final.name> <TODO_ALERT_EMAIL>[email protected]</TODO_ALERT_EMAIL> <TODO_CLUSTER_NAME>chukwa</TODO_CLUSTER_NAME> @@ -58,7 +58,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.apache.chukwa</groupId> - <version>0.6.0</version> + <version>0.7.0-SNAPSHOT</version> <artifactId>chukwa</artifactId> <packaging>jar</packaging> @@ -329,6 +329,16 @@ <artifactId>jsp-api-2.1</artifactId> <version>6.1.14</version> </dependency> + <dependency> + <groupId>org.apache.shiro</groupId> + <artifactId>shiro-core</artifactId> + <version>1.2.3</version> + </dependency> + <dependency> + <groupId>org.apache.shiro</groupId> + <artifactId>shiro-web</artifactId> + <version>1.2.3</version> + </dependency> </dependencies> <developers> @@ -811,7 +821,8 @@ <exclude>contrib/solr/logs/conf/lang/stopwords_pt.txt</exclude> <exclude>contrib/solr/logs/conf/lang/stopwords_ru.txt</exclude> <exclude>contrib/solr/logs/conf/lang/stopwords_sv.txt</exclude> - <exclude>src/main/web/hicc/js/jquery-*</exclude> + <exclude>src/main/web/hicc/js/jquery*</exclude> + <exclude>src/main/web/hicc/home/js/jquery.js</exclude> <exclude>src/main/web/hicc/css/iui.css</exclude> <exclude>src/main/web/hicc/js/behaviour.js</exclude> <exclude>src/main/web/hicc/js/heatmap.js</exclude> @@ -844,6 +855,20 @@ <exclude>src/main/web/hicc/js/workspace/prototype.js</exclude> <exclude>src/main/web/hicc/js/jquery.flot.pack.js</exclude> <exclude>src/main/web/hicc/js/gsv.js</exclude> + <exclude>src/main/web/hicc/js/bootstrap.min.js</exclude> + <exclude>src/main/web/hicc/js/js-cookie.js</exclude> + <exclude>src/main/web/hicc/css/bootstrap-theme.css.map</exclude> + <exclude>src/main/web/hicc/css/bootstrap-theme.min.css</exclude> + <exclude>src/main/web/hicc/css/bootstrap.min.css</exclude> + <exclude>src/main/web/hicc/fonts/glyphicons-halflings-regular.svg</exclude> + <exclude>src/main/web/hicc/home/js/jquery.gridster.min.js</exclude> + <exclude>src/main/web/hicc/home/js/jquery.gridster.with-extras.min.js</exclude> + <exclude>src/main/web/hicc/home/css/jquery.gridster.css</exclude> + <exclude>src/main/web/hicc/home/css/jquery.gridster.min.css</exclude> + <exclude>src/main/web/hicc/home/js/typeahead.bundle.js</exclude> + <exclude>src/main/web/hicc/home/js/classie.js</exclude> + <exclude>src/main/web/hicc/home/js/gnmenu.js</exclude> + <exclude>src/main/web/hicc/home/js/modernizr.custom.js</exclude> <!-- Creative Commons licensed files --> <exclude>src/main/web/hicc/js/autoHeight.js</exclude> @@ -852,6 +877,8 @@ <exclude>src/main/web/hicc/js/base64.js</exclude> <exclude>src/main/web/hicc/js/canvas2image.js</exclude> <exclude>src/main/web/hicc/js/json.js</exclude> + <exclude>src/main/web/hicc/home/fonts/codropsicons/*</exclude> + <exclude>src/main/web/hicc/home/fonts/ecoicons/*</exclude> </excludes> </configuration> </plugin> http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/datacollection/adaptor/sigar/SigarRunner.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/datacollection/adaptor/sigar/SigarRunner.java b/src/main/java/org/apache/hadoop/chukwa/datacollection/adaptor/sigar/SigarRunner.java index cd420d0..d23675e 100644 --- a/src/main/java/org/apache/hadoop/chukwa/datacollection/adaptor/sigar/SigarRunner.java +++ b/src/main/java/org/apache/hadoop/chukwa/datacollection/adaptor/sigar/SigarRunner.java @@ -80,13 +80,13 @@ public class SigarRunner extends TimerTask { for (int i = 0; i < cpuinfo.length; i++) { JSONObject cpuMap = new JSONObject(); cpuMap.putAll(cpuinfo[i].toMap()); - cpuMap.put("combined", cpuPerc[i].getCombined()); - cpuMap.put("user", cpuPerc[i].getUser()); - cpuMap.put("sys", cpuPerc[i].getSys()); - cpuMap.put("idle", cpuPerc[i].getIdle()); - cpuMap.put("wait", cpuPerc[i].getWait()); - cpuMap.put("nice", cpuPerc[i].getNice()); - cpuMap.put("irq", cpuPerc[i].getIrq()); + cpuMap.put("combined", cpuPerc[i].getCombined() * 100); + cpuMap.put("user", cpuPerc[i].getUser() * 100); + cpuMap.put("sys", cpuPerc[i].getSys() * 100); + cpuMap.put("idle", cpuPerc[i].getIdle() * 100); + cpuMap.put("wait", cpuPerc[i].getWait() * 100); + cpuMap.put("nice", cpuPerc[i].getNice() * 100); + cpuMap.put("irq", cpuPerc[i].getIrq() * 100); cpuList.add(cpuMap); } sigar.getCpuPerc(); http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/Reporter.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/Reporter.java b/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/Reporter.java index 8b1674d..e6e1f1b 100644 --- a/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/Reporter.java +++ b/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/Reporter.java @@ -86,8 +86,8 @@ public class Reporter { } private byte[] getHash(String key) { - byte[] hash = new byte[3]; - System.arraycopy(md5.digest(key.getBytes()), 0, hash, 0, 3); + byte[] hash = new byte[5]; + System.arraycopy(md5.digest(key.getBytes()), 0, hash, 0, 5); return hash; } http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java index 476bd79..66553c4 100644 --- a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java +++ b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java @@ -34,6 +34,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.TimeUnit; import org.apache.hadoop.chukwa.hicc.bean.Chart; +import org.apache.hadoop.chukwa.hicc.bean.Dashboard; import org.apache.hadoop.chukwa.hicc.bean.HeatMapPoint; import org.apache.hadoop.chukwa.hicc.bean.Heatmap; import org.apache.hadoop.chukwa.hicc.bean.LineOptions; @@ -73,6 +74,7 @@ public class ChukwaHBaseStore { static byte[] CHART_FAMILY = "c".getBytes(); static byte[] COMMON_FAMILY = "c".getBytes(); static byte[] WIDGET_TYPE = "widget_meta".getBytes(); + static byte[] DASHBOARD_TYPE = "dashboard_meta".getBytes(); private static final String CHUKWA = "chukwa"; private static final String CHUKWA_META = "chukwa_meta"; private static long MILLISECONDS_IN_DAY = 86400000L; @@ -253,8 +255,8 @@ public class ChukwaHBaseStore { } public static Heatmap getHeatmap(String metricGroup, String metric, - long startTime, long endTime, double max, double scale, int height) { - final long MINUTE = TimeUnit.MINUTES.toMillis(1); + long startTime, long endTime, double max, double scale, int width, int height) { + final long SECONDS = TimeUnit.SECONDS.toMillis(1); Heatmap heatmap = new Heatmap(); Set<String> sources = getSourceNames(metricGroup); Set<String> metrics = getMetricNames(metricGroup); @@ -283,8 +285,9 @@ public class ChukwaHBaseStore { } currentDay = currentDay + (i * MILLISECONDS_IN_DAY); } + long timeRange = (endTime - startTime); Result[] rs = table.get(series); - int index = 0; + int index = 1; // Series display in y axis int y = 0; HashMap<String, Integer> keyMap = new HashMap<String, Integer>(); @@ -295,7 +298,10 @@ public class ChukwaHBaseStore { String source = new String(dest); long time = cell.getTimestamp(); // Time display in x axis - int x = (int) ((time - startTime) / MINUTE); + long delta = time - startTime; + double f = (double) delta / timeRange; + f = (double) f * width; + int x = (int) Math.round(f); if (keyMap.containsKey(source)) { y = keyMap.get(source); } else { @@ -320,7 +326,7 @@ public class ChukwaHBaseStore { point.put(point.x, point.y * radius, round); } heatmap.putRadius(radius); - heatmap.putSeries(index); + heatmap.putSeries(index -1); } catch (IOException e) { closeHBase(); LOG.error(ExceptionUtil.getStackTrace(e)); @@ -716,7 +722,21 @@ public class ChukwaHBaseStore { // Populate default widgets Widget widget = new Widget(); widget.setTitle("System Load Average"); - widget.setUrl(new URI("/hicc/v1/chart/draw/1")); + widget.setSrc(new URI("/hicc/v1/chart/draw/1")); + widget.setCol(1); + widget.setRow(1); + widget.setSize_x(7); + widget.setSize_y(1); + createWidget(widget); + + // CPU heatmap + widget = new Widget(); + widget.setTitle("CPU Heatmap"); + widget.setSrc(new URI("/hicc/jsp/heatmap.jsp")); + widget.setCol(1); + widget.setRow(1); + widget.setSize_x(4); + widget.setSize_y(2); createWidget(widget); // Populate example chart widgets @@ -735,8 +755,67 @@ public class ChukwaHBaseStore { chart.SetSeries(series); createChart(chart); + + Dashboard dashboard = new Dashboard(); + dashboard.add(widget); + updateDashboard("default", "", dashboard); } catch (Throwable ex) { LOG.error(ExceptionUtil.getStackTrace(ex)); } } + + public static synchronized Dashboard getDashboard(String id, String user) { + Dashboard dash = null; + String key = new StringBuilder().append(id). + append("|").append(user).toString(); + try { + getHBaseConnection(); + Table table = connection.getTable(TableName.valueOf(CHUKWA_META)); + Get dashboard = new Get(DASHBOARD_TYPE); + dashboard.addColumn(COMMON_FAMILY, key.getBytes()); + Result rs = table.get(dashboard); + byte[] buffer = rs.getValue(COMMON_FAMILY, key.getBytes()); + if(buffer == null) { + // If user dashboard is not found, use default dashboard. + key = new StringBuilder().append(id).append("|").toString(); + dashboard = new Get(DASHBOARD_TYPE); + dashboard.addColumn(COMMON_FAMILY, key.getBytes()); + rs = table.get(dashboard); + buffer = rs.getValue(COMMON_FAMILY, key.getBytes()); + } + Gson gson = new Gson(); + dash = gson.fromJson(new String(buffer), Dashboard.class); + table.close(); + } catch (Exception e) { + closeHBase(); + LOG.error(ExceptionUtil.getStackTrace(e)); + LOG.error("Error retrieving dashboard, id: " + + id + " user:" + user); + } + return dash; + } + + public static boolean updateDashboard(String id, String user, Dashboard dash) { + boolean result = false; + String key = new StringBuilder().append(id). + append("|").append(user).toString(); + try { + getHBaseConnection(); + Table table = connection.getTable(TableName.valueOf(CHUKWA_META)); + Put put = new Put(DASHBOARD_TYPE); + Gson gson = new Gson(); + String buffer = gson.toJson(dash); + put.add(COMMON_FAMILY, key.getBytes(), buffer.getBytes()); + table.put(put); + table.close(); + result = true; + } catch (Exception e) { + closeHBase(); + LOG.error(ExceptionUtil.getStackTrace(e)); + LOG.error("Error in updating dashboard, id: " + + id + " user:" + user); + } + return result; + } + } http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/TimeHandler.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/TimeHandler.java b/src/main/java/org/apache/hadoop/chukwa/hicc/TimeHandler.java index b692c3d..7844b65 100644 --- a/src/main/java/org/apache/hadoop/chukwa/hicc/TimeHandler.java +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/TimeHandler.java @@ -118,6 +118,8 @@ public class TimeHandler { start = end - (7 * 24 * 60 * 60 * 1000); } else if (period.equals("last30d")) { start = end - (30L * 24 * 60 * 60 * 1000); + } else if (period.equals("lastyear")) { + start = end - (365L * 24 * 60 * 60 * 1000); } else if (period.startsWith("custom;")) { // default value is between 2 days ago and now http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/bean/BarOptions.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/BarOptions.java b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/BarOptions.java index e69de29..12c6b12 100644 --- a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/BarOptions.java +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/BarOptions.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.chukwa.hicc.bean; + + +public class BarOptions extends SeriesOptions { + public boolean zero; + public boolean stepByStep = true; + public int barWidth = 4; + public String align; + public boolean horizontal; + + public BarOptions() { + fill = true; + } +} http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Dashboard.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Dashboard.java b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Dashboard.java new file mode 100644 index 0000000..eb12674 --- /dev/null +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Dashboard.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.chukwa.hicc.bean; + +import java.util.ArrayList; + +public class Dashboard { + ArrayList<Widget> grid = null; + + public void add(Widget widget) { + if(grid==null) { + grid = new ArrayList<Widget>(); + } + grid.add(widget); + } +} http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/bean/SessionAttribute.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/SessionAttribute.java b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/SessionAttribute.java new file mode 100644 index 0000000..b9f9d88 --- /dev/null +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/SessionAttribute.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.chukwa.hicc.bean; + +public class SessionAttribute { + public String key; + public String value; + + public SessionAttribute(String id, String value) { + this.key = id; + this.value = value; + } + + public String getKey() { + return this.key; + } + + public String getValue() { + return this.value; + } +} http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Widget.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Widget.java b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Widget.java index 987f525..61dc0b5 100644 --- a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Widget.java +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Widget.java @@ -26,12 +26,52 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Widget { @XmlElement + public int col; + @XmlElement + public int row; + @XmlElement + public int size_x; + @XmlElement + public int size_y; + @XmlElement public String title; @XmlElement - public URI url; + public URI src; @XmlElement public String[] tokens; + public int getCol() { + return col; + } + + public void setCol(int col) { + this.col = col; + } + + public int getRow() { + return row; + } + + public void setRow(int row) { + this.row = row; + } + + public int getSize_x() { + return size_x; + } + + public void setSize_x(int size_x) { + this.size_x = size_x; + } + + public int getSize_y() { + return size_y; + } + + public void setSize_y(int size_y) { + this.size_y = size_y; + } + public String getTitle() { return title; } @@ -40,12 +80,12 @@ public class Widget { this.title = title; } - public URI getUrl() { - return url; + public URI getSrc() { + return src; } - public void setUrl(URI url) { - this.url = url; + public void setSrc(URI src) { + this.src = src; } public String[] getTokens() { @@ -58,6 +98,6 @@ public class Widget { public void tokenize() { String[] tokens = title.split(" "); - this.tokens = tokens; + this.tokens = tokens; } } http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java new file mode 100644 index 0000000..987e405 --- /dev/null +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.chukwa.hicc.rest; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.hadoop.chukwa.datastore.ChukwaHBaseStore; +import org.apache.hadoop.chukwa.hicc.bean.Dashboard; +import org.apache.log4j.Logger; + +import com.google.gson.Gson; + +@Path("dashboard") +public class DashboardController { + static Logger LOG = Logger.getLogger(DashboardController.class); + + @Context + private ServletContext context; + + @GET + @Path("load/{id}") + public String load(@Context HttpServletRequest request, @PathParam("id") String id) { + Gson gson = new Gson(); + Dashboard dash = ChukwaHBaseStore.getDashboard(id, request.getRemoteUser()); + String json = gson.toJson(dash); + return json; + } + + @PUT + @Path("save/{id}") + @Consumes(MediaType.APPLICATION_JSON) + public Response save(@Context HttpServletRequest request, @PathParam("id") String id, String buffer) { + Gson gson = new Gson(); + Dashboard dash = gson.fromJson(buffer, Dashboard.class); + boolean result = ChukwaHBaseStore.updateDashboard(id, request.getRemoteUser(), dash); + if(!result) { + return Response.status(Status.BAD_REQUEST).build(); + } + return Response.ok().build(); + } + + @GET + @Path("whoami") + public String whoami(@Context HttpServletRequest request) { + return request.getRemoteUser(); + } +} http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/rest/HeatmapController.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/HeatmapController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/HeatmapController.java index 4c7d5c5..621f318 100644 --- a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/HeatmapController.java +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/HeatmapController.java @@ -48,6 +48,7 @@ public class HeatmapController { @QueryParam("end") String end, @QueryParam("max") @DefaultValue("1.0") double max, @QueryParam("scale") @DefaultValue("100") double scale, + @QueryParam("width") @DefaultValue("700") int width, @QueryParam("height") @DefaultValue("400") int height) { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); Heatmap heatmap = null; @@ -66,7 +67,7 @@ public class HeatmapController { endTime = time.getEndTime(); } heatmap = ChukwaHBaseStore.getHeatmap(metricGroup, metric, startTime, - endTime, max, scale, height); + endTime, max, scale, width, height); } catch (Throwable e) { log.error(ExceptionUtil.getStackTrace(e)); } http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/rest/SessionController.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/SessionController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/SessionController.java new file mode 100644 index 0000000..ceed0df --- /dev/null +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/SessionController.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.chukwa.hicc.rest; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.log4j.Logger; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +@Path("session") +public class SessionController { + static Logger LOG = Logger.getLogger(SessionController.class); + + /** + * Utility to get session attributes + * @param id + * @return session attribute + */ + @GET + @Path("key/{id}") + @Produces(MediaType.APPLICATION_JSON) + public String draw(@Context HttpServletRequest request, @PathParam("id") String id) { + String value = (String) request.getSession().getAttribute(id); + Map<String, String> map = new HashMap<String, String>(); + map.put(id, value); + Gson gson = new Gson(); + String json = gson.toJson(map); + return json; + } + + @PUT + @Path("save") + public Response save(@Context HttpServletRequest request, String buffer) { + Gson gson = new Gson(); + Type stringStringMap = new TypeToken<Map<String, String>>(){}.getType(); + Map<String,String> map = gson.fromJson(buffer, stringStringMap); + for(String key : map.keySet()) { + request.getSession().setAttribute(key, map.get(key)); + } + return Response.ok().build(); + } +} http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/hicc/rest/WidgetController.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/WidgetController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/WidgetController.java index 1df8efb..64afc19 100644 --- a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/WidgetController.java +++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/WidgetController.java @@ -20,7 +20,6 @@ package org.apache.hadoop.chukwa.hicc.rest; import java.util.List; import javax.annotation.PostConstruct; -import javax.inject.Scope; import javax.inject.Singleton; import javax.servlet.ServletContext; import javax.ws.rs.Consumes; http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java b/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java index b0ae38e..c655e24 100644 --- a/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java +++ b/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java @@ -53,9 +53,9 @@ public class HBaseUtil { c.setTimeInMillis(time); byte[] day = Integer.toString(c.get(Calendar.DAY_OF_YEAR)).getBytes(); byte[] pk = getHash(primaryKey); - byte[] key = new byte[8]; + byte[] key = new byte[12]; System.arraycopy(day, 0, key, 0, day.length); - System.arraycopy(pk, 0, key, 2, 3); + System.arraycopy(pk, 0, key, 2, 5); return key; } @@ -64,16 +64,16 @@ public class HBaseUtil { byte[] day = Integer.toString(c.get(Calendar.DAY_OF_YEAR)).getBytes(); byte[] pk = getHash(primaryKey); byte[] src = getHash(source); - byte[] key = new byte[8]; + byte[] key = new byte[12]; System.arraycopy(day, 0, key, 0, day.length); - System.arraycopy(pk, 0, key, 2, 3); - System.arraycopy(src, 0, key, 5, 3); + System.arraycopy(pk, 0, key, 2, 5); + System.arraycopy(src, 0, key, 7, 5); return key; } private static byte[] getHash(String key) { - byte[] hash = new byte[3]; - System.arraycopy(md5.digest(key.getBytes()), 0, hash, 0, 3); + byte[] hash = new byte[5]; + System.arraycopy(md5.digest(key.getBytes()), 0, hash, 0, 5); return hash; } } http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/web/hicc/WEB-INF/jetty.xml ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/WEB-INF/jetty.xml b/src/main/web/hicc/WEB-INF/jetty.xml index 91fdee5..f0b473d 100644 --- a/src/main/web/hicc/WEB-INF/jetty.xml +++ b/src/main/web/hicc/WEB-INF/jetty.xml @@ -97,7 +97,7 @@ </Set> --> - <Set name="UserRealms"> + <!-- <Set name="UserRealms"> <Array type="org.mortbay.jetty.security.UserRealm"> <Item> <New class="org.mortbay.jetty.security.HashUserRealm"> @@ -107,7 +107,7 @@ </New> </Item> </Array> - </Set> + </Set> --> <!-- =========================================================== --> <!-- Set handler Collection Structure --> http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/web/hicc/WEB-INF/vm/chart.vm ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/WEB-INF/vm/chart.vm b/src/main/web/hicc/WEB-INF/vm/chart.vm index 90cb1d7..67d671c 100644 --- a/src/main/web/hicc/WEB-INF/vm/chart.vm +++ b/src/main/web/hicc/WEB-INF/vm/chart.vm @@ -18,9 +18,9 @@ <!DOCTYPE html> <html lang="en"> <head> - <link href="/hicc/css/default.css" rel="stylesheet" type="text/css"> - <link href="/hicc/css/iframe.css" rel="stylesheet" type="text/css"> - <link href="/hicc/css/flexigrid/flexigrid.css" rel="stylesheet" type="text/css"> + <link type="text/css" rel="stylesheet" href="/hicc/css/default.css" /> + <link type="text/css" rel="stylesheet" href="/hicc/css/iframe.css" /> + <link type="text/css" rel="stylesheet" href="/hicc/css/flexigrid/flexigrid.css" /> </head> <body> <div id="placeholderTitle"><center>$chart.getTitle()</center></div> @@ -33,12 +33,13 @@ <div class="legendHolder"> <div class="center" id="statisLegend"></div> </div> - <script type="text/javascript" src="/hicc/js/jquery-1.2.6.min.js"></script> + <script type="text/javascript" src="/hicc/js/jquery.js"></script> <script type="text/javascript" src="/hicc/js/jquery.flot.pack.js"></script> <script type="text/javascript" src="/hicc/js/flexigrid.pack.js"></script> <script type="text/javascript" src="/hicc/js/excanvas.pack.js"></script> <script type="text/javascript" src="/hicc/js/base64.js"></script> <script type="text/javascript" src="/hicc/js/canvas2image.js"></script> + <script type="text/javascript" src="/hicc/js/js-cookie.js"></script> <script type="text/javascript" src="/hicc/js/flot.extend.js"></script> <script type="text/javascript"> http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/web/hicc/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/WEB-INF/web.xml b/src/main/web/hicc/WEB-INF/web.xml index 2437f08..36e9691 100644 --- a/src/main/web/hicc/WEB-INF/web.xml +++ b/src/main/web/hicc/WEB-INF/web.xml @@ -22,9 +22,25 @@ version="2.5"> <description> - Workspace + Hadoop Infrastructure Care Center </description> - <display-name>Workspace</display-name> + <display-name>hicc</display-name> + + <listener> + <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> + </listener> + <filter> + <filter-name>ShiroFilter</filter-name> + <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class> + </filter> + <filter-mapping> + <filter-name>ShiroFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <welcome-file-list> + <welcome-file>index.html</welcome-file> + <welcome-file>index.jsp</welcome-file> + </welcome-file-list> <servlet> <servlet-name>Workspace</servlet-name> @@ -58,7 +74,7 @@ <url-pattern>/v1/*</url-pattern> </servlet-mapping> - <security-role> +<!-- <security-role> <role-name>user</role-name> </security-role> @@ -75,6 +91,6 @@ <auth-constraint> <role-name>user</role-name> </auth-constraint> - </security-constraint> + </security-constraint> --> </web-app> http://git-wip-us.apache.org/repos/asf/chukwa/blob/dfe84a2c/src/main/web/hicc/css/bootstrap-theme.css.map ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/css/bootstrap-theme.css.map b/src/main/web/hicc/css/bootstrap-theme.css.map new file mode 100644 index 0000000..5a12d63 --- /dev/null +++ b/src/main/web/hicc/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","bootstrap-theme.css","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","file":"bootstrap-theme.css","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12 %));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &:disabled,\n &[disabled] {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn -styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gr adient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n\n .navbar -nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @sh adow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-grou p-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-head ing-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\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 will be 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); // I E9 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(@degr ees);\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.tra nsition(@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",".btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\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-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info . badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default:disabled,\n.btn-default[disabled] {\n background-color: #e0e0 e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary:disabled,\n.btn-primary[disabled] {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-lin ear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success:disabled,\n.btn-success[disabled] {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Mi crosoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info:disabled,\n.btn-info[disabled] {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-rep eat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning:disabled,\n.btn-warning[disabled] {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.bt n-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger:disabled,\n.btn-danger[disabled] {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 2 55, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n background-repeat: repeat-x; \n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear -gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x; \n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n back ground-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bott om, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0) ;\n}\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}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n .panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0% , #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Micro soft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","// 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-col or: #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-ima ge: -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 5 0%, @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","// 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"]} \ No newline at end of file
