You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2015/10/16 14:15:58 UTC

[1/7] karaf-decanter git commit: [KARAF-3904] Add elasticsearch-head feature

Repository: karaf-decanter
Updated Branches:
  refs/heads/master ac125025b -> c4719b9d0


http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/manual/src/main/asciidoc/user-guide/appenders.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/user-guide/appenders.adoc b/manual/src/main/asciidoc/user-guide/appenders.adoc
index 4f75942..64f735a 100644
--- a/manual/src/main/asciidoc/user-guide/appenders.adoc
+++ b/manual/src/main/asciidoc/user-guide/appenders.adoc
@@ -506,6 +506,19 @@ You can change these dashboards to add new panels, change the existing panels, e
 
 Of course, you can create your own dashboards, starting from blank or simple dashboards.
 
+==== Elasticsearch Head console
+
+In addition of the embedded elasticsearch instance, Decanter also provides a web console allowing you to monitor and
+manage your elasticsearch cluster. It's a ready to use elastisearch-head console, directly embedded in Karaf.
+
+The `elasticsearch-head` feature installs the embedded elasticsearch-head web console:
+
+----
+karaf@root()> feature:install elasticsearch-head
+----
+
+By default, the elasticsearch-head web console is available on `http://host:8181/elasticsearch-head`.
+
 === JDBC
 
 The Decanter JDBC appender allows your to store the data (coming from the collectors) into a database.

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index de13455..3d616e0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,7 @@
         <module>appender</module>
         <module>sla</module>
         <module>elasticsearch</module>
+        <module>elasticsearch-head</module>
         <module>kibana</module>
         <module>assembly</module>
     </modules>


[7/7] karaf-decanter git commit: [KARAF-3904] Add elasticsearch-head feature

Posted by jb...@apache.org.
[KARAF-3904] Add elasticsearch-head feature


Project: http://git-wip-us.apache.org/repos/asf/karaf-decanter/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf-decanter/commit/c4719b9d
Tree: http://git-wip-us.apache.org/repos/asf/karaf-decanter/tree/c4719b9d
Diff: http://git-wip-us.apache.org/repos/asf/karaf-decanter/diff/c4719b9d

Branch: refs/heads/master
Commit: c4719b9d081d87ffdbdceb3aa8358e09bf962c17
Parents: ac12502
Author: Jean-Baptiste Onofré <jb...@apache.org>
Authored: Fri Oct 16 14:15:24 2015 +0200
Committer: Jean-Baptiste Onofré <jb...@apache.org>
Committed: Fri Oct 16 14:15:24 2015 +0200

----------------------------------------------------------------------
 assembly/src/main/feature/feature.xml           |     5 +
 elasticsearch-head/pom.xml                      |    57 +
 elasticsearch-head/src/main/resources/app.css   |   704 +
 elasticsearch-head/src/main/resources/app.js    |  4373 +++++
 .../src/main/resources/base/favicon.png         |   Bin 0 -> 952 bytes
 .../src/main/resources/base/loading.gif         |   Bin 0 -> 1849 bytes
 .../src/main/resources/base/reset.css           |    44 +
 .../src/main/resources/fonts/FontAwesome.otf    |   Bin 0 -> 62856 bytes
 .../resources/fonts/fontawesome-webfont.eot     |   Bin 0 -> 38205 bytes
 .../resources/fonts/fontawesome-webfont.svg     |   414 +
 .../resources/fonts/fontawesome-webfont.ttf     |   Bin 0 -> 80652 bytes
 .../resources/fonts/fontawesome-webfont.woff    |   Bin 0 -> 44432 bytes
 elasticsearch-head/src/main/resources/i18n.js   |    93 +
 .../src/main/resources/index.html               |    33 +
 .../src/main/resources/lang/en_strings.js       |   174 +
 .../src/main/resources/lang/fr_strings.js       |   164 +
 .../src/main/resources/lang/pt_strings.js       |   174 +
 .../src/main/resources/lang/zh_strings.js       |   172 +
 .../src/main/resources/vendor.css               |  1338 ++
 elasticsearch-head/src/main/resources/vendor.js | 14500 +++++++++++++++++
 .../src/main/asciidoc/user-guide/appenders.adoc |    13 +
 pom.xml                                         |     1 +
 22 files changed, 22259 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/assembly/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assembly/src/main/feature/feature.xml b/assembly/src/main/feature/feature.xml
index d60ab00..77994df 100644
--- a/assembly/src/main/feature/feature.xml
+++ b/assembly/src/main/feature/feature.xml
@@ -132,6 +132,11 @@
         <bundle>mvn:org.apache.karaf.decanter/org.apache.karaf.decanter.elasticsearch/${project.version}</bundle>
     </feature>
 
+    <feature name="elasticsearch-head" version="${elasticsearch.version}" description="Elasticsearch Head web frontend">
+        <feature>war</feature>
+        <bundle>mvn:org.apache.karaf.decanter/org.apache.karaf.decanter.elasticsearch-head/${project.version}</bundle>
+    </feature>
+
     <feature name="kibana" version="${kibana.version}" description="Embedded Kibana dashboard">
         <feature>war</feature>
         <feature>elasticsearch</feature>

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/pom.xml
----------------------------------------------------------------------
diff --git a/elasticsearch-head/pom.xml b/elasticsearch-head/pom.xml
new file mode 100644
index 0000000..3ff8bc5
--- /dev/null
+++ b/elasticsearch-head/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.karaf</groupId>
+        <artifactId>decanter</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.karaf.decanter</groupId>
+    <artifactId>org.apache.karaf.decanter.elasticsearch-head</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Karaf :: Decanter :: ElasticSearch Head</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <inherited>true</inherited>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+                        <Bundle-Version>${project.version}</Bundle-Version>
+                        <Web-ContextPath>/elasticsearch-head</Web-ContextPath>
+                        <Import-Package>
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/app.css
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/app.css b/elasticsearch-head/src/main/resources/app.css
new file mode 100644
index 0000000..2fa2152
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/app.css
@@ -0,0 +1,704 @@
+TABLE.table {
+	border-collapse: collapse;
+}
+
+
+TABLE.table TH {
+	font-weight: normal;
+	text-align: left;
+	vertical-align: middle;
+}
+
+TABLE.table TBODY.striped TR:nth-child(odd) {
+	background: #eee;
+}
+
+TABLE.table H3 {
+	margin: 0;
+	font-weight: bold;
+	font-size: 140%;
+}
+
+.require { color: #a00; }
+
+.uiButton {
+	padding: 0;
+	border: 0;
+	margin: 3px;
+	width: auto;
+	overflow: visible;
+	cursor: pointer;
+	background: transparent;
+}
+
+.uiButton-content {
+	height: 20px;
+	border: 1px solid #668dc6;
+	border-radius: 2px;
+	background: #96c6eb;
+	background: -moz-linear-gradient(top, #96c6eb, #5296c7);
+	background: -webkit-linear-gradient(top, #96c6eb, #5296c7);
+	color: white;
+	font-weight: bold;
+}
+
+.moz .uiButton-content { margin: 0 -2px; }
+
+.uiButton-label {
+		padding: 2px 6px;
+		white-space: nowrap;
+}
+.uiButton:hover .uiButton-content {
+	background: #2777ba;
+	background: -moz-linear-gradient(top, #6aaadf, #2777ba);
+	background: -webkit-linear-gradient(top, #6aaadf, #2777ba);
+}
+.uiButton.active .uiButton-content,
+.uiButton:active .uiButton-content {
+	background: #2575b7;
+	background: -moz-linear-gradient(top, #2576b8, #2575b7);
+	background: -webkit-linear-gradient(top, #2576b8, #2575b7);
+}
+.uiButton.disabled .uiButton-content,
+.uiButton.disabled:active .uiButton-content {
+		border-color: #c6c6c6;
+		color: #999999;
+		background: #ddd;
+		background: -moz-linear-gradient(top, #ddd, #ddd);
+		background: -webkit-linear-gradient(top, #ddd, #ddd);
+}
+
+.uiButton.disabled {
+		cursor: default;
+}
+
+.uiMenuButton {
+	display: inline-block;
+}
+
+.uiMenuButton .uiButton-label {
+	background-image: url('data:image/gif;base64,R0lGODlhDwAPAIABAP///////yH5BAEAAAEALAAAAAAPAA8AAAITjI+py+0P4wG0gmavq1HLD4ZiAQA7');
+	background-position: right 50%;
+	background-repeat: no-repeat;
+	padding-right: 17px;
+	text-align: left;
+}
+
+.uiSplitButton {
+	white-space: nowrap;
+}
+
+.uiSplitButton .uiButton:first-child {
+	margin-right: 0;
+	display: inline-block;
+}
+
+.uiSplitButton .uiButton:first-child .uiButton-content {
+	border-right-width: 1;
+	border-right-color: #5296c7;
+	border-top-right-radius: 0;
+	border-bottom-right-radius: 0;
+}
+
+.uiSplitButton .uiMenuButton {
+	margin-left: 0;
+}
+
+.uiSplitButton .uiButton:last-child .uiButton-content {
+	border-radius: 2px;
+	border-left-width: 1;
+	border-left-color: #96c6eb;
+	border-top-left-radius: 0;
+	border-bottom-left-radius: 0;
+	height: 20px;
+}
+
+.uiSplitButton .uiButton:last-child .uiButton-label {
+	padding: 2px 17px 2px 6px;
+	margin-left: -8px;
+}
+
+.uiToolbar {
+	height: 28px;
+	background: #fdfefe;
+	background: -moz-linear-gradient(top, #fdfefe, #eaedef);
+	background: -webkit-linear-gradient(top, #fdfefe, #eaedef);
+	border-bottom: 1px solid #d2d5d7;
+	padding: 3px 10px;
+}
+
+.uiToolbar H2 {
+	display: inline-block;
+	font-size: 120%;
+	margin: 0;
+	padding: 5px 20px 5px 0;
+}
+
+.uiToolbar .uiTextField {
+	display: inline-block;
+}
+
+.uiToolbar .uiTextField INPUT {
+	padding-top: 2px;
+	padding-bottom: 5px;
+}
+#uiModal {
+	background: black;
+}
+
+.uiPanel {
+	box-shadow: -1px 2.5px 4px -3px black, -1px -2.5px 4px -3px black, 3px 2.5px 4px -3px black, 3px -2.5px 4px -3px black;
+	position: absolute;
+	background: #eee;
+	border: 1px solid #666;
+}
+
+.uiPanel-titleBar {
+	text-align: center;
+	font-weight: bold;
+	padding: 2px 0;
+	background: rgba(223, 223, 223, 0.75);
+	background: -moz-linear-gradient(top, rgba(223, 223, 223, 0.75), rgba(193, 193, 193, 0.75), rgba(223, 223, 223, 0.75));
+	background: -webkit-linear-gradient(top, rgba(223, 223, 223, 0.75), rgba(193, 193, 193, 0.75), rgba(223, 223, 223, 0.75));
+	border-bottom: 1px solid #bbb;
+}
+
+.uiPanel-close {
+	cursor: pointer;
+	border: 1px solid #aaa;
+	background: #fff;
+	color: #fff;
+	float: left;
+	height: 10px;
+	left: 3px;
+	line-height: 9px;
+	padding: 1px 0;
+	position: relative;
+	text-shadow: 0 0 1px #000;
+	top: 0px;
+	width: 12px;
+}
+.uiPanel-close:hover {
+	background: #eee;
+}
+
+.uiPanel-body {
+	overflow: auto;
+}
+
+
+.uiInfoPanel {
+	background: rgba(0, 0, 0, 0.75);
+	color: white;
+	border-radius: 8px;
+	padding: 1px;
+}
+.uiInfoPanel .uiPanel-titleBar {
+	background: rgba(74, 74, 74, 0.75);
+	background: -moz-linear-gradient(top, rgba(84, 84, 84, 0.75), rgba(54, 54, 54, 0.75), rgba(64, 64, 64, 0.75));
+	background: -webkit-linear-gradient(top, rgba(84, 84, 84, 0.75), rgba(54, 54, 54, 0.75), rgba(64, 64, 64, 0.75));
+	border-radius: 8px 8px 0 0;
+	padding: 1px 0 2px 0;
+	border-bottom: 0;
+}
+.uiInfoPanel .uiPanel-close {
+	border-radius: 6px;
+	height: 13px;
+	width: 13px;
+	background: #ccc;
+	left: 3px;
+	top: 1px;
+	color: #333;
+	text-shadow: #222 0 0 1px;
+	line-height: 11px;
+	border: 0;
+	padding: 0;
+}
+.uiInfoPanel .uiPanel-close:hover {
+	background: #eee;
+}
+
+.uiInfoPanel .uiPanel-body {
+	background: transparent;
+	padding: 20px;
+	border-radius: 0 0 8px 8px;
+	border: 1px solid #222;
+}
+
+.uiMenuPanel {
+	border: 1px solid #668dc6;
+	position: absolute;
+	background: #96c6eb;
+	color: white;
+}
+
+.uiMenuPanel LI {
+	list-style: none;
+	border-bottom: 1px solid #668dc6;
+}
+
+.uiMenuPanel LI:hover {
+	background: #2575b7;
+}
+
+.uiMenuPanel LI:last-child {
+	border-bottom: 0;
+} 
+
+.uiMenuPanel-label {
+	white-space: nowrap;
+	padding: 2px 10px 2px 10px;
+	cursor: pointer;
+}
+
+.disabled .uiMenuPanel-label {
+	cursor: auto;
+	color: #888;
+}
+
+.uiSelectMenuPanel .uiMenuPanel-label {
+	margin-left: 1em;
+	padding-left: 4px;
+}
+
+.uiSelectMenuPanel .uiMenuPanel-item.selected .uiMenuPanel-label:before {
+	content: "\2713";
+	width: 12px;
+	margin-left: -12px;
+	display: inline-block;
+}
+
+.uiTable TABLE {
+	border-collapse: collapse;
+}
+
+.uiTable-body {
+	overflow-y: scroll;
+	overflow-x: auto;
+}
+
+.uiTable-headers {
+	overflow-x: hidden;
+}
+
+.uiTable-body TD {
+	white-space: nowrap;
+}
+
+.uiTable-body .uiTable-header-row TH,
+.uiTable-body .uiTable-header-row TH DIV {
+	padding-top: 0;
+	padding-bottom: 0;
+}
+
+.uiTable-body .uiTable-header-cell > DIV {
+	height: 0;
+	overflow: hidden;
+}
+
+.uiTable-headercell-menu {
+	float: right;
+}
+
+.uiTable-tools {
+	padding: 3px 4px;
+	height: 14px;
+}
+
+.uiTable-header-row {
+	background: #ddd;
+	background: -moz-linear-gradient(top, #eee, #ccc);
+	background: -webkit-linear-gradient(top, #eee, #ccc);
+}
+
+.uiTable-headercell-text {
+	margin-right: 20px;
+}
+
+.uiTable-headercell-menu {
+	display: none;
+}
+
+.uiTable-header-row TH {
+	border-right: 1px solid #bbb;
+	padding: 0;
+	text-align: left;
+}
+
+.uiTable-header-row TH > DIV {
+	padding: 3px 4px;
+	border-right: 1px solid #eee;
+}
+
+.uiTable-headerEndCap > DIV {
+	width: 19px;
+}
+
+.uiTable-header-row .uiTable-sort {
+	background: #ccc;
+	background: -moz-linear-gradient(top, #bebebe, #ccc);
+	background: -webkit-linear-gradient(top, #bebebe, #ccc);
+}
+.uiTable-header-row TH.uiTable-sort > DIV {
+	border-right: 1px solid #ccc;
+}
+
+.uiTable-sort .uiTable-headercell-menu {
+	display: block;
+}
+
+.uiTable TABLE TD {
+	border-right: 1px solid transparent;
+	padding: 3px 4px;
+}
+
+.uiTable-body TABLE TR:nth-child(even) {
+	background: #f3f3f3;
+}
+
+.uiTable-body TABLE TR.selected {
+	color: white;
+	background: #6060f1;
+}
+
+DIV.uiJsonPretty-object { font-size: 1.26em; font-family: monospace; }
+UL.uiJsonPretty-object,
+UL.uiJsonPretty-array { margin: 0; padding: 0 0 0 2em; list-style: none; }
+UL.uiJsonPretty-object LI,
+UL.uiJsonPretty-array LI { padding: 0; margin: 0; }
+.expando > SPAN.uiJsonPretty-name:before { content: "\25bc\a0"; color: #555; position: relative; top: 2px; }
+.expando.uiJsonPretty-minimised > SPAN.uiJsonPretty-name:before { content: "\25ba\a0"; top: 0; }
+.uiJsonPretty-minimised > UL SPAN.uiJsonPretty-name:before,
+.expando .uiJsonPretty-minimised > UL SPAN.uiJsonPretty-name:before { content: ""; }
+SPAN.uiJsonPretty-string,
+SPAN.uiJsonPretty-string A { color: green; }
+SPAN.uiJsonPretty-string A { text-decoration: underline;}
+SPAN.uiJsonPretty-number { color: blue; }
+SPAN.uiJsonPretty-null { color: red; }
+SPAN.uiJsonPretty-boolean { color: purple; }
+.expando > .uiJsonPretty-name { cursor: pointer; }
+.expando > .uiJsonPretty-name:hover { text-decoration: underline; }
+.uiJsonPretty-minimised { white-space: nowrap; overflow: hidden; }
+.uiJsonPretty-minimised > UL { opacity: 0.6; }
+.uiJsonPretty-minimised .uiJsonPretty-minimised > UL { opacity: 1; }
+.uiJsonPretty-minimised UL, .uiJsonPretty-minimised LI { display: inline; padding: 0; }
+
+
+.uiJsonPanel SPAN.uiJsonPretty-string { color: #6F6; }
+.uiJsonPanel SPAN.uiJsonPretty-number { color: #66F; }
+.uiJsonPanel SPAN.uiJsonPretty-null { color: #F66; }
+.uiJsonPanel SPAN.uiJsonPretty-boolean { color: #F6F; }
+
+.uiPanelForm-field {
+	display: block;
+	padding: 2px 0;
+	clear: both;
+}
+
+.uiPanelForm-label {
+	float: left;
+	width: 200px;
+	padding: 3px 7px;
+	text-align: right;
+}
+
+.uiSidebarSection-head {
+	background-color: #b9cfff;
+	background-image: url('data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAcCAMAAABifa5OAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAMAUExURQUCFf///wICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycr
 KysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///2Oyy/cAAAACdFJOU/8A5bcwSgAAADxJREFUeNq8zzkOACAMA8Hd/3+agiuRcIsrRopIjArOoLK1QAMNNBCRPkhLyzkn35Bjfd7JR1Nr09NoDACnvgDl1zlzoQAAAABJRU5ErkJggg==');
+	background-repeat: no-repeat;
+	background-position: 2px 5px;
+	margin-bottom: 1px;
+	padding: 3px 3px 3px 17px;
+	cursor: pointer;
+}
+
+.shown > .uiSidebarSection-head {
+	background-position: 2px -13px;
+}
+
+.uiSidebarSection-body {
+	margin-bottom: 3px;
+	display: none;
+}
+
+.uiSidebarSection-help {
+	text-shadow: #228 1px 1px 2px;
+	color: blue;
+	cursor: pointer;
+}
+
+.uiSidebarSection-help:hover {
+	text-decoration: underline;
+}
+
+.uiQueryFilter {
+	width: 350px;
+	padding: 5px;
+	background: #d8e7ff;
+	background: -moz-linear-gradient(left, #d8e7ff, #e8f1ff);
+	background: -webkit-linear-gradient(left, #d8e7ff, #e8f1ff);
+}
+
+.uiQueryFilter DIV.uiQueryFilter-section {
+	margin-bottom: 5px;
+}
+
+.uiQueryFilter HEADER {
+	display: block;
+	font-variant: small-caps;
+	font-weight: bold;
+	margin: 5px 0;
+}
+
+.uiQueryFilter-aliases SELECT {
+	width: 100%;
+}
+
+.uiQueryFilter-booble {
+	cursor: pointer;
+	background: #e8f1ff;
+	border: 1px solid #e8f1ff;
+	border-radius: 5px;
+	padding: 1px 4px;
+	margin-bottom: 1px;
+	overflow: hidden;
+	white-space: nowrap;
+}
+
+.uiQueryFilter-booble.selected {
+	background: #dae3f0;
+	border-top: 1px solid #c8d4e6;
+	border-left: 1px solid #c8d4e6;
+	border-bottom: 1px solid #ffffff;
+	border-right: 1px solid #ffffff;
+}
+
+.uiQueryFilter-filterName {
+	background-color: #cbdfff;
+	margin-bottom: 4px;
+	padding: 3px;
+	cursor: pointer;
+}
+
+.uiQueryFilter-filters INPUT  {
+	width: 300px;
+}
+
+.uiQueryFilter-subMultiFields {
+	padding-left: 10px;
+}
+
+.uiQueryFilter-rangeHintFrom,
+.uiQueryFilter-rangeHintTo {
+	margin: 0;
+	opacity: 0.75;
+}
+.uiBrowser-filter {
+	float: left;
+}
+
+.uiBrowser-table {
+	margin-left: 365px;
+}
+
+.uiAnyRequest-request {
+	float: left;
+	width: 350px;
+	padding: 5px;
+	background: #d8e7ff;
+	background: -moz-linear-gradient(left, #d8e7ff, #e8f1ff);
+	background: -webkit-linear-gradient(left, #d8e7ff, #e8f1ff);
+}
+
+.uiAnyRequest-request INPUT[type=text],
+.uiAnyRequest-request TEXTAREA {
+	width: 340px;
+}
+
+.anyRequest INPUT[name=path] {
+	width: 259px;
+}
+
+.uiAnyRequest-out {
+	margin-left: 365px;
+}
+
+.uiAnyRequest-out P {
+	margin-top: 0;
+}
+
+.uiAnyRequest-jsonErr {
+	color: red;
+}
+
+.uiAnyRequest-history {
+	margin: 0;
+	padding: 0;
+	list-style: none;
+	max-height: 100px;
+	overflow-x: hidden;
+	overflow-y: auto;
+}
+
+.uiNodesView TH,
+.uiNodesView TD {
+	vertical-align: top;
+	padding: 2px 20px;
+}
+
+.uiNodesView TH.close,
+.uiNodesView TD.close {
+	color: #888;
+	background: #f2f2f2;
+}
+
+.uiNodesView .uiMenuButton .uiButton-content {
+	padding-right: 3px;
+	border-radius: 8px;
+	height: 14px;
+}
+
+.uiNodesView .uiMenuButton.active .uiButton-content,
+.uiNodesView .uiMenuButton:active .uiButton-content {
+	border-bottom-right-radius: 0px;
+	border-bottom-left-radius: 0px;
+}
+
+.uiNodesView .uiMenuButton .uiButton-label {
+	padding: 0px 17px 0px 7px;
+}
+
+.uiNodesView-hasAlias {
+	text-align: center;
+}
+.uiNodesView-hasAlias.max {
+	border-top-right-radius: 8px;
+	border-bottom-right-radius: 8px;
+}
+.uiNodesView-hasAlias.min {
+	border-top-left-radius: 8px;
+	border-bottom-left-radius: 8px;
+}
+.uiNodesView-hasAlias-remove {
+	float: right;
+	font-weight: bold;
+	cursor: pointer;
+}
+
+.uiNodesView TD.uiNodesView-icon {
+	padding: 20px 0px 15px 20px;
+}
+
+.uiNodesView-node:nth-child(odd) {
+	background: #eee;
+}
+
+.uiNodesView-routing {
+	position: relative;
+	min-width: 90px;
+}
+
+.uiNodesView-nullReplica,
+.uiNodesView-replica {
+	box-sizing: border-box;
+	cursor: pointer;
+	float: left;
+	height: 40px;
+	width: 35px;
+	margin: 4px;
+	border: 2px solid #444;
+	padding: 2px;
+	font-size: 32px;
+	line-height: 32px;
+	text-align: center;
+	letter-spacing: -5px;
+	text-indent: -7px;
+}
+
+.uiNodesView-replica.primary {
+	border-width: 4px;
+	line-height: 29px;
+}
+
+.uiNodesView-nullReplica {
+	border-color: transparent;
+}
+
+.uiNodesView-replica.state-UNASSIGNED { background: #eeeeee; color: #999; border-color: #666; float: none; display: inline-block; }
+.uiNodesView-replica.state-INITIALIZING { background: #dddc88; }
+.uiNodesView-replica.state-STARTED { background: #99dd88; }
+.uiNodesView-replica.state-RELOCATING { background: #dc88dd; }
+
+
+.uiClusterConnect-uri {
+	width: 280px;
+}
+
+.uiStructuredQuery {
+	padding: 10px;
+}
+
+.uiStructuredQuery-out {
+	min-height: 30px;
+}
+
+.uiFilterBrowser-row * {
+	margin-right: 0.4em;
+}
+
+.uiFilterBrowser-row BUTTON {
+	height: 22px;
+	position: relative;
+	top: 1px;
+}
+
+.uiHeader {
+	padding: 3px 10px;
+}
+
+.uiHeader-name, .uiHeader-status {
+	font-size: 1.2em;
+	font-weight: bold;
+	padding: 0 10px;
+}
+
+
+.uiApp-header {
+	background: #eee;
+	position: fixed;
+	width: 100%;
+	z-index: 9;
+}
+
+.uiApp-header H1 {
+	margin: -2px 0 -4px 0;
+	float: left;
+	padding-right: 25px;
+}
+
+.uiApp-headerMenu {
+	border-bottom: 1px solid #bbb;
+	padding: 0px 3px;
+	height: 22px;
+}
+
+.uiApp-headerMenu .active {
+	background: white;
+	border-bottom-color: white;
+}
+
+.uiApp-headerMenuItem {
+	border: 1px solid #bbb;
+	padding: 4px 8px 1px ;
+	margin: 2px 1px 0;
+	height: 14px;
+	cursor: pointer;
+}
+
+.uiApp-body {
+	padding: 51px 0px 0px 0px;
+}
+
+.uiApp-headerNewMenuItem {
+	color: blue;
+}


[5/7] karaf-decanter git commit: [KARAF-3904] Add elasticsearch-head feature

Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/base/loading.gif
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/base/loading.gif b/elasticsearch-head/src/main/resources/base/loading.gif
new file mode 100644
index 0000000..f001e23
Binary files /dev/null and b/elasticsearch-head/src/main/resources/base/loading.gif differ

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/base/reset.css
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/base/reset.css b/elasticsearch-head/src/main/resources/base/reset.css
new file mode 100644
index 0000000..29a5f1b
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/base/reset.css
@@ -0,0 +1,44 @@
+BODY {
+	font-family: Verdana, sans-serif;
+	font-size: 73%;
+	padding: 0;
+	margin: 0;
+}
+
+INPUT, SELECT, TEXTAREA {
+	border: 1px solid #cecece;
+	padding: 1px 3px;
+	background: white;
+}
+
+SELECT {
+	padding: 0;
+}
+
+.saf SELECT {
+	margin-top: 0;
+	margin-bottom: 0;
+}
+
+TEXTAREA, CODE {
+	font-family: monospace;
+	font-size: 13px;
+}
+
+BUTTON::-moz-focus-inner {
+	border: none;
+}
+
+.pull-left {
+	float: left;
+}
+
+.pull-right {
+	float: right;
+}
+
+.loading  {
+	background-image: url(loading.gif);
+	background-repeat: no-repeat;
+	text-indent: 20px;
+}

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/fonts/FontAwesome.otf
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/fonts/FontAwesome.otf b/elasticsearch-head/src/main/resources/fonts/FontAwesome.otf
new file mode 100644
index 0000000..8b0f54e
Binary files /dev/null and b/elasticsearch-head/src/main/resources/fonts/FontAwesome.otf differ

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.eot
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.eot b/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.eot
new file mode 100644
index 0000000..7c79c6a
Binary files /dev/null and b/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.eot differ


[4/7] karaf-decanter git commit: [KARAF-3904] Add elasticsearch-head feature

Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.svg
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.svg b/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.svg
new file mode 100644
index 0000000..45fdf33
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.svg
@@ -0,0 +1,414 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="fontawesomeregular" horiz-adv-x="1536" >
+<font-face units-per-em="1792" ascent="1536" descent="-256" />
+<missing-glyph horiz-adv-x="448" />
+<glyph unicode=" "  horiz-adv-x="448" />
+<glyph unicode="&#x09;" horiz-adv-x="448" />
+<glyph unicode="&#xa0;" horiz-adv-x="448" />
+<glyph unicode="&#xa8;" horiz-adv-x="1792" />
+<glyph unicode="&#xa9;" horiz-adv-x="1792" />
+<glyph unicode="&#xae;" horiz-adv-x="1792" />
+<glyph unicode="&#xb4;" horiz-adv-x="1792" />
+<glyph unicode="&#xc6;" horiz-adv-x="1792" />
+<glyph unicode="&#x2000;" horiz-adv-x="768" />
+<glyph unicode="&#x2001;" />
+<glyph unicode="&#x2002;" horiz-adv-x="768" />
+<glyph unicode="&#x2003;" />
+<glyph unicode="&#x2004;" horiz-adv-x="512" />
+<glyph unicode="&#x2005;" horiz-adv-x="384" />
+<glyph unicode="&#x2006;" horiz-adv-x="256" />
+<glyph unicode="&#x2007;" horiz-adv-x="256" />
+<glyph unicode="&#x2008;" horiz-adv-x="192" />
+<glyph unicode="&#x2009;" horiz-adv-x="307" />
+<glyph unicode="&#x200a;" horiz-adv-x="85" />
+<glyph unicode="&#x202f;" horiz-adv-x="307" />
+<glyph unicode="&#x205f;" horiz-adv-x="384" />
+<glyph unicode="&#x2122;" horiz-adv-x="1792" />
+<glyph unicode="&#x221e;" horiz-adv-x="1792" />
+<glyph unicode="&#x2260;" horiz-adv-x="1792" />
+<glyph unicode="&#xe000;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
+<glyph unicode="&#xf001;" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
+<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" />
+<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" />
+<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
+<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
+<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t1
 9 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28
 t28 -68z" />
+<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
+<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
+<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
+<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " />
+<glyph unicode="&#xf011;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
+<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf013;" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
+<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
+<glyph unicode="&#xf016;" horiz-adv-x="1280" d="M128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280zM768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z " />
+<glyph unicode="&#xf017;" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
+<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
+<glyph unicode="&#xf01a;" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01b;" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01c;" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" />
+<glyph unicode="&#xf01d;" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01e;" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
+<glyph unicode="&#xf021;" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
+<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -1
 13 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" />
+<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
+<glyph unicode="&#xf026;" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
+<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
+<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
+<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
+<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
+<glyph unicode="&#xf02b;" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" />
+<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
+<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
+<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
+<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
+<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M725 977l-170 -450q73 -1 153.5 -2t119 -1.5t52.5 -0.5l29 2q-32 95 -92 241q-53 132 -92 211zM21 -128h-21l2 79q22 7 80 18q89 16 110 31q20 16 48 68l237 616l280 724h75h53l11 -21l205 -480q103 -242 124 -297q39 -102 96 -235q26 -58 65 -164q24 -67 65 -149 q22 -49 35 -57q22 -19 69 -23q47 -6 103 -27q6 -39 6 -57q0 -14 -1 -26q-80 0 -192 8q-93 8 -189 8q-79 0 -135 -2l-200 -11l-58 -2q0 45 4 78l131 28q56 13 68 23q12 12 12 27t-6 32l-47 114l-92 228l-450 2q-29 -65 -104 -274q-23 -64 -23 -84q0 -31 17 -43 q26 -21 103 -32q3 0 13.5 -2t30 -5t40.5 -6q1 -28 1 -58q0 -17 -2 -27q-66 0 -349 20l-48 -8q-81 -14 -167 -14z" />
+<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M555 15q76 -32 140 -32q131 0 216 41t122 113q38 70 38 181q0 114 -41 180q-58 94 -141 126q-80 32 -247 32q-74 0 -101 -10v-144l-1 -173l3 -270q0 -15 12 -44zM541 761q43 -7 109 -7q175 0 264 65t89 224q0 112 -85 187q-84 75 -255 75q-52 0 -130 -13q0 -44 2 -77 q7 -122 6 -279l-1 -98q0 -43 1 -77zM0 -128l2 94q45 9 68 12q77 12 123 31q17 27 21 51q9 66 9 194l-2 497q-5 256 -9 404q-1 87 -11 109q-1 4 -12 12q-18 12 -69 15q-30 2 -114 13l-4 83l260 6l380 13l45 1q5 0 14 0.5t14 0.5q1 0 21.5 -0.5t40.5 -0.5h74q88 0 191 -27 q43 -13 96 -39q57 -29 102 -76q44 -47 65 -104t21 -122q0 -70 -32 -128t-95 -105q-26 -20 -150 -77q177 -41 267 -146q92 -106 92 -236q0 -76 -29 -161q-21 -62 -71 -117q-66 -72 -140 -108q-73 -36 -203 -60q-82 -15 -198 -11l-197 4q-84 2 -298 -11q-33 -3 -272 -11z" />
+<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q4 1 77 20q76 19 116 39q29 37 41 101l27 139l56 268l12 64q8 44 17 84.5t16 67t12.5 46.5t9 30.5t3.5 11.5l29 157l16 63l22 135l8 50v38q-41 22 -144 28q-28 2 -38 4l19 103l317 -14q39 -2 73 -2q66 0 214 9q33 2 68 4.5t36 2.5q-2 -19 -6 -38 q-7 -29 -13 -51q-55 -19 -109 -31q-64 -16 -101 -31q-12 -31 -24 -88q-9 -44 -13 -82q-44 -199 -66 -306l-61 -311l-38 -158l-43 -235l-12 -45q-2 -7 1 -27q64 -15 119 -21q36 -5 66 -10q-1 -29 -7 -58q-7 -31 -9 -41q-18 0 -23 -1q-24 -2 -42 -2q-9 0 -28 3q-19 4 -145 17 l-198 2q-41 1 -174 -11q-74 -7 -98 -9z" />
+<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l215 -1h293l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -42.5 2t-103.5 -1t-111 -1 q-34 0 -67 -5q-10 -97 -8 -136l1 -152v-332l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-88 0 -233 -14q-48 -4 -70 -4q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q8 192 6 433l-5 428q-1 62 -0.5 118.5t0.5 102.5t-2 57t-6 15q-6 5 -14 6q-38 6 -148 6q-43 0 -100 -13.5t-73 -24.5q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1744 128q33 0 42 -18.5t-11 -44.5 l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80z" />
+<glyph unicode="&#xf035;" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l446 -1h318l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -58.5 2t-138.5 -1t-128 -1 q-94 0 -127 -5q-10 -97 -8 -136l1 -152v52l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-82 0 -233 -13q-45 -5 -70 -5q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q6 137 6 433l-5 44q0 265 -2 278q-2 11 -6 15q-6 5 -14 6q-38 6 -148 6q-50 0 -168.5 -14t-132.5 -24q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1505 113q26 -20 26 -49t-26 -49l-162 -126 q-26 -20 -44.5 -11t-18.5 42v80h-1024v-80q0 -33 -18.5 -42t-44.5 11l-162 126q-26 20 -26 49t26 49l162 126q26 20 44.5 11t18.5 -42v-80h1024v80q0 33 18.5 42t44.5 -11z" />
+<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t
 -22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" />
+<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf040;" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" />
+<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
+<glyph unicode="&#xf042;" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
+<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
+<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
+<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" />
+<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" />
+<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" />
+<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" />
+<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
+<glyph unicode="&#xf04c;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf04d;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
+<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
+<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" />
+<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
+<glyph unicode="&#xf053;" horiz-adv-x="1152" d="M742 -37l-652 651q-37 37 -37 90.5t37 90.5l652 651q37 37 90.5 37t90.5 -37l75 -75q37 -37 37 -90.5t-37 -90.5l-486 -486l486 -485q37 -38 37 -91t-37 -90l-75 -75q-37 -37 -90.5 -37t-90.5 37z" />
+<glyph unicode="&#xf054;" horiz-adv-x="1152" d="M1099 704q0 -52 -37 -91l-652 -651q-37 -37 -90 -37t-90 37l-76 75q-37 39 -37 91q0 53 37 90l486 486l-486 485q-37 39 -37 91q0 53 37 90l76 75q36 38 90 38t90 -38l652 -651q37 -37 37 -90z" />
+<glyph unicode="&#xf055;" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf056;" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" />
+<glyph unicode="&#xf057;" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf058;" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf059;" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05a;" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05b;" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf05c;" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05d;" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05e;" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
+<glyph unicode="&#xf060;" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" />
+<glyph unicode="&#xf061;" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
+<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" />
+<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
+<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
+<glyph unicode="&#xf065;" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf066;" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
+<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
+<glyph unicode="&#xf06a;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
+<glyph unicode="&#xf06b;" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
+<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
+<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
+<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " />
+<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
+<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
+<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
+<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
+<glyph unicode="&#xf076;" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf077;" horiz-adv-x="1664" d="M1611 320q0 -53 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-486 485l-486 -485q-36 -38 -90 -38t-90 38l-75 75q-38 36 -38 90q0 53 38 91l651 651q37 37 90 37q52 0 91 -37l650 -651q38 -38 38 -91z" />
+<glyph unicode="&#xf078;" horiz-adv-x="1664" d="M1611 832q0 -53 -37 -90l-651 -651q-38 -38 -91 -38q-54 0 -90 38l-651 651q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l486 -486l486 486q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
+<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
+<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
+<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
+<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf080;" horiz-adv-x="1920" d="M512 512v-384h-256v384h256zM896 1024v-896h-256v896h256zM1280 768v-640h-256v640h256zM1664 1152v-1024h-256v1024h256zM1792 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5z M1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf082;" d="M1307 618l23 219h-198v109q0 49 15.5 68.5t71.5 19.5h110v219h-175q-152 0 -218 -72t-66 -213v-131h-131v-219h131v-635h262v635h175zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
+<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
+<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 
 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
+<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
+<glyph unicode="&#xf087;" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
+<glyph unicode="&#xf088;" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" />
+<glyph unicode="&#xf089;" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
+<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" />
+<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
+<glyph unicode="&#xf08c;" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
+<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf090;" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf092;" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 
 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
+<glyph unicode="&#xf094;" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" />
+<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
+<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
+<glyph unicode="&#xf098;" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
+<glyph unicode="&#xf09a;" horiz-adv-x="768" d="M511 980h257l-30 -284h-227v-824h-341v824h-170v284h170v171q0 182 86 275.5t283 93.5h227v-284h-142q-39 0 -62.5 -6.5t-34 -23.5t-13.5 -34.5t-3 -49.5v-142z" />
+<glyph unicode="&#xf09b;" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" />
+<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
+<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" />
+<glyph unicode="&#xf0a0;" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
+<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
+<glyph unicode="&#xf0a2;" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM1664 128q0 -52 -38 -90t-90 -38 h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" />
+<glyph unicode="&#xf0a3;" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
+<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
+<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
+<glyph unicode="&#xf0a6;" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
+<glyph unicode="&#xf0a7;" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
+<glyph unicode="&#xf0a8;" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0a9;" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0aa;" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0ab;" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0ac;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17
 t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-1
 5 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q
 -15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 

<TRUNCATED>

[6/7] karaf-decanter git commit: [KARAF-3904] Add elasticsearch-head feature

Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/app.js
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/app.js b/elasticsearch-head/src/main/resources/app.js
new file mode 100644
index 0000000..008f0b0
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/app.js
@@ -0,0 +1,4373 @@
+(function() {
+
+	var window = this,
+		$ = jQuery;
+
+	function ns( namespace ) {
+		return (namespace || "").split(".").reduce( function( space, name ) {
+			return space[ name ] || ( space[ name ] = { ns: ns } );
+		}, this );
+	}
+
+	var app = ns("app");
+
+	var acx = ns("acx");
+
+	/**
+	 * object iterator, returns an array with one element for each property of the object
+	 * @function
+	 */
+	acx.eachMap = function(obj, fn, thisp) {
+		var ret = [];
+		for(var n in obj) {
+			ret.push(fn.call(thisp, n, obj[n], obj));
+		}
+		return ret;
+	};
+
+	/**
+	 * augments the first argument with the properties of the second and subsequent arguments
+	 * like {@link $.extend} except that existing properties are not overwritten
+	 */
+	acx.augment = function() {
+		var args = Array.prototype.slice.call(arguments),
+			src = (args.length === 1) ? this : args.shift(),
+			augf = function(n, v) {
+				if(! (n in src)) {
+					src[n] = v;
+				}
+			};
+		for(var i = 0; i < args.length; i++) {
+			$.each(args[i], augf);
+		}
+		return src;
+	};
+
+	/**
+	 * tests whether the argument is an array
+	 * @function
+	 */
+	acx.isArray = $.isArray;
+
+	/**
+	 * tests whether the argument is an object
+	 * @function
+	 */
+	acx.isObject = function (value) {
+		return Object.prototype.toString.call(value) == "[object Object]";
+	};
+
+	/**
+	 * tests whether the argument is a function
+	 * @function
+	 */
+	acx.isFunction = $.isFunction;
+
+	/**
+	 * tests whether the argument is a date
+	 * @function
+	 */
+	acx.isDate = function (value) {
+		return Object.prototype.toString.call(value) == "[object Date]";
+	};
+
+	/**
+	 * tests whether the argument is a regexp
+	 * @function
+	 */
+	acx.isRegExp = function (value) {
+		return Object.prototype.toString.call(value) == "[object RegExp]";
+	};
+
+	/**
+	 * tests whether the value is blank or empty
+	 * @function
+	 */
+	acx.isEmpty = function (value, allowBlank) {
+		return value === null || value === undefined || ((acx.isArray(value) && !value.length)) || (!allowBlank ? value === '' : false);
+	};
+
+	/**
+	 * data type for performing chainable geometry calculations<br>
+	 * can be initialised x,y | {x, y} | {left, top}
+	 */
+	acx.vector = function(x, y) {
+		return new acx.vector.prototype.Init(x, y);
+	};
+
+	acx.vector.prototype = {
+		Init : function(x, y) {
+			x = x || 0;
+			this.y = isFinite(x.y) ? x.y : (isFinite(x.top) ? x.top : (isFinite(y) ? y : 0));
+			this.x = isFinite(x.x) ? x.x : (isFinite(x.left) ? x.left : (isFinite(x) ? x : 0));
+		},
+		
+		add : function(i, j) {
+			var d = acx.vector(i, j);
+			return new this.Init(this.x + d.x, this.y + d.y);
+		},
+		
+		sub : function(i, j) {
+			var d = acx.vector(i, j);
+			return new this.Init(this.x - d.x, this.y - d.y);
+		},
+		
+		addX : function(i) {
+			return new this.Init(this.x + i, this.y);
+		},
+		
+		addY : function(j) {
+			return new this.Init(this.x, this.y + j);
+		},
+
+		mod : function(fn) { // runs a function against the x and y values
+			return new this.Init({x: fn.call(this, this.x, "x"), y: fn.call(this, this.y, "y")});
+		},
+		
+		/** returns true if this is within a rectangle formed by the points p and q */
+		within : function(p, q) {
+			return ( this.x >= ((p.x < q.x) ? p.x : q.x) && this.x <= ((p.x > q.x) ? p.x : q.x) &&
+					this.y >= ((p.y < q.y) ? p.y : q.y) && this.y <= ((p.y > q.y) ? p.y : q.y) );
+		},
+		
+		asOffset : function() {
+			return { top: this.y, left: this.x };
+		},
+		
+		asSize : function() {
+			return { height: this.y, width: this.x };
+		}
+	};
+
+	acx.vector.prototype.Init.prototype = acx.vector.prototype;
+
+	/**
+	 * short cut functions for working with vectors and jquery.
+	 * Each function returns the equivalent jquery value in a two dimentional vector
+	 */
+	$.fn.vSize = function() { return acx.vector(this.width(), this.height()); };
+	$.fn.vOuterSize = function(margin) { return acx.vector(this.outerWidth(margin), this.outerHeight(margin)); };
+	$.fn.vScroll = function() { return acx.vector(this.scrollLeft(), this.scrollTop()); };
+	$.fn.vOffset = function() { return acx.vector(this.offset()); };
+	$.fn.vPosition = function() { return acx.vector(this.position()); };
+	$.Event.prototype.vMouse = function() { return acx.vector(this.pageX, this.pageY); };
+
+	/**
+	 * object extensions (ecma5 compatible)
+	 */
+	acx.augment(Object, {
+		keys: function(obj) {
+			var ret = [];
+			for(var n in obj) if(Object.prototype.hasOwnProperty.call(obj, n)) ret.push(n);
+			return ret;
+		}
+	});
+
+	/**
+	 * Array prototype extensions
+	 */
+	acx.augment(Array.prototype, {
+		'contains' : function(needle) {
+			return this.indexOf(needle) !== -1;
+		},
+
+		// returns a new array consisting of all the members that are in both arrays
+		'intersection' : function(b) {
+			var ret = [];
+			for(var i = 0; i < this.length; i++) {
+				if(b.contains(this[i])) {
+					ret.push(this[i]);
+				}
+			}
+			return ret;
+		},
+		
+		'remove' : function(value) {
+			var i = this.indexOf(value);
+			if(i !== -1) {
+				this.splice(i, 1);
+			}
+		}
+	});
+
+	/**
+	 * String prototype extensions
+	 */
+	acx.augment(String.prototype, {
+		'contains' : function(needle) {
+			return this.indexOf(needle) !== -1;
+		},
+
+		'equalsIgnoreCase' : function(match) {
+			return this.toLowerCase() === match.toLowerCase();
+		},
+
+		'escapeHtml' : function() {
+			return this.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+		},
+
+		'escapeJS' : function() {
+			var meta = {'"':'\\"', '\\':'\\\\', '/':'\\/', '\b':'\\b', '\f':'\\f', '\n':'\\n', '\r':'\\r', '\t':'\\t'},
+				xfrm = function(c) { return meta[c] || "\\u" + c.charCodeAt(0).toString(16).zeroPad(4); };
+			return this.replace(new RegExp('(["\\\\\x00-\x1f\x7f-\uffff])', 'g'), xfrm);
+		},
+
+		'escapeRegExp' : function() {
+			var ret = "", esc = "\\^$*+?.()=|{,}[]-";
+			for ( var i = 0; i < this.length; i++) {
+				ret += (esc.contains(this.charAt(i)) ? "\\" : "") + this.charAt(i);
+			}
+			return ret;
+		},
+		
+		'zeroPad' : function(len) {
+			return ("0000000000" + this).substring(this.length - len + 10);
+		}
+	});
+
+	$.fn.forEach = Array.prototype.forEach;
+
+	// joey / jquery integration
+	$.joey = function( obj ) {
+		return $( window.joey( obj ) );
+	};
+
+	window.joey.plugins.push( function( obj ) {
+		if( obj instanceof jQuery ) {
+			return obj[0];
+		}
+	});
+
+})();
+
+/**
+ * base class for creating inheritable classes
+ * based on resigs 'Simple Javascript Inheritance Class' (based on base2 and prototypejs)
+ * modified with static super and auto config
+ * @name Class
+ * @constructor
+ */
+(function( $, app ){
+
+	var ux = app.ns("ux");
+
+	var initializing = false, fnTest = /\b_super\b/;
+
+	ux.Class = function(){};
+
+	ux.Class.extend = function(prop) {
+		function Class() {
+			if(!initializing) {
+				var args = Array.prototype.slice.call(arguments);
+				this.config = $.extend( function(t) { // automatically construct a config object based on defaults and last item passed into the constructor
+					return $.extend(t._proto && t._proto() && arguments.callee(t._proto()) || {}, t.defaults);
+				} (this) , args.pop() );
+				this.init && this.init.apply(this, args); // automatically run the init function when class created
+			}
+		}
+
+		initializing = true;
+		var prototype = new this();
+		initializing = false;
+		
+		var _super = this.prototype;
+		prototype._proto = function() {
+			return _super;
+		};
+
+		for(var name in prop) {
+			prototype[name] = typeof prop[name] === "function" && typeof _super[name] === "function" && fnTest.test(prop[name]) ?
+				(function(name, fn){
+					return function() { this._super = _super[name]; return fn.apply(this, arguments); };
+				})(name, prop[name]) : prop[name];
+		}
+
+		Class.prototype = prototype;
+		Class.constructor = Class;
+
+		Class.extend = arguments.callee; // make class extendable
+
+		return Class;
+	};
+})( this.jQuery, this.app );
+
+(function( app ) {
+
+	var ut = app.ns("ut");
+
+	ut.option_template = function(v) { return { tag: "OPTION", value: v, text: v }; };
+
+	ut.require_template = function(f) { return f.require ? { tag: "SPAN", cls: "require", text: "*" } : null; };
+
+
+	var sib_prefix = ['B','ki','Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'];
+
+	ut.byteSize_template = function(n) {
+		var i = 0;
+		while( n >= 1000 ) {
+			i++;
+			n /= 1024;
+		}
+		return (i === 0 ? n.toString() : n.toFixed( 3 - parseInt(n,10).toString().length )) + ( sib_prefix[ i ] || "..E" );
+	};
+
+	var sid_prefix = ['','k','M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
+
+	ut.count_template = function(n) {
+		var i = 0;
+		while( n >= 1000 ) {
+			i++;
+			n /= 1000;
+		}
+		return i === 0 ? n.toString() : ( n.toFixed( 3 - parseInt(n,10).toString().length ) + ( sid_prefix[ i ] || "..E" ) );
+	};
+
+})( this.app );
+
+(function( app ) {
+
+	var ux = app.ns("ux");
+
+	ux.Observable = ux.Class.extend((function() {
+		return {
+			init: function() {
+				this.observers = {};
+				for( var opt in this.config ) { // automatically install observers that are defined in the configuration
+					if( opt.indexOf( 'on' ) === 0 ) {
+						this.on( opt.substring(2) , this.config[ opt ] );
+					}
+				}
+			},
+			_getObs: function( type ) {
+				return ( this.observers[ type.toLowerCase() ] || ( this.observers[ type.toLowerCase() ] = [] ) );
+			},
+			on: function( type, fn, params, thisp ) {
+				this._getObs( type ).push( { "cb" : fn, "args" : params || [] , "cx" : thisp || this } );
+				return this;
+			},
+			fire: function( type ) {
+				var params = Array.prototype.slice.call( arguments, 1 );
+				this._getObs( type ).slice().forEach( function( ob ) {
+					ob["cb"].apply( ob["cx"], ob["args"].concat( params ) );
+				} );
+				return this;
+			},
+			removeAllObservers: function() {
+				this.observers = {};
+			},
+			removeObserver: function( type, fn ) {
+				var obs = this._getObs( type ),
+					index = obs.reduce( function(p, t, i) { return (t.cb === fn) ? i : p; }, -1 );
+				if(index !== -1) {
+					obs.splice( index, 1 );
+				}
+				return this; // make observable functions chainable
+			},
+			hasObserver: function( type ) {
+				return !! this._getObs( type ).length;
+			}
+		};
+	})());
+
+})( this.app );
+(function( app ) {
+
+	var ux = app.ns("ux");
+
+	var extend = ux.Observable.extend;
+	var instance = function() {
+		if( ! ("me" in this) ) {
+			this.me = new this();
+		}
+		return this.me;
+	};
+
+	ux.Singleton = ux.Observable.extend({});
+
+	ux.Singleton.extend = function() {
+		var Self = extend.apply( this, arguments );
+		Self.instance = instance;
+		return Self;
+	};
+
+})( this.app );
+
+(function( $, app ) {
+
+	var ux = app.ns("ux");
+
+	/**
+	 * Provides drag and drop functionality<br>
+	 * a DragDrop instance is created for each usage pattern and then used over and over again<br>
+	 * first a dragObj is defined - this is the jquery node that will be dragged around<br>
+	 * second, the event callbacks are defined - these allow you control the ui during dragging and run functions when successfully dropping<br>
+	 * thirdly drop targets are defined - this is a list of DOM nodes, the constructor works in one of two modes:
+	 * <li>without targets - objects can be picked up and dragged around, dragStart and dragStop events fire</li>
+	 * <li>with targets - as objects are dragged over targets dragOver, dragOut and DragDrop events fire
+	 * to start dragging call the DragDrop.pickup_handler() function, dragging stops when the mouse is released.
+	 * @constructor
+	 * The following options are supported
+	 * <dt>targetSelector</dt>
+	 *   <dd>an argument passed directly to jquery to create a list of targets, as such it can be a CSS style selector, or an array of DOM nodes<br>if target selector is null the DragDrop does Drag only and will not fire dragOver dragOut and dragDrop events</dd>
+	 * <dt>pickupSelector</dt>
+	 *   <dd>a jquery selector. The pickup_handler is automatically bound to matched elements (eg clicking on these elements starts the drag). if pickupSelector is null, the pickup_handler must be manually bound <code>$(el).bind("mousedown", dragdrop.pickup_handler)</code></dd>
+	 * <dt>dragObj</dt>
+	 *   <dd>the jQuery element to drag around when pickup is called. If not defined, dragObj must be set in onDragStart</dd>
+	 * <dt>draggingClass</dt>
+	 *   <dd>the class(es) added to items when they are being dragged</dd>
+	 * The following observables are supported
+	 * <dt>dragStart</dt>
+	 *   <dd>a callback when start to drag<br><code>function(jEv)</code></dd>
+	 * <dt>dragOver</dt>
+	 *   <dd>a callback when we drag into a target<br><code>function(jEl)</code></dd>
+	 * <dt>dragOut</dt>
+	 *   <dd>a callback when we drag out of a target, or when we drop over a target<br><code>function(jEl)</code></dd>
+	 * <dt>dragDrop</dt>
+	 *   <dd>a callback when we drop on a target<br><code>function(jEl)</code></dd>
+	 * <dt>dragStop</dt>
+	 *   <dd>a callback when we stop dragging<br><code>function(jEv)</code></dd>
+	 */
+	ux.DragDrop = ux.Observable.extend({
+		defaults : {
+			targetsSelector : null,
+			pickupSelector:   null,
+			dragObj :         null,
+			draggingClass :   "dragging"
+		},
+
+		init: function(options) {
+			this._super(); // call the class initialiser
+		
+			this.drag_handler = this.drag.bind(this);
+			this.drop_handler = this.drop.bind(this);
+			this.pickup_handler = this.pickup.bind(this);
+			this.targets = [];
+			this.dragObj = null;
+			this.dragObjOffset = null;
+			this.currentTarget = null;
+			if(this.config.pickupSelector) {
+				$(this.config.pickupSelector).bind("mousedown", this.pickup_handler);
+			}
+		},
+
+		drag : function(jEv) {
+			jEv.preventDefault();
+			var mloc = acx.vector( this.lockX || jEv.pageX, this.lockY || jEv.pageY );
+			this.dragObj.css(mloc.add(this.dragObjOffset).asOffset());
+			if(this.targets.length === 0) {
+				return;
+			}
+			if(this.currentTarget !== null && mloc.within(this.currentTarget[1], this.currentTarget[2])) {
+				return;
+			}
+			if(this.currentTarget !== null) {
+				this.fire('dragOut', this.currentTarget[0]);
+				this.currentTarget = null;
+			}
+			for(var i = 0; i < this.targets.length; i++) {
+				if(mloc.within(this.targets[i][1], this.targets[i][2])) {
+					this.currentTarget = this.targets[i];
+					break;
+				}
+			}
+			if(this.currentTarget !== null) {
+				this.fire('dragOver', this.currentTarget[0]);
+			}
+		},
+		
+		drop : function(jEv) {
+			$(document).unbind("mousemove", this.drag_handler);
+			$(document).unbind("mouseup", this.drop_handler);
+			this.dragObj.removeClass(this.config.draggingClass);
+			if(this.currentTarget !== null) {
+				this.fire('dragOut', this.currentTarget[0]);
+				this.fire('dragDrop', this.currentTarget[0]);
+			}
+			this.fire('dragStop', jEv);
+			this.dragObj = null;
+		},
+		
+		pickup : function(jEv, opts) {
+			$.extend(this.config, opts);
+			this.fire('dragStart', jEv);
+			this.dragObj = this.dragObj || this.config.dragObj;
+			this.dragObjOffset = this.config.dragObjOffset || acx.vector(this.dragObj.offset()).sub(jEv.pageX, jEv.pageY);
+			this.lockX = this.config.lockX ? jEv.pageX : 0;
+			this.lockY = this.config.lockY ? jEv.pageY : 0;
+			this.dragObj.addClass(this.config.draggingClass);
+			if(!this.dragObj.get(0).parentNode || this.dragObj.get(0).parentNode.nodeType === 11) { // 11 = document fragment
+				$(document.body).append(this.dragObj);
+			}
+			if(this.config.targetsSelector) {
+				this.currentTarget = null;
+				var targets = ( this.targets = [] );
+				// create an array of elements optimised for rapid collision detection calculation
+				$(this.config.targetsSelector).each(function(i, el) {
+					var jEl = $(el);
+					var tl = acx.vector(jEl.offset());
+					var br = tl.add(jEl.width(), jEl.height());
+					targets.push([jEl, tl, br]);
+				});
+			}
+			$(document).bind("mousemove", this.drag_handler);
+			$(document).bind("mouseup", this.drop_handler);
+			this.drag_handler(jEv);
+		}
+	});
+
+})( this.jQuery, this.app );
+
+(function( app ) {
+
+	var ux = app.ns("ux");
+
+	ux.FieldCollection = ux.Observable.extend({
+		defaults: {
+			fields: []	// the collection of fields
+		},
+		init: function() {
+			this._super();
+			this.fields = this.config.fields;
+		},
+		validate: function() {
+			return this.fields.reduce(function(r, field) {
+				return r && field.validate();
+			}, true);
+		},
+		getData: function(type) {
+			return this.fields.reduce(function(r, field) {
+				r[field.name] = field.val(); return r;
+			}, {});
+		}
+	});
+
+})( this.app );
+
+(function( $, app ) {
+
+	var data = app.ns("data");
+	var ux = app.ns("ux");
+
+	data.Model = ux.Observable.extend({
+		defaults: {
+			data: null
+		},
+		init: function() {
+			this.set( this.config.data );
+		},
+		set: function( key, value ) {
+			if( arguments.length === 1 ) {
+				this._data = $.extend( {}, key );
+			} else {
+				key.split(".").reduce(function( ptr, prop, i, props) {
+					if(i === (props.length - 1) ) {
+						ptr[prop] = value;
+					} else {
+						if( !(prop in ptr) ) {
+							ptr[ prop ] = {};
+						}
+						return ptr[prop];
+					}
+				}, this._data );
+			}
+		},
+		get: function( key ) {
+			return key.split(".").reduce( function( ptr, prop ) {
+				return ( ptr && ( prop in ptr ) ) ? ptr[ prop ] : undefined;
+			}, this._data );
+		},
+	});
+})( this.jQuery, this.app );
+
+(function( app ) {
+
+	var data = app.ns("data");
+	var ux = app.ns("ux");
+
+	data.DataSourceInterface = ux.Observable.extend({
+		/*
+		properties
+			meta = { total: 0 },
+			headers = [ { name: "" } ],
+			data = [ { column: value, column: value } ],
+			sort = { column: "name", dir: "desc" }
+		events
+			data: function( DataSourceInterface )
+		 */
+		_getSummary: function(res) {
+			this.summary = i18n.text("TableResults.Summary", res._shards.successful, res._shards.total, res.hits.total, (res.took / 1000).toFixed(3));
+		},
+		_getMeta: function(res) {
+			this.meta = { total: res.hits.total, shards: res._shards, tool: res.took };
+		}
+	});
+
+})( this.app );
+(function( app ) {
+
+	var data = app.ns("data");
+
+	data.ResultDataSourceInterface = data.DataSourceInterface.extend({
+		results: function(res) {
+			this._getSummary(res);
+			this._getMeta(res);
+			this._getData(res);
+			this.sort = {};
+			this.fire("data", this);
+		},
+		_getData: function(res) {
+			var columns = this.columns = [];
+			this.data = res.hits.hits.map(function(hit) {
+				var row = (function(path, spec, row) {
+					for(var prop in spec) {
+						if(acx.isObject(spec[prop])) {
+							arguments.callee(path.concat(prop), spec[prop], row);
+						} else if(acx.isArray(spec[prop])) {
+							if(spec[prop].length) {
+								arguments.callee(path.concat(prop), spec[prop][0], row)
+							}
+						} else {
+							var dpath = path.concat(prop).join(".");
+							if(! columns.contains(dpath)) {
+								columns.push(dpath);
+							}
+							row[dpath] = (spec[prop] || "null").toString();
+						}
+					}
+					return row;
+				})([ hit._type ], hit, {});
+				row._source = hit;
+				return row;
+			}, this);
+		}
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	/*
+	notes on elasticsearch terminology used in this project
+
+	indices[index] contains one or more
+	types[type] contains one or more
+	documents contain one or more
+	paths[path]
+	each path contains one element of data
+	each path maps to one field
+
+	eg PUT, "/twitter/tweet/1"
+	{
+		user: "mobz",
+		date: "2011-01-01",
+		message: "You know, for browsing elasticsearch",
+		name: {
+			first: "Ben",
+			last: "Birch"
+		}
+	}
+
+	creates
+		1 index: twitter
+				this is the collection of index data
+		1 type: tweet
+				this is the type of document (kind of like a table in sql)
+		1 document: /twitter/tweet/1
+				this is an actual document in the index ( kind of like a row in sql)
+		5 paths: [ ["user"], ["date"], ["message"], ["name","first"], ["name","last"] ]
+				since documents can be heirarchical this maps a path from a document root to a piece of data
+		5 fields: [ "user", "date", "message", "first", "last" ]
+				this is an indexed 'column' of data. fields are not heirarchical
+
+		the relationship between a path and a field is called a mapping. mappings also contain a wealth of information about how es indexes the field
+
+	notes
+	1) a path is stored as an array, the dpath is  <index> . <type> . path.join("."),
+			which can be considered the canonical reference for a mapping
+	2) confusingly, es uses the term index for both the collection of indexed data, and the individually indexed fields
+			so the term index_name is the same as field_name in this sense.
+
+	*/
+
+	var data = app.ns("data");
+	var ux = app.ns("ux");
+
+	var coretype_map = {
+		"string" : "string",
+		"long" : "number",
+		"integer" : "number",
+		"float" : "number",
+		"double" : "number",
+		"ip" : "number",
+		"date" : "date",
+		"boolean" : "boolean",
+		"binary" : "binary",
+		"multi_field" : "multi_field"
+	};
+
+	var default_property_map = {
+		"string" : { "store" : "no", "index" : "analysed" },
+		"number" : { "store" : "no", "precision_steps" : 4 },
+		"date" : { "store" : "no", "format" : "dateOptionalTime", "index": "yes", "precision_steps": 4 },
+		"boolean" : { "store" : "no", "index": "yes" },
+		"binary" : { },
+		"multi_field" : { }
+	};
+
+	// parses metatdata from a cluster, into a bunch of useful data structures
+	data.MetaData = ux.Observable.extend({
+		defaults: {
+			state: null // (required) response from a /_cluster/state request
+		},
+		init: function() {
+			this._super();
+			this.refresh(this.config.state);
+		},
+		getIndices: function(alias) {
+			return alias ? this.aliases[alias] : this.indicesList;
+		},
+		// returns an array of strings containing all types that are in all of the indices passed in, or all types
+		getTypes: function(indices) {
+			var indices = indices || [], types = [];
+			this.typesList.forEach(function(type) {
+				for(var i = 0; i < indices.length; i++) {
+					if(! this.indices[indices[i]].types.contains(type))
+						return;
+				}
+				types.push(type);
+			}, this);
+			return types;
+		},
+		refresh: function(state) {
+			// currently metadata expects all like named fields to have the same type, even when from different types and indices
+			var aliases = this.aliases = {};
+			var indices = this.indices = {};
+			var types = this.types = {};
+			var fields = this.fields = {};
+			var paths = this.paths = {};
+
+			function createField( mapping, index, type, path, name ) {
+				var dpath = [ index, type ].concat( path ).join( "." );
+				var field_name = mapping.index_name || name;
+				var field = paths[ dpath ] = fields[ field_name ] || $.extend({
+					field_name : field_name,
+					core_type : coretype_map[ mapping.type ],
+					dpaths : []
+				}, default_property_map[ coretype_map[ mapping.type ] ], mapping );
+
+				if (field.type === "multi_field" && typeof field.fields !== "undefined") {
+					for (var subField in field.fields) {
+						field.fields[ subField ] = createField( field.fields[ subField ], index, type, path.concat( subField ), name + "." + subField );
+					}
+				}
+				if (fields.dpaths) {
+					field.dpaths.push(dpath);
+				}
+				return field;
+			}
+			function getFields(properties, type, index, listeners) {
+				(function procPath(prop, path) {
+					for (var n in prop) {
+						if ("properties" in prop[n]) {
+							procPath( prop[ n ].properties, path.concat( n ) );
+						} else {
+							var field = createField(prop[n], index, type, path.concat(n), n);							
+							listeners.forEach( function( listener ) {
+								listener[ field.field_name ] = field;
+							} );
+						}
+					}
+				})(properties, []);
+			}
+			for (var index in state.metadata.indices) {
+				indices[index] = {
+					types : [], fields : {}, paths : {}, parents : {}
+				};
+				indices[index].aliases = state.metadata.indices[index].aliases;
+				indices[index].aliases.forEach(function(alias) {
+					(aliases[alias] || (aliases[alias] = [])).push(index);
+				});
+				var mapping = state.metadata.indices[index].mappings;
+				for (var type in mapping) {
+					indices[index].types.push(type);
+					if ( type in types) {
+						types[type].indices.push(index);
+					} else {
+						types[type] = {
+							indices : [index], fields : {}
+						};
+					}
+					getFields(mapping[type].properties, type, index, [fields, types[type].fields, indices[index].fields]);
+					if ( typeof mapping[type]._parent !== "undefined") {
+						indices[index].parents[type] = mapping[type]._parent.type;
+					}
+				}
+			}
+
+			this.aliasesList = Object.keys(aliases);
+			this.indicesList = Object.keys(indices);
+			this.typesList = Object.keys(types);
+			this.fieldsList = Object.keys(fields);
+		}
+	});
+
+})( this.app );	
+
+(function( app ) {
+
+	var data = app.ns("data");
+	var ux = app.ns("ux");
+
+	data.MetaDataFactory = ux.Observable.extend({
+		defaults: {
+			cluster: null // (required) an app.services.Cluster
+		},
+		init: function() {
+			this._super();
+			this.config.cluster.get("_cluster/state", function(data) {
+				this.metaData = new app.data.MetaData({state: data});
+				this.fire("ready", this.metaData,  { originalData: data }); // TODO originalData needed for legacy ui.FilterBrowser
+			}.bind(this));
+		}
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	var data = app.ns("data");
+	var ux = app.ns("ux");
+
+	data.Query = ux.Observable.extend({
+		defaults: {
+			cluster: null,  // (required) instanceof app.services.Cluster
+			size: 50        // size of pages to return
+		},
+		init: function() {
+			this._super();
+			this.cluster = this.config.cluster;
+			this.refuid = 0;
+			this.refmap = {};
+			this.indices = [];
+			this.types = [];
+			this.search = {
+				fields : [ "_parent", "_source" ],
+				query: { bool: { must: [], must_not: [], should: [] } },
+				from: 0,
+				size: this.config.size,
+				sort: [],
+				facets: {},
+				version: true
+			};
+			this.defaultClause = this.addClause();
+			this.history = [ this.getState() ];
+		},
+		clone: function() {
+			var q = new data.Query({ cluster: this.cluster });
+			q.restoreState(this.getState());
+			for(var uqid in q.refmap) {
+				q.removeClause(uqid);
+			}
+			return q;
+		},
+		getState: function() {
+			return $.extend(true, {}, { search: this.search, indices: this.indices, types: this.types });
+		},
+		restoreState: function(state) {
+			state = $.extend(true, {}, state || this.history[this.history.length - 1]);
+			this.indices = state.indices;
+			this.types = state.types;
+			this.search = state.search;
+		},
+		getData: function() {
+			return JSON.stringify(this.search);
+		},
+		query: function() {
+			var state = this.getState();
+			this.cluster.post(
+					(this.indices.join(",") || "_all") + "/" + ( this.types.length ? this.types.join(",") + "/" : "") + "_search",
+					this.getData(),
+					function(results) {
+						if(results === null) {
+							alert(i18n.text("Query.FailAndUndo"));
+							this.restoreState();
+							return;
+						}
+						this.history.push(state);
+
+						this.fire("results", this, results);
+					}.bind(this));
+		},
+		loadParents: function(res,metadata){
+			//create data for mget
+			var data = { docs :[] };
+			var indexToTypeToParentIds = {};
+			res.hits.hits.forEach(function(hit) {
+			if (typeof hit.fields != "undefined"){
+				if (typeof hit.fields._parent != "undefined"){
+					var parentType = metadata.indices[hit._index].parents[hit._type];
+					if (typeof indexToTypeToParentIds[hit._index] == "undefined"){
+						indexToTypeToParentIds[hit._index] = new Object();
+					}
+					if (typeof indexToTypeToParentIds[hit._index][hit._type] == "undefined"){
+						indexToTypeToParentIds[hit._index][hit._type] = new Object();
+					}
+					if (typeof indexToTypeToParentIds[hit._index][hit._type][hit.fields._parent] == "undefined"){
+						indexToTypeToParentIds[hit._index][hit._type][hit.fields._parent] = null;
+						data.docs.push({ _index:hit._index, _type:parentType, _id:hit.fields._parent});
+					}
+				}
+			}
+		});
+
+		//load parents
+		var state = this.getState();
+			this.cluster.post("_mget",JSON.stringify(data),
+				function(results) {
+					if(results === null) {
+						alert(i18n.text("Query.FailAndUndo"));
+						this.restoreState();
+						return;
+					}
+					this.history.push(state);
+					var indexToTypeToParentIdToHit = new Object();
+					results.docs.forEach(function(doc) {
+						if (typeof indexToTypeToParentIdToHit[doc._index] == "undefined"){
+						indexToTypeToParentIdToHit[doc._index] = new Object();
+					}
+					
+					if (typeof indexToTypeToParentIdToHit[doc._index][doc._type] == "undefined"){
+						indexToTypeToParentIdToHit[doc._index][doc._type] = new Object();
+					}
+					
+					indexToTypeToParentIdToHit[doc._index][doc._type][doc._id] = doc;
+					});
+					
+					res.hits.hits.forEach(function(hit) {
+						if (typeof hit.fields != "undefined"){
+							if (typeof hit.fields._parent != "undefined"){
+								var parentType = metadata.indices[hit._index].parents[hit._type];
+								hit._parent = indexToTypeToParentIdToHit[hit._index][parentType][hit.fields._parent];
+							}
+						}
+					});
+
+					this.fire("resultsWithParents", this, res);
+				}.bind(this));
+		},
+		setPage: function(page) {
+			this.search.from = this.config.size * (page - 1);
+		},
+		setSort: function(index, desc) {
+			var sortd = {}; sortd[index] = { reverse: !!desc };
+			this.search.sort.unshift( sortd );
+			for(var i = 1; i < this.search.sort.length; i++) {
+				if(Object.keys(this.search.sort[i])[0] === index) {
+					this.search.sort.splice(i, 1);
+					break;
+				}
+			}
+		},
+		setIndex: function(index, add) {
+			if(add) {
+				if(! this.indices.contains(index)) this.indices.push(index);
+			} else {
+				this.indices.remove(index);
+			}
+			this.fire("setIndex", this, { index: index, add: !!add });
+		},
+		setType: function(type, add) {
+			if(add) {
+				if(! this.types.contains(type)) this.types.push(type);
+			} else {
+				this.types.remove(type);
+			}
+			this.fire("setType", this, { type: type, add: !!add });
+		},
+		addClause: function(value, field, op, bool) {
+			bool = bool || "should";
+			op = op || "match_all";
+			field = field || "_all";
+			var clause = this._setClause(value, field, op, bool);
+			var uqid = "q-" + this.refuid++;
+			this.refmap[uqid] = { clause: clause, value: value, field: field, op: op, bool: bool };
+			if(this.search.query.bool.must.length + this.search.query.bool.should.length > 1) {
+				this.removeClause(this.defaultClause);
+			}
+			this.fire("queryChanged", this, { uqid: uqid, search: this.search} );
+			return uqid; // returns reference to inner query object to allow fast updating
+		},
+		removeClause: function(uqid) {
+			var ref = this.refmap[uqid],
+				bool = this.search.query.bool[ref.bool];
+			bool.remove(ref.clause);
+			if(this.search.query.bool.must.length + this.search.query.bool.should.length === 0) {
+				this.defaultClause = this.addClause();
+			}
+		},
+		addFacet: function(facet) {
+			var facetId = "f-" + this.refuid++;
+			this.search.facets[facetId] = facet;
+			this.refmap[facetId] = { facetId: facetId, facet: facet };
+			return facetId;
+		},
+		removeFacet: function(facetId) {
+			delete this.search.facets[facetId];
+			delete this.refmap[facetId];
+		},
+		_setClause: function(value, field, op, bool) {
+			var clause = {}, query = {};
+			if(op === "match_all") {
+			} else if(op === "query_string") {
+				query["default_field"] = field;
+				query["query"] = value;
+			} else if(op === "missing") {
+				op = "constant_score"
+				var missing = {}, filter = {};
+				missing["field"] = field;
+				filter["missing"] = missing
+				query["filter"] = filter;
+			} else {
+				query[field] = value;
+			}
+			clause[op] = query;
+			this.search.query.bool[bool].push(clause);
+			return clause;
+		}
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	var data = app.ns("data");
+
+	data.QueryDataSourceInterface = data.DataSourceInterface.extend({
+		defaults: {
+			metadata: null, // (required) instanceof app.data.MetaData, the cluster metadata
+			query: null     // (required) instanceof app.data.Query the data source
+		},
+		init: function() {
+			this._super();
+			this.config.query.on("results", this._results_handler.bind(this) );
+			this.config.query.on("resultsWithParents", this._load_parents.bind(this) );
+		},
+		_results_handler: function(query, res) {
+			this._getSummary(res);
+			this._getMeta(res);
+			var sort = query.search.sort[0] || { "_score": { reverse: false }};
+			var sortField = Object.keys(sort)[0];
+			this.sort = { column: sortField, dir: (sort[sortField].reverse ? "asc" : "desc") };
+			this._getData(res, this.config.metadata);
+			this.fire("data", this);
+		},
+		_load_parents: function(query, res) {
+			query.loadParents(res, this.config.metadata);
+		},
+		_getData: function(res, metadata) {
+			var metaColumns = ["_index", "_type", "_id", "_score"];
+			var columns = this.columns = [].concat(metaColumns);
+
+			this.data = res.hits.hits.map(function(hit) {
+				var row = (function(path, spec, row) {
+					for(var prop in spec) {
+						if(acx.isObject(spec[prop])) {
+							arguments.callee(path.concat(prop), spec[prop], row);
+						} else if(acx.isArray(spec[prop])) {
+							if(spec[prop].length) {
+								arguments.callee(path.concat(prop), spec[prop][0], row)
+							}
+						} else {
+							var dpath = path.concat(prop).join(".");
+							if(metadata.paths[dpath]) {
+								var field_name = metadata.paths[dpath].field_name;
+								if(! columns.contains(field_name)) {
+									columns.push(field_name);
+								}
+								row[field_name] = (spec[prop] === null ? "null" : spec[prop] ).toString();
+							} else {
+								// TODO: field not in metadata index
+							}
+						}
+					}
+					return row;
+				})([ hit._index, hit._type ], hit._source, {});
+				metaColumns.forEach(function(n) { row[n] = hit[n]; });
+				row._source = hit;
+				if (typeof hit._parent!= "undefined") {
+					(function(prefix, path, spec, row) {
+					for(var prop in spec) {
+						if(acx.isObject(spec[prop])) {
+							arguments.callee(prefix, path.concat(prop), spec[prop], row);
+						} else if(acx.isArray(spec[prop])) {
+							if(spec[prop].length) {
+								arguments.callee(prefix, path.concat(prop), spec[prop][0], row)
+							}
+						} else {
+							var dpath = path.concat(prop).join(".");
+							if(metadata.paths[dpath]) {
+								var field_name = metadata.paths[dpath].field_name;
+								var column_name = prefix+"."+field_name;
+								if(! columns.contains(column_name)) {
+									columns.push(column_name);
+								}
+								row[column_name] = (spec[prop] === null ? "null" : spec[prop] ).toString();
+							} else {
+								// TODO: field not in metadata index
+							}
+						}
+					}
+					})(hit._parent._type,[hit._parent._index, hit._parent._type], hit._parent._source, row);
+				}
+				return row;
+			}, this);
+		}
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	var data = app.ns("data");
+	var ux = app.ns("ux");
+
+	data.BoolQuery = ux.Observable.extend({
+		defaults: {
+			size: 50		// size of pages to return
+		},
+		init: function() {
+			this._super();
+			this.refuid = 0;
+			this.refmap = {};
+			this.search = {
+				query: { bool: { must: [], must_not: [], should: [] } },
+				from: 0,
+				size: this.config.size,
+				sort: [],
+				facets: {}
+			};
+			this.defaultClause = this.addClause();
+		},
+		setSize: function(size) {
+			this.search.size = parseInt( size, 10 );
+		},
+		setPage: function(page) {
+			this.search.from = this.config.size * (page - 1) + 1;
+		},
+		addClause: function(value, field, op, bool) {
+			bool = bool || "should";
+			op = op || "match_all";
+			field = field || "_all";
+			var clause = this._setClause(value, field, op, bool);
+			var uqid = "q-" + this.refuid++;
+			this.refmap[uqid] = { clause: clause, value: value, field: field, op: op, bool: bool };
+			if(this.search.query.bool.must.length + this.search.query.bool.should.length > 1) {
+				this.removeClause(this.defaultClause);
+			}
+			this.fire("queryChanged", this, { uqid: uqid, search: this.search} );
+			return uqid; // returns reference to inner query object to allow fast updating
+		},
+		removeClause: function(uqid) {
+			var ref = this.refmap[uqid],
+				bool = this.search.query.bool[ref.bool];
+			var clauseIdx = bool.indexOf(ref.clause);
+			// Check that this clause hasn't already been removed
+			if (clauseIdx >=0) {
+				bool.splice(clauseIdx, 1);
+			}
+		},
+		_setClause: function(value, field, op, bool) {
+			var clause = {}, query = {};
+			if(op === "match_all") {
+			} else if(op === "query_string") {
+				query["default_field"] = field;
+				query["query"] = value;
+			} else if(op === "missing") {
+				op = "constant_score"
+				var missing = {}, filter = {};
+				missing["field"] = field;
+				filter["missing"] = missing
+				query["filter"] = filter;
+			} else {
+				query[field] = value;
+			}
+			clause[op] = query;
+			this.search.query.bool[bool].push(clause);
+			return clause;
+		},
+		getData: function() {
+			return JSON.stringify(this.search);
+		}
+	});
+
+})( this.app );
+(function( app ) {
+	
+	var ux = app.ns("ux");
+	var services = app.ns("services");
+
+	services.Preferences = ux.Singleton.extend({
+		init: function() {
+			this._storage = window.localStorage;
+			this._setItem("__version", 1 );
+		},
+		get: function( key ) {
+			return this._getItem( key );
+		},
+		set: function( key, val ) {
+			return this._setItem( key, val );
+		},
+		_getItem: function( key ) {
+			try {
+				return JSON.parse( this._storage.getItem( key ) );
+			} catch(e) {
+				console.warn( e );
+				return undefined;
+			}
+		},
+		_setItem: function( key, val ) {
+			try {
+				return this._storage.setItem( key, JSON.stringify( val ) );
+			} catch(e) {
+				console.warn( e );
+				return undefined;
+			}
+		}
+	});
+
+})( this.app );
+
+(function( $, app ) {
+
+	var services = app.ns("services");
+	var ux = app.ns("ux");
+
+	function parse_version( v ) {
+		return v.match(/^(\d+)\.(\d+)\.(\d+)/).slice(1,4).map( function(d) { return parseInt(d || 0, 10); } );
+	}
+
+	services.Cluster = ux.Class.extend({
+		defaults: {
+			base_uri: null
+		},
+		init: function() {
+			this.base_uri = this.config.base_uri;
+		},
+		setVersion: function( v ) {
+			this.version = v;
+			this._version_parts = parse_version( v );
+		},
+		versionAtLeast: function( v ) {
+			var testVersion = parse_version( v );
+			for( var i = 0; i < 3; i++ ) {
+				if( testVersion[i] !== this._version_parts[i] ) {
+					return testVersion[i] < this._version_parts[i];
+				}
+			}
+			return true;
+		},
+		request: function( params ) {
+			return $.ajax( $.extend({
+				url: this.base_uri + params.path,
+				dataType: "json",
+				error: function(xhr, type, message) {
+					if("console" in window) {
+						console.log({ "XHR Error": type, "message": message });
+					}
+				}
+			},  params) );
+		},
+		"get": function(path, success) { return this.request( { type: "GET", path: path, success: success } ); },
+		"post": function(path, data, success) { return this.request( { type: "POST", path: path, data: data, success: success } ); },
+		"put": function(path, data, success) { return this.request( { type: "PUT", path: path, data: data, success: success } ); },
+		"delete": function(path, data, success) { return this.request( { type: "DELETE", path: path, data: data, success: success } ); }
+	});
+
+})( this.jQuery, this.app );
+
+(function( app ) {
+
+	var services = app.ns("services");
+	var ux = app.ns("ux");
+
+	services.ClusterState = ux.Observable.extend({
+		defaults: {
+			cluster: null
+		},
+		init: function() {
+			this._super();
+			this.cluster = this.config.cluster;
+			this.clusterState = null;
+			this.status = null;
+			this.nodeStats = null;
+			this.clusterNodes = null;
+		},
+		refresh: function() {
+			var self = this, clusterState, status, nodeStats, clusterNodes, clusterHealth;
+			function updateModel() {
+				if( clusterState && status && nodeStats && clusterNodes && clusterHealth ) {
+					this.clusterState = clusterState;
+					this.status = status;
+					this.nodeStats = nodeStats;
+					this.clusterNodes = clusterNodes;
+					this.clusterHealth = clusterHealth;
+					this.fire( "data", this );
+				}
+			}
+			this.cluster.get("_cluster/state", function( data ) {
+				clusterState = data;
+				updateModel.call( self );
+			});
+			this.cluster.get("_status", function( data ) {
+				status = data;
+				updateModel.call( self );
+			});
+			this.cluster.get("_nodes/stats?all=true", function( data ) {
+				nodeStats = data;
+				updateModel.call( self );
+			});
+			this.cluster.get("_nodes", function( data ) {
+				clusterNodes = data;
+				updateModel.call( self );
+			});
+			this.cluster.get("_cluster/health", function( data ) {
+				clusterHealth = data;
+				updateModel.call( self );
+			});
+		},
+		_clusterState_handler: function(state) {
+			this.clusterState = state;
+			this.redraw("clusterState");
+		},
+		_status_handler: function(status) {
+			this.status = status;
+			this.redraw("status");
+		},
+		_clusterNodeStats_handler: function(stats) {
+			this.nodeStats = stats;
+			this.redraw("nodeStats");
+		},
+		_clusterNodes_handler: function(nodes) {
+			this.clusterNodes = nodes;
+			this.redraw("clusterNodes");
+		},
+		_clusterHealth_handler: function(health) {
+			this.clusterHealth = health;
+			this.redraw("status");
+		}
+	});
+
+})( this.app );
+(function( $, joey, app ) {
+
+	var ui = app.ns("ui");
+	var ux = app.ns("ux");
+
+	ui.AbstractWidget = ux.Observable.extend({
+		defaults : {
+			id: null     // the id of the widget
+		},
+
+		el: null,       // this is the jquery wrapped dom element(s) that is the root of the widget
+
+		init: function() {
+			this._super();
+			for(var prop in this) {       // automatically bind all the event handlers
+				if(prop.contains("_handler")) {
+					this[prop] = this[prop].bind(this);
+				}
+			}
+		},
+
+		id: function(suffix) {
+			return this.config.id ? (this.config.id + (suffix ? "-" + suffix : "")) : undefined;
+		},
+
+		attach: function( parent, method ) {
+			if( parent ) {
+				this.el[ method || "appendTo"]( parent );
+			}
+			this.fire("attached", this );
+			return this;
+		},
+
+		remove: function() {
+			this.el.remove();
+			this.fire("removed", this );
+			this.removeAllObservers();
+			this.el = null;
+			return this;
+		}
+	});
+
+	joey.plugins.push( function( obj ) {
+		if( obj instanceof ui.AbstractWidget ) {
+			return obj.el[0];
+		}
+	});
+
+})( this.jQuery, this.joey, this.app );
+
+(function( $, app, joey ) {
+
+	var ui = app.ns("ui");
+
+	ui.AbstractField = ui.AbstractWidget.extend({
+
+		defaults: {
+			name : "",			// (required) - name of the field
+			require: false,	// validation requirements (false, true, regexp, function)
+			value: "",			// default value
+			label: ""				// human readable label of this field
+		},
+
+		init: function(parent) {
+			this._super();
+			this.el = $.joey(this._main_template());
+			this.field = this.el.find("[name="+this.config.name+"]");
+			this.label = this.config.label;
+			this.require = this.config.require;
+			this.name = this.config.name;
+			this.val( this.config.value );
+			this.attach( parent );
+		},
+
+		val: function( val ) {
+			if(val === undefined) {
+				return this.field.val();
+			} else {
+				this.field.val( val );
+				return this;
+			}
+		},
+
+		validate: function() {
+			var val = this.val(), req = this.require;
+			if( req === false ) {
+				return true;
+			} else if( req === true ) {
+				return val.length > 0;
+			} else if( req.test && $.isFunction(req.test) ) {
+				return req.test( val );
+			} else if( $.isFunction(req) ) {
+				return req( val, this );
+			}
+		}
+
+	});
+
+})( this.jQuery, this.app, this.joey );
+
+(function( app ) {
+
+	var ui = app.ns("ui");
+
+	ui.TextField = ui.AbstractField.extend({
+		init: function() {
+			this._super();
+		},
+		_keyup_handler: function() {
+			this.fire("change", this );
+		},
+		_main_template: function() {
+			return { tag: "DIV", id: this.id(), cls: "uiField uiTextField", children: [
+				{ tag: "INPUT",
+					type: "text",
+					name: this.config.name,
+					placeholder: this.config.placeholder,
+					onkeyup: this._keyup_handler
+				}
+			]};
+		}
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	var ui = app.ns("ui");
+
+	ui.CheckField = ui.AbstractField.extend({
+		_main_template: function() { return (
+			{ tag: "DIV", id: this.id(), cls: "uiCheckField", children: [
+				{ tag: "INPUT", type: "checkbox", name: this.config.name, checked: !!this.config.value }
+			] }
+		); },
+		validate: function() {
+			return this.val() || ( ! this.require );
+		},
+		val: function( val ) {
+			if( val === undefined ) {
+				return !!this.field.attr( "checked" );
+			} else {
+				this.field.attr( "checked", !!val );
+			}
+		}
+	});
+
+})( this.app );
+
+
+
+(function( $, joey, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.Button = ui.AbstractWidget.extend({
+		defaults : {
+			label: "",                 // the label text
+			disabled: false,           // create a disabled button
+			autoDisable: false         // automatically disable the button when clicked
+		},
+
+		_baseCls: "uiButton",
+
+		init: function(parent) {
+			this._super();
+			this.el = $.joey(this.button_template())
+				.bind("click", this.click_handler);
+			this.config.disabled && this.disable();
+			this.attach( parent );
+		},
+
+		click_handler: function(jEv) {
+			if(! this.disabled) {
+				this.fire("click", jEv, this);
+				this.config.autoDisable && this.disable();
+			}
+		},
+
+		enable: function() {
+			this.el.removeClass("disabled");
+			this.disabled = false;
+			return this;
+		},
+
+		disable: function(disable) {
+			if(disable === false) {
+					return this.enable();
+			}
+			this.el.addClass("disabled");
+			this.disabled = true;
+			return this;
+		},
+
+		button_template: function() { return (
+			{ tag: 'BUTTON', type: 'button', id: this.id(), cls: this._baseCls, children: [
+				{ tag: 'DIV', cls: 'uiButton-content', children: [
+					{ tag: 'DIV', cls: 'uiButton-label', text: this.config.label }
+				] }
+			] }
+		); }
+	});
+
+})( this.jQuery, this.joey, this.app );
+
+(function( $, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.MenuButton = app.ui.Button.extend({
+		defaults: {
+			menu: null
+		},
+		_baseCls: "uiButton uiMenuButton",
+		init: function(parent) {
+			this._super(parent);
+			this.menu = this.config.menu;
+			this.on("click", this.openMenu_handler);
+			this.menu.on("open", function() { this.el.addClass("active"); }.bind(this));
+			this.menu.on("close", function() { this.el.removeClass("active"); }.bind(this));
+		},
+		openMenu_handler: function(jEv) {
+			this.menu && this.menu.open(jEv);
+		}
+	});
+
+})( this.jQuery, this.app );
+
+(function( $, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.SplitButton = ui.AbstractWidget.extend({
+		defaults: {
+			items: [],
+			label: ""
+		},
+		_baseCls: "uiSplitButton",
+		init: function( parent ) {
+			this._super( parent );
+			this.value = null;
+			this.button = new ui.Button({
+				label: this.config.label,
+				onclick: this._click_handler
+			});
+			this.menu = new ui.SelectMenuPanel({
+				value: this.config.value,
+				items: this._getItems(),
+				onSelect: this._select_handler
+			});
+			this.menuButton = new ui.MenuButton({
+				label: "\u00a0",
+				menu: this.menu
+			});
+			this.el = $.joey(this._main_template());
+		},
+		remove: function() {
+			this.menu.remove();
+		},
+		disable: function() {
+			this.button.disable();
+		},
+		enable: function() {
+			this.button.enable();
+		},
+		_click_handler: function() {
+			this.fire("click", this, { value: this.value } );
+		},
+		_select_handler: function( panel, event ) {
+			this.fire( "select", this, event );
+		},
+		_getItems: function() {
+			return this.config.items;
+		},
+		_main_template: function() {
+			return { tag: "DIV", cls: this._baseCls, children: [
+				this.button, this.menuButton
+			] };
+		}
+	});
+
+})( this.jQuery, this.app );
+
+(function( $, app, i18n ) {
+
+	var ui = app.ns("ui");
+
+	ui.RefreshButton = ui.SplitButton.extend({
+		defaults: {
+			timer: -1
+		},
+		init: function( parent ) {
+			this.config.label = i18n.text("General.RefreshResults");
+			this._super( parent );
+			this.set( this.config.timer );
+		},
+		set: function( value ) {
+			this.value = value;
+			window.clearInterval( this._timer );
+			if( this.value > 0 ) {
+				this._timer = window.setInterval( this._refresh_handler, this.value );
+			}
+		},
+		_click_handler: function() {
+			this._refresh_handler();
+		},
+		_select_handler: function( el, event ) {
+			this.set( event.value );
+			this.fire("change", this );
+		},
+		_refresh_handler: function() {
+			this.fire("refresh", this );
+		},
+		_getItems: function() {
+			return [
+				{ text: i18n.text("General.ManualRefresh"), value: -1 },
+				{ text: i18n.text("General.RefreshQuickly"), value: 100 },
+				{ text: i18n.text("General.Refresh5seconds"), value: 5000 },
+				{ text: i18n.text("General.Refresh1minute"), value: 60000 }
+			];
+		}
+	});
+
+})( this.jQuery, this.app, this.i18n );
+
+(function( $, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.Toolbar = ui.AbstractWidget.extend({
+		defaults: {
+			label: "",
+			left: [],
+			right: []
+		},
+		init: function(parent) {
+			this._super();
+			this.el = $.joey(this._main_template());
+		},
+		_main_template: function() {
+			return { tag: "DIV", cls: "uiToolbar", children: [
+				{ tag: "DIV", cls: "pull-left", children: [
+					{ tag: "H2", text: this.config.label }
+				].concat(this.config.left) },
+				{ tag: "DIV", cls: "pull-right", children: this.config.right }
+			]};
+		}
+	});
+
+})( this.jQuery, this.app );
+
+(function( $, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.AbstractPanel = ui.AbstractWidget.extend({
+		defaults: {
+			body: null,            // initial content of the body
+			modal: true,           // create a modal panel - creates a div that blocks interaction with page
+			height: 'auto',        // panel height
+			width: 400,            // panel width (in pixels)
+			open: false,           // show the panel when it is created
+			parent: 'BODY',        // node that panel is attached to
+			autoRemove: false      // remove the panel from the dom and destroy it when the widget is closed
+		},
+		shared: {  // shared data for all instances of ui.Panel and decendants
+			stack: [], // array of all open panels
+			modal: $( { tag: "DIV", id: "uiModal", css: { opacity: 0.2, position: "absolute", top: "0px", left: "0px" } } )
+		},
+		init: function() {
+			this._super();
+		},
+		open: function( ev ) {
+			this.el
+				.css( { visibility: "hidden" } )
+				.appendTo( this.config.parent )
+				.css( this._getPosition( ev ) )
+				.css( { zIndex: (this.shared.stack.length ? (+this.shared.stack[this.shared.stack.length - 1].el.css("zIndex") + 10) : 100) } )
+				.css( { visibility: "visible", display: "block" } );
+			this.shared.stack.remove(this);
+			this.shared.stack.push(this);
+			this._setModal();
+			$(document).bind("keyup", this._close_handler );
+			this.fire("open", { source: this, event: ev } );
+			return this;
+		},
+		close: function() {
+			var index = this.shared.stack.indexOf(this);
+			if(index !== -1) {
+				this.shared.stack.splice(index, 1);
+				this.el.css( { left: "-2999px" } ); // move the dialog to the left rather than hiding to prevent ie6 rendering artifacts
+				this._setModal();
+				this.fire("close", this );
+				if(this.config.autoRemove) {
+					this.remove();
+				}
+			}
+			return this;
+		},
+		// close the panel and remove it from the dom, destroying it (you can not reuse the panel after calling remove)
+		remove: function() {
+			this.close();
+			$(document).unbind("keyup", this._close_handler );
+			this._super();
+		},
+		// starting at the top of the stack, find the first panel that wants a modal and put it just underneath, otherwise remove the modal
+		_setModal: function() {
+			for(var stackPtr = this.shared.stack.length - 1; stackPtr >= 0; stackPtr--) {
+				if(this.shared.stack[stackPtr].config.modal) {
+					this.shared.modal
+						.appendTo( document.body )
+						.css( { zIndex: this.shared.stack[stackPtr].el.css("zIndex") - 5 } )
+						.css( $(document).vSize().asSize() );
+					return;
+				}
+			}
+			this.shared.modal.remove(); // no panels that want a modal were found
+		},
+		_getPosition: function() {
+			return $(window).vSize()                        // get the current viewport size
+				.sub(this.el.vSize())                         // subtract the size of the panel
+				.mod(function(s) { return s / 2; })           // divide by 2 (to center it)
+				.add($(document).vScroll())                   // add the current scroll offset
+				.mod(function(s) { return Math.max(5, s); })  // make sure the panel is not off the edge of the window
+				.asOffset();                                  // and return it as a {top, left} object
+		},
+		_close_handler: function( ev ) {
+			if( ev.type === "keyup" && ev.keyCode !== 27) { return; } // press esc key to close
+			$(document).unbind("keyup", this._close_handler);
+			this.close( ev );
+		}
+	});
+
+})( this.jQuery, this.app );
+
+(function( $, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.DraggablePanel = ui.AbstractPanel.extend({
+		defaults: {
+	//		title: ""   // (required) text for the panel title
+		},
+
+		_baseCls: "uiPanel",
+
+		init: function() {
+			this._super();
+			this.body = $(this._body_template());
+			this.title = $(this._title_template());
+			this.el = $.joey( this._main_template() );
+			this.el.css( { width: this.config.width } );
+			this.dd = new app.ux.DragDrop({
+				pickupSelector: this.el.find(".uiPanel-titleBar"),
+				dragObj: this.el
+			});
+			// open the panel if set in configuration
+			this.config.open && this.open();
+		},
+
+		setBody: function(body) {
+				this.body.empty().append(body);
+		},
+		_body_template: function() { return { tag: "DIV", cls: "uiPanel-body", css: { height: this.config.height + (this.config.height === 'auto' ? "" : "px" ) }, children: [ this.config.body ] }; },
+		_title_template: function() { return { tag: "SPAN", cls: "uiPanel-title", text: this.config.title }; },
+		_main_template: function() { return (
+			{ tag: "DIV", id: this.id(), cls: this._baseCls, children: [
+				{ tag: "DIV", cls: "uiPanel-titleBar", children: [
+					{ tag: "DIV", cls: "uiPanel-close", onclick: this._close_handler, text: "x" },
+					this.title
+				]},
+				this.body
+			] }
+		); }
+	});
+
+})( this.jQuery, this.app );
+
+(function( app ) {
+
+	var ui = app.ns("ui");
+
+	ui.InfoPanel = ui.DraggablePanel.extend({
+		_baseCls: "uiPanel uiInfoPanel"
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	var ui = app.ns("ui");
+
+	ui.DialogPanel = ui.DraggablePanel.extend({
+		_commit_handler: function(jEv) {
+			this.fire("commit", this, { jEv: jEv });
+		},
+		_main_template: function() {
+			var t = this._super();
+			t.children.push(this._actionsBar_template());
+			return t;
+		},
+		_actionsBar_template: function() {
+			return { tag: "DIV", cls: "pull-right", children: [
+				new app.ui.Button({ label: "Cancel", onclick: this._close_handler }),
+				new app.ui.Button({ label: "OK", onclick: this._commit_handler })
+			]};
+		}
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	var ui = app.ns("ui");
+
+	ui.MenuPanel = ui.AbstractPanel.extend({
+		defaults: {
+			items: [],		// (required) an array of menu items
+			modal: false
+		},
+		_baseCls: "uiMenuPanel",
+		init: function() {
+			this._super();
+			this.el = $(this._main_template());
+		},
+		open: function(jEv) {
+			this._super(jEv);
+			var cx = this; setTimeout(function() { $(document).bind("click", cx._close_handler); }, 50);
+		},
+		_getItems: function() {
+			return this.config.items;
+		},
+		_close_handler: function(jEv) {
+			this._super(jEv);
+			$(document).unbind("click", this._close_handler);
+		},
+		_main_template: function() {
+			return { tag: "DIV", cls: this._baseCls, children: this._getItems().map(this._menuItem_template, this) };
+		},
+		_menuItem_template: function(item) {
+			var dx = item.disabled ? { onclick: function() {} } : {};
+			return { tag: "LI", cls: "uiMenuPanel-item" + (item.disabled ? " disabled" : "") + (item.selected ? " selected" : ""), children: [ $.extend({ tag: "DIV", cls: "uiMenuPanel-label" }, item, dx ) ] };
+		},
+		_getPosition: function(jEv) {
+			var right = !! $(jEv.target).parents(".pull-right").length;
+			var parent = $(jEv.target).closest("BUTTON");
+			return parent.vOffset()
+				.addY(parent.vSize().y)
+				.addX( right ? parent.vSize().x - this.el.vOuterSize().x : 0 )
+				.asOffset();
+		}
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	var ui = app.ns("ui");
+
+	ui.SelectMenuPanel = ui.MenuPanel.extend({
+		defaults: {
+			items: [],		// (required) an array of menu items
+			value: null
+		},
+		_baseCls: "uiSelectMenuPanel uiMenuPanel",
+		init: function() {
+			this.value = this.config.value;
+			this._super();
+		},
+		_getItems: function() {
+			return this.config.items.map( function( item ) {
+				return {
+					text: item.text,
+					selected: this.value === item.value,
+					onclick: function( jEv ) {
+						var el = $( jEv.target ).closest("LI");
+						el.parent().children().removeClass("selected");
+						el.addClass("selected");
+						this.fire( "select", this, { value: item.value } );
+						this.value = item.value;
+					}.bind(this)
+				};
+			}, this );
+
+		}
+	});
+
+})( this.app );
+
+( function( $, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.Table = ui.AbstractWidget.extend({
+		defaults: {
+			store: null, // (required) implements interface app.data.DataSourceInterface
+			height: 0,
+			width: 0
+		},
+		_baseCls: "uiTable",
+		init: function(parent) {
+			this._super();
+			this.initElements(parent);
+			this.config.store.on("data", this._data_handler);
+		},
+		attach: function(parent) {
+			if(parent) {
+				this._super(parent);
+				this._reflow();
+			}
+		},
+		initElements: function(parent) {
+			this.el = $.joey(this._main_template());
+			this.body = this.el.find(".uiTable-body");
+			this.headers = this.el.find(".uiTable-headers");
+			this.tools = this.el.find(".uiTable-tools");
+			this.attach( parent );
+		},
+		_data_handler: function(store) {
+			this.tools.text(store.summary);
+			this.headers.empty().append(this._header_template(store.columns));
+			this.body.empty().append(this._body_template(store.data, store.columns));
+			this._reflow();
+		},
+		_reflow: function() {
+			var firstCol = this.body.find("TR:first TH.uiTable-header-cell > DIV"),
+					headers = this.headers.find("TR:first TH.uiTable-header-cell > DIV");
+			for(var i = 0; i < headers.length; i++) {
+				$(headers[i]).width( $(firstCol[i]).width() );
+			}
+			this._scroll_handler();
+		},
+		_scroll_handler: function(ev) {
+			this.el.find(".uiTable-headers").scrollLeft(this.body.scrollLeft());
+		},
+		_dataClick_handler: function(ev) {
+			var row = $(ev.target).closest("TR");
+			if(row.length) {
+				this.fire("rowClick", this, { row: row } );
+			}
+		},
+		_headerClick_handler: function(ev) {
+			var header = $(ev.target).closest("TH.uiTable-header-cell");
+			if(header.length) {
+				this.fire("headerClick", this, { header: header, column: header.data("column"), dir: header.data("dir") });
+			}
+		},
+		_main_template: function() {
+			return { tag: "DIV", id: this.id(), css: { width: this.config.width + "px" }, cls: this._baseCls, children: [
+				{ tag: "DIV", cls: "uiTable-tools" },
+				{ tag: "DIV", cls: "uiTable-headers", onclick: this._headerClick_handler },
+				{ tag: "DIV", cls: "uiTable-body",
+					onclick: this._dataClick_handler,
+					onscroll: this._scroll_handler,
+					css: { height: this.config.height + "px", width: this.config.width + "px" }
+				}
+			] };
+		},
+		_header_template: function(columns) {
+			var ret = { tag: "TABLE", children: [ this._headerRow_template(columns) ] };
+			ret.children[0].children.push(this._headerEndCap_template());
+			return ret;
+		},
+		_headerRow_template: function(columns) {
+			return { tag: "TR", cls: "uiTable-header-row", children: columns.map(function(column) {
+				var dir = ((this.config.store.sort.column === column) && this.config.store.sort.dir) || "none";
+				return { tag: "TH", data: { column: column, dir: dir }, cls: "uiTable-header-cell" + ((dir !== "none") ? " uiTable-sort" : ""), children: [
+					{ tag: "DIV", children: [
+						{ tag: "DIV", cls: "uiTable-headercell-menu", text: dir === "asc" ? "\u25b2" : "\u25bc" },
+						{ tag: "DIV", cls: "uiTable-headercell-text", text: column }
+					]}
+				]};
+			}, this)};
+		},
+		_headerEndCap_template: function() {
+			return { tag: "TH", cls: "uiTable-headerEndCap", children: [ { tag: "DIV" } ] };
+		},
+		_body_template: function(data, columns) {
+			return { tag: "TABLE", children: []
+				.concat(this._headerRow_template(columns))
+				.concat(data.map(function(row) {
+					return { tag: "TR", data: { row: row }, cls: "uiTable-row", children: columns.map(function(column){
+						return { tag: "TD", cls: "uiTable-cell", children: [ { tag: "DIV", text: (row[column] || "").toString() } ] };
+					})};
+				}))
+			};
+		}
+
+	});
+
+})( this.jQuery, this.app );
+
+( function( $, app, joey ) {
+
+	var ui = app.ns("ui");
+
+	var CELL_SEPARATOR = ",";
+	var CELL_QUOTE = '"';
+	var LINE_SEPARATOR = "\r\n";
+
+	ui.CSVTable = ui.AbstractWidget.extend({
+		defaults: {
+			results: null
+		},
+		_baseCls: "uiCSVTable",
+		init: function( parent ) {
+			this._super();
+			var results = this.config.results.hits.hits;
+			var columns = this._parseResults( results );
+			this._downloadButton = new ui.Button({
+				label: "Generate Download Link",
+				onclick: this._downloadLinkGenerator_handler
+			});
+			this._downloadLink = $.joey( { tag: "A", text: "download", });
+			this._downloadLink.hide();
+			this._csvText = this._csv_template( columns, results );
+			this.el = $.joey( this._main_template() );
+			this.attach( parent );
+		},
+		_downloadLinkGenerator_handler: function() {
+			this._downloadLink.attr("href", "data:text/csv;chatset=utf-8," + window.encodeURIComponent( this._csvText ) );
+			this._downloadLink.show();
+		},
+		_parseResults: function( results ) {
+			var columnPaths = {};
+			(function parse( path, obj ) {
+				if( obj instanceof Array ) {
+					for( var i = 0; i < obj.length; i++ ) {
+						parse( path, obj[i] );
+					}
+				} else if( typeof obj === "object" ) {
+					for( var prop in obj ) {
+						parse( path + "." + prop, obj[ prop ] );
+					}
+				} else {
+					columnPaths[ path ] = true;
+				}
+			})( "root", results );
+			var columns = [];
+			for( var column in columnPaths ) {
+				columns.push( column.split(".").slice(1) );
+			}
+			return columns;
+		},
+		_main_template: function() { return (
+			{ tag: "DIV", cls: this._baseCls, id: this.id(), children: [
+				this._downloadButton,
+				this._downloadLink,
+				{ tag: "PRE", text: this._csvText }
+			] }
+		); },
+		_csv_template: function( columns, results ) {
+			return this._header_template( columns ) + LINE_SEPARATOR + this._results_template( columns, results );
+		},
+		_header_template: function( columns ) {
+			return columns.map( function( column ) {
+				return column.join(".");
+			}).join( CELL_SEPARATOR );
+		},
+		_results_template: function( columns, results ) {
+			return results.map( function( result ) {
+				return columns.map( function( column ) {
+					var l = 0,
+						ptr = result;
+					while( l !== column.length && ptr != null ) {
+						ptr = ptr[ column[ l++ ] ];
+					}
+					return ( ptr == null ) ? "" : ( CELL_QUOTE + ptr.toString().replace(/"/g, '""') + CELL_QUOTE );
+				}).join( CELL_SEPARATOR );
+			}).join( LINE_SEPARATOR );
+		}
+	});
+
+})( this.jQuery, this.app, this.joey );
+
+(function( $, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.JsonPretty = ui.AbstractWidget.extend({
+		defaults: {
+			obj: null
+		},
+		init: function(parent) {
+			this._super();
+			this.el = $(this._main_template());
+			this.attach(parent);
+			this.el.click(this._click_handler);
+		},
+		
+		_click_handler: function(jEv) {
+			var t = $(jEv.target).closest(".uiJsonPretty-name").closest("LI");
+			if(t.length === 0 || t.parents(".uiJsonPretty-minimised").length > 0) { return; }
+			t.toggleClass("uiJsonPretty-minimised");
+			jEv.stopPropagation();
+		},
+		
+		_main_template: function() {
+			try {
+					return { tag: "DIV", cls: "uiJsonPretty", children: this.pretty.parse(this.config.obj) };
+			}	catch (error) {
+					throw "JsonPretty error: " + error.message;
+			}
+		},
+		
+		pretty: { // from https://github.com/RyanAmos/Pretty-JSON/blob/master/pretty_json.js
+			"expando" : function(value) {
+				return (value && (/array|object/i).test(value.constructor.name)) ? "expando" : "";
+			},
+			"parse": function (member) {
+				return this[(member == null) ? 'null' : member.constructor.name.toLowerCase()](member);
+			},
+			"null": function (value) {
+				return this['value']('null', 'null');
+			},
+			"array": function (value) {
+				var results = [];
+				var lastItem = value.length - 1;
+				value.forEach(function( v, i ) {
+					results.push({ tag: "LI", cls: this.expando(v), children: [ this['parse'](v) ] });
+					if( i !== lastItem ) {
+						results.push(",");
+					}
+				}, this);
+				return [ "[ ", ((results.length > 0) ? { tag: "UL", cls: "uiJsonPretty-array", children: results } : null), "]" ];
+			},
+			"object": function (value) {
+				var results = [];
+				var keys = Object.keys( value );
+				var lastItem = keys.length - 1;
+				keys.forEach( function( key, i ) {
+					var children = [ this['value']( 'name', '"' + key + '"' ), ": ", this['parse']( value[ key ]) ];
+					if( i !== lastItem ) {
+						children.push(",");
+					}
+					results.push( { tag: "LI", cls: this.expando( value[ key ] ), children: children } );
+				}, this);
+				return [ "{ ", ((results.length > 0) ? { tag: "UL", cls: "uiJsonPretty-object", children: results } : null ),  "}" ];
+			},
+			"number": function (value) {
+				return this['value']('number', value.toString());
+			},
+			"string": function (value) {
+				if (/^(http|https|file):\/\/[^\s]+$/.test(value)) {
+					return this['link']( value );
+				} else {
+					return this['value']('string', '"' + value.toString() + '"');
+				}
+			},
+			"boolean": function (value) {
+				return this['value']('boolean', value.toString());
+			},
+			"link": function( value ) {
+					return this['value']("string", { tag: "A", href: value, target: "_blank", text: '"' + value + '"' } );
+			},
+			"value": function (type, value) {
+				if (/^(http|https|file):\/\/[^\s]+$/.test(value)) {
+				}
+				return { tag: "SPAN", cls: "uiJsonPretty-" + type, text: value };
+			}
+		}
+	});
+
+})( this.jQuery, this.app );
+
+(function( $, app ) {
+
+	var ui = app.ns("ui");
+	var ut = app.ns("ut");
+
+	ui.PanelForm = ui.AbstractWidget.extend({
+		defaults: {
+			fields: null	// (required) instanceof app.ux.FieldCollection
+		},
+		init: function(parent) {
+			this._super();
+			this.el = $.joey(this._main_template());
+			this.attach( parent );
+		},
+		_main_template: function() {
+			return { tag: "DIV", id: this.id(), cls: "uiPanelForm", children: this.config.fields.fields.map(this._field_template, this) };
+		},
+		_field_template: function(field) {
+			return { tag: "LABEL", cls: "uiPanelForm-field", children: [
+				{ tag: "DIV", cls: "uiPanelForm-label", children: [ field.label, ut.require_template(field) ] },
+				field
+			]};
+		}
+	});
+
+})( this.jQuery, this.app );
+
+(function( app ){
+
+	var ui = app.ns("ui");
+
+	ui.HelpPanel = ui.InfoPanel.extend({
+		defaults: {
+			ref: "",
+			open: true,
+			autoRemove: true,
+			modal: false,
+			width: 500,
+			height: 450,
+			title: i18n.text("General.Help")
+		},
+		init: function() {
+			this._super();
+			this.body.append(i18n.text(this.config.ref));
+		}
+	});
+
+})( this.app );
+
+(function( app ) {
+
+	var ui = app.ns("ui");
+
+	ui.JsonPanel = ui.InfoPanel.extend({
+		defaults: {
+			json: null, // (required)
+			modal: false,
+			open: true,
+			autoRemove: true,
+			height: 500,
+			width: 600
+		},
+
+		_baseCls: "uiPanel uiInfoPanel uiJsonPanel",
+
+		_body_template: function() {
+			var body = this._super();
+			body.children = [ new ui.JsonPretty({ obj: this.config.json }) ];
+			return body;
+		}
+	});
+
+})( this.app );
+
+(function( $, app, i18n ) {
+
+	var ui = app.ns("ui");
+
+	ui.SidebarSection = ui.AbstractWidget.extend({
+		defaults: {
+			title: "",
+			help: null,
+			body: null,
+			open: false
+		},
+		init: function() {
+			this._super();
+			this.el = $.joey( this._main_template() );
+			this.body = this.el.children(".uiSidebarSection-body");
+			this.config.open && ( this.el.addClass("shown") && this.body.css("display", "block") );
+		},
+		_showSection_handler: function( ev ) {
+			var shown = $( ev.target ).closest(".uiSidebarSection")
+				.toggleClass("shown")
+					.children(".uiSidebarSection-body").slideToggle(200, function() { this.fire("animComplete", this); }.bind(this))
+				.end()
+				.hasClass("shown");
+			this.fire(shown ? "show" : "hide", this);
+		},
+		_showHelp_handler: function( ev ) {
+			new ui.HelpPanel({ref: this.config.help});
+			ev.stopPropagation();
+		},
+		_main_template: function() { return (
+			{ tag: "DIV", cls: "uiSidebarSection", children: [
+				(this.config.title && { tag: "DIV", cls: "uiSidebarSection-head", onclick: this._showSection_handler, children: [
+					this.config.title,
+					( this.config.help && { tag: "SPAN", cls: "uiSidebarSection-help pull-right", onclick: this._showHelp_handler, text: i18n.text("General.HelpGlyph") } )
+				] }),
+				{ tag: "DIV", cls: "uiSidebarSection-body", children: [ this.config.body ] }
+			] }
+		); }
+	});
+
+})( this.jQuery, this.app, this.i18n );
+
+(function( $, app ) {
+
+	var ui = app.ns("ui");
+
+	ui.ResultTable = ui.Table.extend({
+		defaults: {
+			width: 500,
+			height: 400
+		},
+
+		init: function() {
+			this._super();
+			this.on("rowClick", this._showPreview_handler);
+			this.selectedRow = null;
+			$(document).bind("keydown", this._nav_handler);
+		},
+		remove: function() {
+			$(document).unbind("keydown", this._nav_handler);
+			this._super();
+		},
+		attach: function(parent) {
+			if(parent) {
+				var height = parent.height() || ( $(document).height() - parent.offset().top - 41 ); // 41 = height in px of .uiTable-tools + uiTable-header
+				var width = parent.width();
+				this.el.width( width );
+				this.body.width( width ).height( height );
+			}
+			this._super(parent);
+		},
+		showPreview: function(row) {
+			row.addClass("selected");
+			this.preview = new app.ui.JsonPanel({
+				title: i18n.text("Browser.ResultSourcePanelTitle"),
+				json: row.data("row")._source,
+				onClose: function() { row.removeClass("selected"); }
+			});
+		},
+		_nav_handler: function(jEv) {
+			if(jEv.keyCode !== 40 && jEv.keyCode !== 38) {
+				return;
+			}
+			this.selectedRow && this.preview && this.preview.remove();
+			if(jEv.keyCode === 40) { // up arrow
+				this.selectedRow = this.selectedRow ? this.selectedRow.next("TR") : this.body.find("TR:first");
+			} else if(jEv.keyCode === 38) { // down arrow
+				this.selectedRow = this.selectedRow ? this.selectedRow.prev("TR") : this.body.find("TR:last");
+			}
+			this.selectedRow && this.showPreview(this.selectedRow);
+		},
+		_showPreview_handler: function(obj, data) {
+			this.showPreview(this.selectedRow = data.row);
+		}
+	});
+
+})( this.jQuery, this.app );
+
+(function( $, app, i18n ) {
+
+	var ui = app.ns("ui");
+	var ut = app.ns("ut");
+
+	ui.QueryFilter = ui.AbstractWidget.extend({
+		defaults: {
+			metadata: null,   // (required) instanceof app.data.MetaData
+			query: null       // (required) instanceof app.data.Query that the filters will act apon
+		},
+		init: function() {
+			this._super();
+			this.metadata = this.config.metadata;
+			this.query = this.config.query;
+			this.el = $(this._main_template());
+		},
+		helpTypeMap: {
+			"date" : "QueryFilter.DateRangeHelp"
+		},
+		requestUpdate: function(jEv) {
+			if(jEv && jEv.originalEvent) { // we only want to update on real user interaction not generated events
+				this.query.setPage(1);
+				this.query.query();
+			}
+		},
+		getSpec: function(fieldName) {
+			var fieldNameParts = fieldName.split('.');
+			var namePart = 0;
+			var spec = this.metadata.fields[fieldNameParts[namePart]];
+			while (typeof spec.fields !== "undefined") {
+				namePart++;
+				if (typeof spec.fields[fieldNameParts[namePart]] === "undefined") {
+					break;
+				}
+				spec =  spec.fields[fieldNameParts[namePart]];
+			}
+			return spec;
+		},
+		_selectAlias_handler: function(jEv) {
+			var indices = (jEv.target.selectedIndex === 0) ? [] : this.metadata.getIndices($(jEv.target).val());
+			$(".uiQueryFilter-index").each(function(i, el) {
+				var jEl = $(el);
+				if(indices.contains(jEl.text()) !== jEl.hasClass("selected")) {
+					jEl.click();
+				}
+			});
+			this.requestUpdate(jEv);
+		},
+		_selectIndex_handler: function(jEv) {
+			var jEl = $(jEv.target).closest(".uiQueryFilter-index");
+			jEl.toggleClass("selected");
+			var selected = jEl.hasClass("selected");
+			this.query.setIndex(jEl.text(), selected);
+			if(selected) {
+				var types = this.metadata.getTypes(this.query.indices);
+				this.el.find("DIV.uiQueryFilter-type.selected").each(function(n, el) {
+					if(! types.contains($(el).text())) {
+						$(el).click();
+					}
+				});
+			}
+			this.requestUpdate(jEv);
+		},
+		_selectType_handler: function(jEv) {
+			var jEl = $(jEv.target).closest(".uiQueryFilter-type");
+			jEl.toggleClass("selected");
+			var type = jEl.text(), selected = jEl.hasClass("selected");
+			this.query.setType(type, selected);
+			if(selected) {
+				var indices = this.metadata.types[type].indices;
+				// es throws a 500 if searching an index for a type it does not contain - so we prevent that
+				this.el.find("DIV.uiQueryFilter-index.selected").each(function(n, el) {
+					if(! indices.contains($(el).text())) {
+						$(el).click();
+					}
+				});
+				// es throws a 500 if you specify types from different indices with _all
+				jEl.siblings(".uiQueryFilter-type.selected").forEach(function(el) {
+					if(this.metadata.types[$(el).text()].indices.intersection(indices).length === 0) {
+						$(el).click();
+					}
+				}, this);
+			}
+			this.requestUpdate(jEv);
+		},
+		_openFilter_handler: function(section) {
+			var field_name = section.config.title;
+			if(! section.loaded) {
+				var spec = this.getSpec(field_name);
+				if(spec.core_type === "string") {
+					section.body.append(this._textFilter_template(spec));
+				} else if(spec.core_type === "date") {
+					section.body.append(this._dateFilter_template(spec));
+					section.body.append(new ui.DateHistogram({ printEl: section.body.find("INPUT"), cluster: this.cluster, query: this.query, spec: spec }));
+				} else if(spec.core_type === "number") {
+					section.body.append(this._numericFilter_template(spec));
+				} else if(spec.core_type === 'boolean') {
+					section.body.append(this._booleanFilter_template(spec));
+				} else if (spec.core_type === 'multi_field') {
+					section.body.append(this._multiFieldFilter_template(section, spec));
+				} 
+				section.loaded = true;
+			}
+			section.on("animComplete", function(section) { section.body.find("INPUT").focus(); });
+		},
+		_textFilterChange_handler: function(jEv) {
+			var jEl = $(jEv.target).closest("INPUT");
+			var val = jEl.val();
+			var spec = jEl.data("spec");
+			var uqids = jEl.data("uqids") || [];
+			uqids.forEach(function(uqid) {
+				uqid && this.query.removeClause(uqid);
+			}, this);
+			if(val.length) {
+				if(jEl[0] === document.activeElement && jEl[0].selectionStart === jEl[0].selectionEnd) {
+					val = val.replace(new RegExp("(.{"+jEl[0].selectionStart+"})"), "$&*");
+				}
+				uqids = val.split(/\s+/).map(function(term) {
+					// Figure out the actual field name - needed for multi_field, because
+					// querying for "field.field" will not work. Simply "field" must be used
+					// if nothing is aliased.
+					var fieldNameParts = spec.field_name.split('.');
+					var part = fieldNameParts.length - 1;
+					var name = fieldNameParts[part];
+					while (part >= 1) {
+						if (fieldNameParts[part] !== fieldNameParts[part - 1]) {
+							name = fieldNameParts[part - 1] + "." + name;
+						}
+						part--;
+					}
+					return term && this.query.addClause(term, name, "wildcard", "must");
+				}, this);
+			}
+			jEl.data("uqids", uqids);
+			this.requestUpdate(jEv);
+		},
+		_dateFilterChange_handler: function(jEv) {
+			var jEl = $(jEv.target).closest("INPUT");
+			var val = jEl.val();
+			var spec = jEl.data("spec");
+			var uqid = jEl.data("uqid") || null;
+			var range = window.dateRangeParser.parse(val);
+			var lastRange = jEl.data("lastRange");
+			if(!range || (lastRange && lastRange.start === range.start && lastRange.end === range.end)) {
+				return;
+			}
+			uqid && this.query.removeClause(uqid);
+			if((range.start && range.end) === null) {
+				uqid = null;
+			} else {
+				var value = {};
+				if( range.start ) {
+					value["gte"] = range.start;
+				}
+				if( range.end ) {
+					value["lte"] = range.end;
+				}
+				uqid = this.query.addClause( value, spec.field_name, "range", "must");
+			}
+			jEl.data("lastRange", range);
+			jEl.siblings(".uiQueryFilter-rangeHintFrom")
+				.text(i18n.text("QueryFilter.DateRangeHint.from", range.start && new Date(range.start).toUTCString()));
+			jEl.siblings(".uiQueryFilter-rangeHintTo")
+				.text(i18n.text("QueryFilter.DateRangeHint.to", range.end && new Date(range.end).toUTCString()));
+			jEl.data("uqid", uqid);
+			this.requestUpdate(jEv);
+		},
+		_numericFilterChange_handler: function(jEv) {
+			var jEl = $(jEv.target).closest("INPUT");
+			var val = jEl.val();
+			var spec = jEl.data("spec");
+			var uqid = jEl.data("uqid") || null;
+			var lastRange = jEl.data("lastRange");
+			var range = (function(val) {
+				var ops = val.split(/->|<>|</).map( function(v) { return parseInt(v.trim(), 10); });
+				if(/<>/.test(val)) {
+					return { gte: (ops[0] - ops[1]), lte: (ops[0] + ops[1]) };
+				} else if(/->|</.test(val)) {
+					return { gte: ops[0], lte: ops[1] };
+				} else {
+					return { gte: ops[0], lte: ops[0] };
+				}
+			})(val || "");
+			if(!range || (lastRange && lastRange.lte === range.lte && lastRange.gte === range.gte)) {
+				return;
+			}
+			jEl.data("lastRange", range);
+			uqid && this.query.removeClause(uqid);
+			uqid = this.query.addClause( range, spec.field_name, "range", "must");
+			jEl.data("uqid", uqid);
+			this.requestUpdate(jEv);
+		},
+		_booleanFilterChange_handler: function( jEv ) {
+			var jEl = $(jEv.target).closest("SELECT");
+			var val = jEl.val();
+			var spec = jEl.data("spec");
+			var uqid = jEl.data("uqid") || null;
+			uqid && this.query.removeClause(uqid);
+			if(val === "true" || val === "false") {
+				jEl.data("uqid", this.query.addClause(val, spec.field_name, "term", "must") );
+			}
+			this.requestUpdate(jEv);
+		},
+		_main_template: function() {
+			return { tag: "DIV", id: this.id(), cls: "uiQueryFilter", children: [
+				this._aliasSelector_template(),
+				this._indexSelector_template(),
+				this._typesSelector_template(),
+				this._filters_template()
+			] };
+		},
+		_aliasSelector_template: function() {
+			var aliases = Object.keys(this.metadata.aliases).sort();
+			aliases.unshift( i18n.text("QueryFilter.AllIndices") );
+			return { tag: "DIV", cls: "uiQueryFilter-section uiQueryFilter-aliases", children: [
+				{ tag: "SELECT", onChange: this._selectAlias_handler, children: aliases.map(ut.option_template) }
+			] };
+		},
+		_indexSelector_template: function() {
+			var indices = Object.keys( this.metadata.indices ).sort();
+			return { tag: "DIV", cls: "uiQueryFilter-section uiQueryFilter-indices", children: [
+				{ tag: "HEADER", text: i18n.text("QueryFilter-Header-Indices") },
+				{ tag: "DIV", onClick: this._selectIndex_handler, children: indices.map( function( name ) {
+					return { tag: "DIV", cls: "uiQueryFilter-booble uiQueryFilter-index", text: name };
+				})}
+			] };
+		},
+		_typesSelector_template: function() {
+			var types = Object.keys( this.metadata.types ).sort();
+			return { tag: "DIV", cls: "uiQueryFilter-section uiQueryFilter-types", children: [
+				{ tag: "HEADER", text: i18n.text("QueryFilter-Header-Types") },
+				{ tag: "DIV", onClick: this._selectType_handler, children: types.map( function( name ) {
+					return { tag: "DIV", cls: "uiQueryFilter-booble uiQueryFilter-type", text: name };
+				})}
+			] };
+		},
+		_filters_template: function() {
+			var fields = Object.keys( this.metadata.fields ).sort();
+			return { tag: "DIV", cls: "uiQueryFilter-section uiQueryFilter-filters", children: [
+				{ tag: "HEADER", text: i18n.text("QueryFilter-Header-Fields") },
+				{ tag: "DIV", children: fields.map( function(name ) {
+					return new app.ui.SidebarSection({
+						title: name,
+						help: this.helpTypeMap[this.metadata.fields[ name ].type],
+						onShow: this._openFilter_handler
+					});
+				}, this ) }
+			] };
+		},
+		_textFilter_template: function(spec) {
+			return { tag: "INPUT", data: { spec: spec }, onKeyup: this._textFilterChange_handler };
+		},
+		_dateFilter_template: function(spec) {
+			return { tag: "DIV", children: [
+				{ tag: "INPUT", data: { spec: spec }, onKeyup: this._dateFilterChange_handler },
+				{ tag: "PRE", cls: "uiQueryFilter-rangeHintFrom", text: i18n.text("QueryFilter.DateRangeHint.from", "")},
+				{ tag: "PRE", cls: "uiQueryFilter-rangeHintTo", text: i18n.text("QueryFilter.DateRangeHint.to", "") }
+			]};
+		},
+		_numericFilter_template: function(spec) {
+			return { tag: "INPUT", data: { spec: spec }, onKeyup: this._numericFilterChange_handler };
+		},
+		_booleanFilter_template: function(spec) {
+			return { tag: "SELECT", data: { spec: spec }, onChange: this._booleanFilterChange_handler,
+				children: [ i18n.text("QueryFilter.AnyValue"), "true", "false" ].map( function( val ) {
+					return { tag: "OPTION", value: val, text: val };
+				})
+			};
+		},
+		_multiFieldFilter_template: function(section, spec) {
+			return {
+				tag : "DIV", cls : "uiQueryFilter-subMultiFields", children : acx.eachMap(spec.fields, function(name, data) {
+					if (name === spec.field_name) {
+						section.config.title = spec.field_name + "." + name;
+						return this._openFilter_handler(section);
+					}
+					return new app.ui.SidebarSection({
+						title : data.field_name, help : this.helpTypeMap[data.type], onShow : this._openFilter_handler
+					});
+				}, this)
+			};
+		}	
+	});
+
+})( this.jQuery, this.app, this.i18n );
+
+(function( app ) {
+
+	var ui = app.ns("ui");
+
+	ui.Page = ui.AbstractWidget.extend({
+		show: function() {
+			this.el.show();
+		},
+		hide: function() {
+			this.el.hide();
+		}
+	});
+
+})( this.app );
+(function( $, app, i18n ){
+
+	var ui = app.ns("ui");
+	var data = app.ns("data");
+
+	ui.Browser = ui.Page.extend({
+		defaults: {
+			cluster: null  // (required) instanceof app.services.Cluster
+		},
+		init: function() {
+			this._super();
+			this.cluster = this.config.cluster;
+			this.query = new app.data.Query( { cluster: this.cluster } );
+			this._refreshButton = new ui.Button({
+				label: i18n.text("General.RefreshResults"),
+				onclick: function( btn ) {
+					this.query.query();
+				}.bind(this)
+			});
+			this.el = $(this._main_template());
+			new data.MetaDataFactory({
+				cluster: this.cluster,
+				onReady: function(metadata) {
+					this.metadata = metadata;
+					this.store = new data.QueryDataSourceInterface( { metadata: metadata, query: this.query } );
+					this.queryFilter = new ui.QueryFilter({ metadata: metadata, query: this.query });
+					this.queryFilter.attach(this.el.find("> .uiBrowser-filter") );
+					this.resultTable = new ui.ResultTable( {
+						onHeaderClick: this._changeSort_handler,
+						store: this.store
+					} );
+					this.resultTable.attach( this.el.find("> .uiBrowser-table") );
+					this.updateResults();
+				}.bind(this)
+			});
+		},
+		updateResults: function() {
+			this.query.query();
+		},
+		_changeSort_handler: function(table, wEv) {
+			this.query.setSort(wEv.column, wEv.dir === "desc");
+			this.query.setPage(1);
+			this.query.query();
+		},
+		_main_template: function() {
+			return { tag: "DIV", cls: "uiBrowser", children: [
+				new ui.Toolbar({
+					label: i18n.text("Browser.Title"),
+					left: [ ],
+					right: [ this._refreshButton ]
+				}),
+				{ tag: "DIV", cls: "uiBrowser-filter" },
+				{ tag: "DIV", cls: "uiBrowser-table" }
+			] };
+		}
+	});
+
+})( this.jQuery, this.app, this.i18n );
+
+(function( $, app, i18n, raphael ) {
+
+	var ui = app.ns("ui");
+	var ut = app.ns("ut");
+	var services = app.ns("services");
+
+	ui.AnyRequest = ui.Page.extend({
+		defaults: {
+			cluster: null,       // (required) instanceof app.services.Cluster
+			path: "_search",     // default uri to send a request to
+			query: { query: { match_all: { }}},
+			transform: "  return root;" // default transformer function (does nothing)
+		},
+		init: function(parent) {
+			this._super();
+			this.prefs = services.Preferences.instance();
+			this.history = this.prefs.get("anyRequest-history") || [ { type: "POST", path: this.config.path, query : JSON.stringify(this.config.query), transform: this.config.transform } ];
+			this.el = $.joey(this._main_template());
+			this.base_uriEl = this.el.find("INPUT[name=base_uri]");
+			this.pathEl = this.el.find("INPUT[name=path]");
+			this.typeEl = this.el.find("SELECT[name=method]");
+			this.dataEl = this.el.find("TEXTAREA[name=body]");
+			this.prettyEl = this.el.find("INPUT[name=pretty]");
+			this.transformEl = this.el.find("TEXTAREA[name=transform]");
+			this.asGraphEl = this.el.find("INPUT[name=asGraph]");
+			this.asTableEl = this.el.find("INPUT[name=asTable]");
+			this.asJsonEl = this.el.find("INPUT[name=asJson]");
+			this.cronEl = this.el.find("SELECT[name=cron]");
+			this.outEl = this.el.find("DIV.uiAnyRequest-out");
+			this.errEl = this.el.find("DIV.uiAnyRequest-jsonErr");
+			this.typeEl.val("GET");
+			this.attach(parent);
+			this.setHistoryItem(this.history[this.history.length - 1]);
+		},
+		setHistoryItem: function(item) {
+			this.pathEl.val(item.path);
+			this.typeEl.val(item.type);
+			this.dataEl.val(item.query);
+			this.transformEl.val(item.transform);
+		},
+		_request_handler: function( ev ) {
+			if(! this._validateJson_handler()) {
+				return;
+			}
+			var path = this.pathEl.val(),
+					type = this.typeEl.val(),
+					query = JSON.stringify(JSON.parse(this.dataEl.val())),
+					transform = this.transformEl.val(),
+					base_uri = this.base_uriEl.val();
+			if( ev ) { // if the user click request
+				if(this.timer) {
+					window.clearTimeout(this.timer); // stop any cron jobs
+				}
+				delete this.prevData; // remove data from previous cron runs
+				this.outEl.text(i18n.text("AnyRequest.Requesting"));
+				if( ! /\/$/.test( base_uri )) {
+					base_uri += "/";
+					this.base_uriEl.val( base_uri );
+				}
+				for(var i = 0; i < this.history.length; i++) {
+					if(this.history[i].path === path &&
+						this.history[i].type === type &&
+						this.history[i].query === query &&
+						this.history[i].transform === transform) {
+						this.history.splice(i, 1);
+					}
+				}
+				this.history.push({
+					path: path,
+					type: type,
+					query: query,
+					transform: transform
+				});
+				this.history.slice(250); // make sure history does not get too large
+				this.prefs.set( "anyRequest-history", this.history );
+				this.el.find("UL.uiAnyRequest-history")
+					.empty()
+					.append($( { tag: "UL", children: this.history.map(this._historyItem_template, this) }).children())
+					.children().find(":last-child").each(function(i, j) { j.scrollIntoView(false); }).end()
+					.scrollLeft(0);
+			}
+			this.config.cluster.request({
+				url: base_uri + path,
+				type: type,
+				data: query,
+				success: this._responseWriter_handler,
+				error: this._responseError_handler
+			});
+		},
+		_responseError_handler: function (response) {
+			var obj;
+			try {
+				obj = JSON.parse(response.responseText);
+				if (obj) {
+					this._responseWriter_handler(obj);
+				}
+			} catch (err) {
+			}
+		},
+		_responseWriter_handler: function(data) {
+			this.outEl.empty();
+			try {
+				data = (new Function("root", "prev", this.transformEl.val()))(data, this.

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/base/favicon.png
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/base/favicon.png b/elasticsearch-head/src/main/resources/base/favicon.png
new file mode 100644
index 0000000..f433ec6
Binary files /dev/null and b/elasticsearch-head/src/main/resources/base/favicon.png differ


[2/7] karaf-decanter git commit: [KARAF-3904] Add elasticsearch-head feature

Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/vendor.js
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/vendor.js b/elasticsearch-head/src/main/resources/vendor.js
new file mode 100644
index 0000000..bf75939
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/vendor.js
@@ -0,0 +1,14500 @@
+/*!
+ * jQuery JavaScript Library v1.6.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu May 12 15:04:36 2011 -0400
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document,
+	navigator = window.navigator,
+	location = window.location;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		return new jQuery.fn.init( selector, context, rootjQuery );
+	},
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// A simple way to check for HTML strings or ID strings
+	// (both of which we optimize for)
+	quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+	// Check if a string has a non-whitespace character in it
+	rnotwhite = /\S/,
+
+	// Used for trimming whitespace
+	trimLeft = /^\s+/,
+	trimRight = /\s+$/,
+
+	// Check for digits
+	rdigit = /\d/,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+	// JSON RegExp
+	rvalidchars = /^[\],:{}\s]*$/,
+	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+	// Useragent RegExp
+	rwebkit = /(webkit)[ \/]([\w.]+)/,
+	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+	rmsie = /(msie) ([\w.]+)/,
+	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+	// Keep a UserAgent string for use with jQuery.browser
+	userAgent = navigator.userAgent,
+
+	// For matching the engine and version of the browser
+	browserMatch,
+
+	// The deferred used on DOM ready
+	readyList,
+
+	// The ready event handler
+	DOMContentLoaded,
+
+	// Save a reference to some core methods
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	push = Array.prototype.push,
+	slice = Array.prototype.slice,
+	trim = String.prototype.trim,
+	indexOf = Array.prototype.indexOf,
+
+	// [[Class]] -> type pairs
+	class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+	constructor: jQuery,
+	init: function( selector, context, rootjQuery ) {
+		var match, elem, ret, doc;
+
+		// Handle $(""), $(null), or $(undefined)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+
+		// The body element only exists once, optimize finding it
+		if ( selector === "body" && !context && document.body ) {
+			this.context = document;
+			this[0] = document.body;
+			this.selector = selector;
+			this.length = 1;
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			// Are we dealing with HTML string or an ID?
+			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+				// Assume that strings that start and end with <> are HTML and skip the regex check
+				match = [ null, selector, null ];
+
+			} else {
+				match = quickExpr.exec( selector );
+			}
+
+			// Verify a match, and that no context was specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					context = context instanceof jQuery ? context[0] : context;
+					doc = (context ? context.ownerDocument || context : document);
+
+					// If a single string is passed in and it's a single tag
+					// just do a createElement and skip the rest
+					ret = rsingleTag.exec( selector );
+
+					if ( ret ) {
+						if ( jQuery.isPlainObject( context ) ) {
+							selector = [ document.createElement( ret[1] ) ];
+							jQuery.fn.attr.call( selector, context, true );
+
+						} else {
+							selector = [ doc.createElement( ret[1] ) ];
+						}
+
+					} else {
+						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+						selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
+					}
+
+					return jQuery.merge( this, selector );
+
+				// HANDLE: $("#id")
+				} else {
+					elem = document.getElementById( match[2] );
+
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return (context || rootjQuery).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return this.constructor( context ).find( selector );
+			}
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if (selector.selector !== undefined) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
+
+	// Start with an empty selector
+	selector: "",
+
+	// The current version of jQuery being used
+	jquery: "1.6.1",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
+	toArray: function() {
+		return slice.call( this, 0 );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this[ this.length + num ] : this[ num ] );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems, name, selector ) {
+		// Build a new jQuery matched element set
+		var ret = this.constructor();
+
+		if ( jQuery.isArray( elems ) ) {
+			push.apply( ret, elems );
+
+		} else {
+			jQuery.merge( ret, elems );
+		}
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+
+		ret.context = this.context;
+
+		if ( name === "find" ) {
+			ret.selector = this.selector + (this.selector ? " " : "") + selector;
+		} else if ( name ) {
+			ret.selector = this.selector + "." + name + "(" + selector + ")";
+		}
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+
+	ready: function( fn ) {
+		// Attach the listeners
+		jQuery.bindReady();
+
+		// Add the callback
+		readyList.done( fn );
+
+		return this;
+	},
+
+	eq: function( i ) {
+		return i === -1 ?
+			this.slice( i ) :
+			this.slice( i, +i + 1 );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	slice: function() {
+		return this.pushStack( slice.apply( this, arguments ),
+			"slice", slice.call(arguments).join(",") );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+
+	end: function() {
+		return this.prevObject || this.constructor(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: push,
+	sort: [].sort,
+	splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+	var options, name, src, copy, copyIsArray, clone,
+		target = arguments[0] || {},
+		i = 1,
+		length = arguments.length,
+		deep = false;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && jQuery.isArray(src) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject(src) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	noConflict: function( deep ) {
+		if ( window.$ === jQuery ) {
+			window.$ = _$;
+		}
+
+		if ( deep && window.jQuery === jQuery ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+
+	// Hold (or release) the ready event
+	holdReady: function( hold ) {
+		if ( hold ) {
+			jQuery.readyWait++;
+		} else {
+			jQuery.ready( true );
+		}
+	},
+
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+		// Either a released hold or an DOMready/load event and not yet ready
+		if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
+			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+			if ( !document.body ) {
+				return setTimeout( jQuery.ready, 1 );
+			}
+
+			// Remember that the DOM is ready
+			jQuery.isReady = true;
+
+			// If a normal DOM Ready event fired, decrement, and wait if need be
+			if ( wait !== true && --jQuery.readyWait > 0 ) {
+				return;
+			}
+
+			// If there are functions bound, to execute
+			readyList.resolveWith( document, [ jQuery ] );
+
+			// Trigger any bound ready events
+			if ( jQuery.fn.trigger ) {
+				jQuery( document ).trigger( "ready" ).unbind( "ready" );
+			}
+		}
+	},
+
+	bindReady: function() {
+		if ( readyList ) {
+			return;
+		}
+
+		readyList = jQuery._Deferred();
+
+		// Catch cases where $(document).ready() is called after the
+		// browser event has already occurred.
+		if ( document.readyState === "complete" ) {
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
+			return setTimeout( jQuery.ready, 1 );
+		}
+
+		// Mozilla, Opera and webkit nightlies currently support this event
+		if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", jQuery.ready, false );
+
+		// If IE event model is used
+		} else if ( document.attachEvent ) {
+			// ensure firing before onload,
+			// maybe late but safe also for iframes
+			document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", jQuery.ready );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var toplevel = false;
+
+			try {
+				toplevel = window.frameElement == null;
+			} catch(e) {}
+
+			if ( document.documentElement.doScroll && toplevel ) {
+				doScrollCheck();
+			}
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return jQuery.type(obj) === "function";
+	},
+
+	isArray: Array.isArray || function( obj ) {
+		return jQuery.type(obj) === "array";
+	},
+
+	// A crude way of determining if an object is a window
+	isWindow: function( obj ) {
+		return obj && typeof obj === "object" && "setInterval" in obj;
+	},
+
+	isNaN: function( obj ) {
+		return obj == null || !rdigit.test( obj ) || isNaN( obj );
+	},
+
+	type: function( obj ) {
+		return obj == null ?
+			String( obj ) :
+			class2type[ toString.call(obj) ] || "object";
+	},
+
+	isPlainObject: function( obj ) {
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+			return false;
+		}
+
+		// Not own constructor property must be Object
+		if ( obj.constructor &&
+			!hasOwn.call(obj, "constructor") &&
+			!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+			return false;
+		}
+
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+
+		var key;
+		for ( key in obj ) {}
+
+		return key === undefined || hasOwn.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		for ( var name in obj ) {
+			return false;
+		}
+		return true;
+	},
+
+	error: function( msg ) {
+		throw msg;
+	},
+
+	parseJSON: function( data ) {
+		if ( typeof data !== "string" || !data ) {
+			return null;
+		}
+
+		// Make sure leading/trailing whitespace is removed (IE can't handle it)
+		data = jQuery.trim( data );
+
+		// Attempt to parse using the native JSON parser first
+		if ( window.JSON && window.JSON.parse ) {
+			return window.JSON.parse( data );
+		}
+
+		// Make sure the incoming data is actual JSON
+		// Logic borrowed from http://json.org/json2.js
+		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+			.replace( rvalidtokens, "]" )
+			.replace( rvalidbraces, "")) ) {
+
+			return (new Function( "return " + data ))();
+
+		}
+		jQuery.error( "Invalid JSON: " + data );
+	},
+
+	// Cross-browser xml parsing
+	// (xml & tmp used internally)
+	parseXML: function( data , xml , tmp ) {
+
+		if ( window.DOMParser ) { // Standard
+			tmp = new DOMParser();
+			xml = tmp.parseFromString( data , "text/xml" );
+		} else { // IE
+			xml = new ActiveXObject( "Microsoft.XMLDOM" );
+			xml.async = "false";
+			xml.loadXML( data );
+		}
+
+		tmp = xml.documentElement;
+
+		if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
+			jQuery.error( "Invalid XML: " + data );
+		}
+
+		return xml;
+	},
+
+	noop: function() {},
+
+	// Evaluates a script in a global context
+	// Workarounds based on findings by Jim Driscoll
+	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+	globalEval: function( data ) {
+		if ( data && rnotwhite.test( data ) ) {
+			// We use execScript on Internet Explorer
+			// We use an anonymous function so that context is window
+			// rather than jQuery in Firefox
+			( window.execScript || function( data ) {
+				window[ "eval" ].call( window, data );
+			} )( data );
+		}
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+	},
+
+	// args is for internal usage only
+	each: function( object, callback, args ) {
+		var name, i = 0,
+			length = object.length,
+			isObj = length === undefined || jQuery.isFunction( object );
+
+		if ( args ) {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.apply( object[ name ], args ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.apply( object[ i++ ], args ) === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return object;
+	},
+
+	// Use native String.trim function wherever possible
+	trim: trim ?
+		function( text ) {
+			return text == null ?
+				"" :
+				trim.call( text );
+		} :
+
+		// Otherwise use our own trimming functionality
+		function( text ) {
+			return text == null ?
+				"" :
+				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+		},
+
+	// results is for internal usage only
+	makeArray: function( array, results ) {
+		var ret = results || [];
+
+		if ( array != null ) {
+			// The window, strings (and functions) also have 'length'
+			// The extra typeof function check is to prevent crashes
+			// in Safari 2 (See: #3039)
+			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+			var type = jQuery.type( array );
+
+			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+				push.call( ret, array );
+			} else {
+				jQuery.merge( ret, array );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, array ) {
+
+		if ( indexOf ) {
+			return indexOf.call( array, elem );
+		}
+
+		for ( var i = 0, length = array.length; i < length; i++ ) {
+			if ( array[ i ] === elem ) {
+				return i;
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var i = first.length,
+			j = 0;
+
+		if ( typeof second.length === "number" ) {
+			for ( var l = second.length; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var ret = [], retVal;
+		inv = !!inv;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			retVal = !!callback( elems[ i ], i );
+			if ( inv !== retVal ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var value, key, ret = [],
+			i = 0,
+			length = elems.length,
+			// jquery objects are treated as arrays
+			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
+
+		// Go through the array, translating each of the items to their
+		if ( isArray ) {
+			for ( ; i < length; i++ ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+
+		// Go through every key on the object,
+		} else {
+			for ( key in elems ) {
+				value = callback( elems[ key ], key, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+		}
+
+		// Flatten any nested arrays
+		return ret.concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	// Bind a function to a context, optionally partially applying any
+	// arguments.
+	proxy: function( fn, context ) {
+		if ( typeof context === "string" ) {
+			var tmp = fn[ context ];
+			context = fn;
+			fn = tmp;
+		}
+
+		// Quick check to determine if target is callable, in the spec
+		// this throws a TypeError, but we will just return undefined.
+		if ( !jQuery.isFunction( fn ) ) {
+			return undefined;
+		}
+
+		// Simulated bind
+		var args = slice.call( arguments, 2 ),
+			proxy = function() {
+				return fn.apply( context, args.concat( slice.call( arguments ) ) );
+			};
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+
+		return proxy;
+	},
+
+	// Mutifunctional method to get and set values to a collection
+	// The value/s can be optionally by executed if its a function
+	access: function( elems, key, value, exec, fn, pass ) {
+		var length = elems.length;
+
+		// Setting many attributes
+		if ( typeof key === "object" ) {
+			for ( var k in key ) {
+				jQuery.access( elems, k, key[k], exec, fn, value );
+			}
+			return elems;
+		}
+
+		// Setting one attribute
+		if ( value !== undefined ) {
+			// Optionally, function values get executed if exec is true
+			exec = !pass && exec && jQuery.isFunction(value);
+
+			for ( var i = 0; i < length; i++ ) {
+				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+			}
+
+			return elems;
+		}
+
+		// Getting an attribute
+		return length ? fn( elems[0], key ) : undefined;
+	},
+
+	now: function() {
+		return (new Date()).getTime();
+	},
+
+	// Use of jQuery.browser is frowned upon.
+	// More details: http://docs.jquery.com/Utilities/jQuery.browser
+	uaMatch: function( ua ) {
+		ua = ua.toLowerCase();
+
+		var match = rwebkit.exec( ua ) ||
+			ropera.exec( ua ) ||
+			rmsie.exec( ua ) ||
+			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+			[];
+
+		return { browser: match[1] || "", version: match[2] || "0" };
+	},
+
+	sub: function() {
+		function jQuerySub( selector, context ) {
+			return new jQuerySub.fn.init( selector, context );
+		}
+		jQuery.extend( true, jQuerySub, this );
+		jQuerySub.superclass = this;
+		jQuerySub.fn = jQuerySub.prototype = this();
+		jQuerySub.fn.constructor = jQuerySub;
+		jQuerySub.sub = this.sub;
+		jQuerySub.fn.init = function init( selector, context ) {
+			if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+				context = jQuerySub( context );
+			}
+
+			return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+		};
+		jQuerySub.fn.init.prototype = jQuerySub.fn;
+		var rootjQuerySub = jQuerySub(document);
+		return jQuerySub;
+	},
+
+	browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+	jQuery.browser[ browserMatch.browser ] = true;
+	jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+	jQuery.browser.safari = true;
+}
+
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
+	trimLeft = /^[\s\xA0]+/;
+	trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+	DOMContentLoaded = function() {
+		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+		jQuery.ready();
+	};
+
+} else if ( document.attachEvent ) {
+	DOMContentLoaded = function() {
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( document.readyState === "complete" ) {
+			document.detachEvent( "onreadystatechange", DOMContentLoaded );
+			jQuery.ready();
+		}
+	};
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+	if ( jQuery.isReady ) {
+		return;
+	}
+
+	try {
+		// If IE is used, use the trick by Diego Perini
+		// http://javascript.nwbox.com/IEContentLoaded/
+		document.documentElement.doScroll("left");
+	} catch(e) {
+		setTimeout( doScrollCheck, 1 );
+		return;
+	}
+
+	// and execute any waiting functions
+	jQuery.ready();
+}
+
+// Expose jQuery to the global object
+return jQuery;
+
+})();
+
+
+var // Promise methods
+	promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
+	// Static reference to slice
+	sliceDeferred = [].slice;
+
+jQuery.extend({
+	// Create a simple deferred (one callbacks list)
+	_Deferred: function() {
+		var // callbacks list
+			callbacks = [],
+			// stored [ context , args ]
+			fired,
+			// to avoid firing when already doing so
+			firing,
+			// flag to know if the deferred has been cancelled
+			cancelled,
+			// the deferred itself
+			deferred  = {
+
+				// done( f1, f2, ...)
+				done: function() {
+					if ( !cancelled ) {
+						var args = arguments,
+							i,
+							length,
+							elem,
+							type,
+							_fired;
+						if ( fired ) {
+							_fired = fired;
+							fired = 0;
+						}
+						for ( i = 0, length = args.length; i < length; i++ ) {
+							elem = args[ i ];
+							type = jQuery.type( elem );
+							if ( type === "array" ) {
+								deferred.done.apply( deferred, elem );
+							} else if ( type === "function" ) {
+								callbacks.push( elem );
+							}
+						}
+						if ( _fired ) {
+							deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
+						}
+					}
+					return this;
+				},
+
+				// resolve with given context and args
+				resolveWith: function( context, args ) {
+					if ( !cancelled && !fired && !firing ) {
+						// make sure args are available (#8421)
+						args = args || [];
+						firing = 1;
+						try {
+							while( callbacks[ 0 ] ) {
+								callbacks.shift().apply( context, args );
+							}
+						}
+						finally {
+							fired = [ context, args ];
+							firing = 0;
+						}
+					}
+					return this;
+				},
+
+				// resolve with this as context and given arguments
+				resolve: function() {
+					deferred.resolveWith( this, arguments );
+					return this;
+				},
+
+				// Has this deferred been resolved?
+				isResolved: function() {
+					return !!( firing || fired );
+				},
+
+				// Cancel
+				cancel: function() {
+					cancelled = 1;
+					callbacks = [];
+					return this;
+				}
+			};
+
+		return deferred;
+	},
+
+	// Full fledged deferred (two callbacks list)
+	Deferred: function( func ) {
+		var deferred = jQuery._Deferred(),
+			failDeferred = jQuery._Deferred(),
+			promise;
+		// Add errorDeferred methods, then and promise
+		jQuery.extend( deferred, {
+			then: function( doneCallbacks, failCallbacks ) {
+				deferred.done( doneCallbacks ).fail( failCallbacks );
+				return this;
+			},
+			always: function() {
+				return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
+			},
+			fail: failDeferred.done,
+			rejectWith: failDeferred.resolveWith,
+			reject: failDeferred.resolve,
+			isRejected: failDeferred.isResolved,
+			pipe: function( fnDone, fnFail ) {
+				return jQuery.Deferred(function( newDefer ) {
+					jQuery.each( {
+						done: [ fnDone, "resolve" ],
+						fail: [ fnFail, "reject" ]
+					}, function( handler, data ) {
+						var fn = data[ 0 ],
+							action = data[ 1 ],
+							returned;
+						if ( jQuery.isFunction( fn ) ) {
+							deferred[ handler ](function() {
+								returned = fn.apply( this, arguments );
+								if ( returned && jQuery.isFunction( returned.promise ) ) {
+									returned.promise().then( newDefer.resolve, newDefer.reject );
+								} else {
+									newDefer[ action ]( returned );
+								}
+							});
+						} else {
+							deferred[ handler ]( newDefer[ action ] );
+						}
+					});
+				}).promise();
+			},
+			// Get a promise for this deferred
+			// If obj is provided, the promise aspect is added to the object
+			promise: function( obj ) {
+				if ( obj == null ) {
+					if ( promise ) {
+						return promise;
+					}
+					promise = obj = {};
+				}
+				var i = promiseMethods.length;
+				while( i-- ) {
+					obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
+				}
+				return obj;
+			}
+		});
+		// Make sure only one callback list will be used
+		deferred.done( failDeferred.cancel ).fail( deferred.cancel );
+		// Unexpose cancel
+		delete deferred.cancel;
+		// Call given func if any
+		if ( func ) {
+			func.call( deferred, deferred );
+		}
+		return deferred;
+	},
+
+	// Deferred helper
+	when: function( firstParam ) {
+		var args = arguments,
+			i = 0,
+			length = args.length,
+			count = length,
+			deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
+				firstParam :
+				jQuery.Deferred();
+		function resolveFunc( i ) {
+			return function( value ) {
+				args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+				if ( !( --count ) ) {
+					// Strange bug in FF4:
+					// Values changed onto the arguments object sometimes end up as undefined values
+					// outside the $.when method. Cloning the object into a fresh array solves the issue
+					deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
+				}
+			};
+		}
+		if ( length > 1 ) {
+			for( ; i < length; i++ ) {
+				if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
+					args[ i ].promise().then( resolveFunc(i), deferred.reject );
+				} else {
+					--count;
+				}
+			}
+			if ( !count ) {
+				deferred.resolveWith( deferred, args );
+			}
+		} else if ( deferred !== firstParam ) {
+			deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
+		}
+		return deferred.promise();
+	}
+});
+
+
+
+jQuery.support = (function() {
+
+	var div = document.createElement( "div" ),
+		documentElement = document.documentElement,
+		all,
+		a,
+		select,
+		opt,
+		input,
+		marginDiv,
+		support,
+		fragment,
+		body,
+		bodyStyle,
+		tds,
+		events,
+		eventName,
+		i,
+		isSupported;
+
+	// Preliminary tests
+	div.setAttribute("className", "t");
+	div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+	all = div.getElementsByTagName( "*" );
+	a = div.getElementsByTagName( "a" )[ 0 ];
+
+	// Can't get basic test support
+	if ( !all || !all.length || !a ) {
+		return {};
+	}
+
+	// First batch of supports tests
+	select = document.createElement( "select" );
+	opt = select.appendChild( document.createElement("option") );
+	input = div.getElementsByTagName( "input" )[ 0 ];
+
+	support = {
+		// IE strips leading whitespace when .innerHTML is used
+		leadingWhitespace: ( div.firstChild.nodeType === 3 ),
+
+		// Make sure that tbody elements aren't automatically inserted
+		// IE will insert them into empty tables
+		tbody: !div.getElementsByTagName( "tbody" ).length,
+
+		// Make sure that link elements get serialized correctly by innerHTML
+		// This requires a wrapper element in IE
+		htmlSerialize: !!div.getElementsByTagName( "link" ).length,
+
+		// Get the style information from getAttribute
+		// (IE uses .cssText instead)
+		style: /top/.test( a.getAttribute("style") ),
+
+		// Make sure that URLs aren't manipulated
+		// (IE normalizes it by default)
+		hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
+
+		// Make sure that element opacity exists
+		// (IE uses filter instead)
+		// Use a regex to work around a WebKit issue. See #5145
+		opacity: /^0.55$/.test( a.style.opacity ),
+
+		// Verify style float existence
+		// (IE uses styleFloat instead of cssFloat)
+		cssFloat: !!a.style.cssFloat,
+
+		// Make sure that if no value is specified for a checkbox
+		// that it defaults to "on".
+		// (WebKit defaults to "" instead)
+		checkOn: ( input.value === "on" ),
+
+		// Make sure that a selected-by-default option has a working selected property.
+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+		optSelected: opt.selected,
+
+		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+		getSetAttribute: div.className !== "t",
+
+		// Will be defined later
+		submitBubbles: true,
+		changeBubbles: true,
+		focusinBubbles: false,
+		deleteExpando: true,
+		noCloneEvent: true,
+		inlineBlockNeedsLayout: false,
+		shrinkWrapBlocks: false,
+		reliableMarginRight: true
+	};
+
+	// Make sure checked status is properly cloned
+	input.checked = true;
+	support.noCloneChecked = input.cloneNode( true ).checked;
+
+	// Make sure that the options inside disabled selects aren't marked as disabled
+	// (WebKit marks them as disabled)
+	select.disabled = true;
+	support.optDisabled = !opt.disabled;
+
+	// Test to see if it's possible to delete an expando from an element
+	// Fails in Internet Explorer
+	try {
+		delete div.test;
+	} catch( e ) {
+		support.deleteExpando = false;
+	}
+
+	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
+		div.attachEvent( "onclick", function click() {
+			// Cloning a node shouldn't copy over any
+			// bound event handlers (IE does this)
+			support.noCloneEvent = false;
+			div.detachEvent( "onclick", click );
+		});
+		div.cloneNode( true ).fireEvent( "onclick" );
+	}
+
+	// Check if a radio maintains it's value
+	// after being appended to the DOM
+	input = document.createElement("input");
+	input.value = "t";
+	input.setAttribute("type", "radio");
+	support.radioValue = input.value === "t";
+
+	input.setAttribute("checked", "checked");
+	div.appendChild( input );
+	fragment = document.createDocumentFragment();
+	fragment.appendChild( div.firstChild );
+
+	// WebKit doesn't clone checked state correctly in fragments
+	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+	div.innerHTML = "";
+
+	// Figure out if the W3C box model works as expected
+	div.style.width = div.style.paddingLeft = "1px";
+
+	// We use our own, invisible, body
+	body = document.createElement( "body" );
+	bodyStyle = {
+		visibility: "hidden",
+		width: 0,
+		height: 0,
+		border: 0,
+		margin: 0,
+		// Set background to avoid IE crashes when removing (#9028)
+		background: "none"
+	};
+	for ( i in bodyStyle ) {
+		body.style[ i ] = bodyStyle[ i ];
+	}
+	body.appendChild( div );
+	documentElement.insertBefore( body, documentElement.firstChild );
+
+	// Check if a disconnected checkbox will retain its checked
+	// value of true after appended to the DOM (IE6/7)
+	support.appendChecked = input.checked;
+
+	support.boxModel = div.offsetWidth === 2;
+
+	if ( "zoom" in div.style ) {
+		// Check if natively block-level elements act like inline-block
+		// elements when setting their display to 'inline' and giving
+		// them layout
+		// (IE < 8 does this)
+		div.style.display = "inline";
+		div.style.zoom = 1;
+		support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
+
+		// Check if elements with layout shrink-wrap their children
+		// (IE 6 does this)
+		div.style.display = "";
+		div.innerHTML = "<div style='width:4px;'></div>";
+		support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
+	}
+
+	div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
+	tds = div.getElementsByTagName( "td" );
+
+	// Check if table cells still have offsetWidth/Height when they are set
+	// to display:none and there are still other visible table cells in a
+	// table row; if so, offsetWidth/Height are not reliable for use when
+	// determining if an element has been hidden directly using
+	// display:none (it is still safe to use offsets if a parent element is
+	// hidden; don safety goggles and see bug #4512 for more information).
+	// (only IE 8 fails this test)
+	isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+	tds[ 0 ].style.display = "";
+	tds[ 1 ].style.display = "none";
+
+	// Check if empty table cells still have offsetWidth/Height
+	// (IE < 8 fail this test)
+	support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+	div.innerHTML = "";
+
+	// Check if div with explicit width and no margin-right incorrectly
+	// gets computed margin-right based on width of container. For more
+	// info see bug #3333
+	// Fails in WebKit before Feb 2011 nightlies
+	// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+	if ( document.defaultView && document.defaultView.getComputedStyle ) {
+		marginDiv = document.createElement( "div" );
+		marginDiv.style.width = "0";
+		marginDiv.style.marginRight = "0";
+		div.appendChild( marginDiv );
+		support.reliableMarginRight =
+			( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
+	}
+
+	// Remove the body element we added
+	body.innerHTML = "";
+	documentElement.removeChild( body );
+
+	// Technique from Juriy Zaytsev
+	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+	// We only care about the case where non-standard event systems
+	// are used, namely in IE. Short-circuiting here helps us to
+	// avoid an eval call (in setAttribute) which can cause CSP
+	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+	if ( div.attachEvent ) {
+		for( i in {
+			submit: 1,
+			change: 1,
+			focusin: 1
+		} ) {
+			eventName = "on" + i;
+			isSupported = ( eventName in div );
+			if ( !isSupported ) {
+				div.setAttribute( eventName, "return;" );
+				isSupported = ( typeof div[ eventName ] === "function" );
+			}
+			support[ i + "Bubbles" ] = isSupported;
+		}
+	}
+
+	return support;
+})();
+
+// Keep track of boxModel
+jQuery.boxModel = jQuery.support.boxModel;
+
+
+
+
+var rbrace = /^(?:\{.*\}|\[.*\])$/,
+	rmultiDash = /([a-z])([A-Z])/g;
+
+jQuery.extend({
+	cache: {},
+
+	// Please use with caution
+	uuid: 0,
+
+	// Unique for each copy of jQuery on the page
+	// Non-digits removed to match rinlinejQuery
+	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
+
+	// The following elements throw uncatchable exceptions if you
+	// attempt to add expando properties to them.
+	noData: {
+		"embed": true,
+		// Ban all objects except for Flash (which handle expandos)
+		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+		"applet": true
+	},
+
+	hasData: function( elem ) {
+		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+
+		return !!elem && !isEmptyDataObject( elem );
+	},
+
+	data: function( elem, name, data, pvt /* Internal Use Only */ ) {
+		if ( !jQuery.acceptData( elem ) ) {
+			return;
+		}
+
+		var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
+
+			// We have to handle DOM nodes and JS objects differently because IE6-7
+			// can't GC object references properly across the DOM-JS boundary
+			isNode = elem.nodeType,
+
+			// Only DOM nodes need the global jQuery cache; JS object data is
+			// attached directly to the object so GC can occur automatically
+			cache = isNode ? jQuery.cache : elem,
+
+			// Only defining an ID for JS objects if its cache already exists allows
+			// the code to shortcut on the same path as a DOM node with no cache
+			id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
+
+		// Avoid doing any more work than we need to when trying to get data on an
+		// object that has no data at all
+		if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
+			return;
+		}
+
+		if ( !id ) {
+			// Only DOM nodes need a new unique ID for each element since their data
+			// ends up in the global cache
+			if ( isNode ) {
+				elem[ jQuery.expando ] = id = ++jQuery.uuid;
+			} else {
+				id = jQuery.expando;
+			}
+		}
+
+		if ( !cache[ id ] ) {
+			cache[ id ] = {};
+
+			// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+			// metadata on plain JS objects when the object is serialized using
+			// JSON.stringify
+			if ( !isNode ) {
+				cache[ id ].toJSON = jQuery.noop;
+			}
+		}
+
+		// An object can be passed to jQuery.data instead of a key/value pair; this gets
+		// shallow copied over onto the existing cache
+		if ( typeof name === "object" || typeof name === "function" ) {
+			if ( pvt ) {
+				cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
+			} else {
+				cache[ id ] = jQuery.extend(cache[ id ], name);
+			}
+		}
+
+		thisCache = cache[ id ];
+
+		// Internal jQuery data is stored in a separate object inside the object's data
+		// cache in order to avoid key collisions between internal data and user-defined
+		// data
+		if ( pvt ) {
+			if ( !thisCache[ internalKey ] ) {
+				thisCache[ internalKey ] = {};
+			}
+
+			thisCache = thisCache[ internalKey ];
+		}
+
+		if ( data !== undefined ) {
+			thisCache[ jQuery.camelCase( name ) ] = data;
+		}
+
+		// TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
+		// not attempt to inspect the internal events object using jQuery.data, as this
+		// internal data object is undocumented and subject to change.
+		if ( name === "events" && !thisCache[name] ) {
+			return thisCache[ internalKey ] && thisCache[ internalKey ].events;
+		}
+
+		return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;
+	},
+
+	removeData: function( elem, name, pvt /* Internal Use Only */ ) {
+		if ( !jQuery.acceptData( elem ) ) {
+			return;
+		}
+
+		var internalKey = jQuery.expando, isNode = elem.nodeType,
+
+			// See jQuery.data for more information
+			cache = isNode ? jQuery.cache : elem,
+
+			// See jQuery.data for more information
+			id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+		// If there is already no cache entry for this object, there is no
+		// purpose in continuing
+		if ( !cache[ id ] ) {
+			return;
+		}
+
+		if ( name ) {
+			var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
+
+			if ( thisCache ) {
+				delete thisCache[ name ];
+
+				// If there is no data left in the cache, we want to continue
+				// and let the cache object itself get destroyed
+				if ( !isEmptyDataObject(thisCache) ) {
+					return;
+				}
+			}
+		}
+
+		// See jQuery.data for more information
+		if ( pvt ) {
+			delete cache[ id ][ internalKey ];
+
+			// Don't destroy the parent cache unless the internal data object
+			// had been the only thing left in it
+			if ( !isEmptyDataObject(cache[ id ]) ) {
+				return;
+			}
+		}
+
+		var internalCache = cache[ id ][ internalKey ];
+
+		// Browsers that fail expando deletion also refuse to delete expandos on
+		// the window, but it will allow it on all other JS objects; other browsers
+		// don't care
+		if ( jQuery.support.deleteExpando || cache != window ) {
+			delete cache[ id ];
+		} else {
+			cache[ id ] = null;
+		}
+
+		// We destroyed the entire user cache at once because it's faster than
+		// iterating through each key, but we need to continue to persist internal
+		// data if it existed
+		if ( internalCache ) {
+			cache[ id ] = {};
+			// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+			// metadata on plain JS objects when the object is serialized using
+			// JSON.stringify
+			if ( !isNode ) {
+				cache[ id ].toJSON = jQuery.noop;
+			}
+
+			cache[ id ][ internalKey ] = internalCache;
+
+		// Otherwise, we need to eliminate the expando on the node to avoid
+		// false lookups in the cache for entries that no longer exist
+		} else if ( isNode ) {
+			// IE does not allow us to delete expando properties from nodes,
+			// nor does it have a removeAttribute function on Document nodes;
+			// we must handle all of these cases
+			if ( jQuery.support.deleteExpando ) {
+				delete elem[ jQuery.expando ];
+			} else if ( elem.removeAttribute ) {
+				elem.removeAttribute( jQuery.expando );
+			} else {
+				elem[ jQuery.expando ] = null;
+			}
+		}
+	},
+
+	// For internal use only.
+	_data: function( elem, name, data ) {
+		return jQuery.data( elem, name, data, true );
+	},
+
+	// A method for determining if a DOM node can handle the data expando
+	acceptData: function( elem ) {
+		if ( elem.nodeName ) {
+			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+			if ( match ) {
+				return !(match === true || elem.getAttribute("classid") !== match);
+			}
+		}
+
+		return true;
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		var data = null;
+
+		if ( typeof key === "undefined" ) {
+			if ( this.length ) {
+				data = jQuery.data( this[0] );
+
+				if ( this[0].nodeType === 1 ) {
+			    var attr = this[0].attributes, name;
+					for ( var i = 0, l = attr.length; i < l; i++ ) {
+						name = attr[i].name;
+
+						if ( name.indexOf( "data-" ) === 0 ) {
+							name = jQuery.camelCase( name.substring(5) );
+
+							dataAttr( this[0], name, data[ name ] );
+						}
+					}
+				}
+			}
+
+			return data;
+
+		} else if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		var parts = key.split(".");
+		parts[1] = parts[1] ? "." + parts[1] : "";
+
+		if ( value === undefined ) {
+			data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+			// Try to fetch any internally stored data first
+			if ( data === undefined && this.length ) {
+				data = jQuery.data( this[0], key );
+				data = dataAttr( this[0], key, data );
+			}
+
+			return data === undefined && parts[1] ?
+				this.data( parts[0] ) :
+				data;
+
+		} else {
+			return this.each(function() {
+				var $this = jQuery( this ),
+					args = [ parts[0], value ];
+
+				$this.triggerHandler( "setData" + parts[1] + "!", args );
+				jQuery.data( this, key, value );
+				$this.triggerHandler( "changeData" + parts[1] + "!", args );
+			});
+		}
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+
+function dataAttr( elem, key, data ) {
+	// If nothing was found internally, try to fetch any
+	// data from the HTML5 data-* attribute
+	if ( data === undefined && elem.nodeType === 1 ) {
+		var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
+
+		data = elem.getAttribute( name );
+
+		if ( typeof data === "string" ) {
+			try {
+				data = data === "true" ? true :
+				data === "false" ? false :
+				data === "null" ? null :
+				!jQuery.isNaN( data ) ? parseFloat( data ) :
+					rbrace.test( data ) ? jQuery.parseJSON( data ) :
+					data;
+			} catch( e ) {}
+
+			// Make sure we set the data so it isn't changed later
+			jQuery.data( elem, key, data );
+
+		} else {
+			data = undefined;
+		}
+	}
+
+	return data;
+}
+
+// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
+// property to be considered empty objects; this property always exists in
+// order to make sure JSON.stringify does not expose internal metadata
+function isEmptyDataObject( obj ) {
+	for ( var name in obj ) {
+		if ( name !== "toJSON" ) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+
+
+
+function handleQueueMarkDefer( elem, type, src ) {
+	var deferDataKey = type + "defer",
+		queueDataKey = type + "queue",
+		markDataKey = type + "mark",
+		defer = jQuery.data( elem, deferDataKey, undefined, true );
+	if ( defer &&
+		( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
+		( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
+		// Give room for hard-coded callbacks to fire first
+		// and eventually mark/queue something else on the element
+		setTimeout( function() {
+			if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
+				!jQuery.data( elem, markDataKey, undefined, true ) ) {
+				jQuery.removeData( elem, deferDataKey, true );
+				defer.resolve();
+			}
+		}, 0 );
+	}
+}
+
+jQuery.extend({
+
+	_mark: function( elem, type ) {
+		if ( elem ) {
+			type = (type || "fx") + "mark";
+			jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
+		}
+	},
+
+	_unmark: function( force, elem, type ) {
+		if ( force !== true ) {
+			type = elem;
+			elem = force;
+			force = false;
+		}
+		if ( elem ) {
+			type = type || "fx";
+			var key = type + "mark",
+				count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
+			if ( count ) {
+				jQuery.data( elem, key, count, true );
+			} else {
+				jQuery.removeData( elem, key, true );
+				handleQueueMarkDefer( elem, type, "mark" );
+			}
+		}
+	},
+
+	queue: function( elem, type, data ) {
+		if ( elem ) {
+			type = (type || "fx") + "queue";
+			var q = jQuery.data( elem, type, undefined, true );
+			// Speed up dequeue by getting out quickly if this is just a lookup
+			if ( data ) {
+				if ( !q || jQuery.isArray(data) ) {
+					q = jQuery.data( elem, type, jQuery.makeArray(data), true );
+				} else {
+					q.push( data );
+				}
+			}
+			return q || [];
+		}
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ),
+			fn = queue.shift(),
+			defer;
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+		}
+
+		if ( fn ) {
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift("inprogress");
+			}
+
+			fn.call(elem, function() {
+				jQuery.dequeue(elem, type);
+			});
+		}
+
+		if ( !queue.length ) {
+			jQuery.removeData( elem, type + "queue", true );
+			handleQueueMarkDefer( elem, type, "queue" );
+		}
+	}
+});
+
+jQuery.fn.extend({
+	queue: function( type, data ) {
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+		}
+
+		if ( data === undefined ) {
+			return jQuery.queue( this[0], type );
+		}
+		return this.each(function() {
+			var queue = jQuery.queue( this, type, data );
+
+			if ( type === "fx" && queue[0] !== "inprogress" ) {
+				jQuery.dequeue( this, type );
+			}
+		});
+	},
+	dequeue: function( type ) {
+		return this.each(function() {
+			jQuery.dequeue( this, type );
+		});
+	},
+	// Based off of the plugin by Clint Helfers, with permission.
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
+	delay: function( time, type ) {
+		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+		type = type || "fx";
+
+		return this.queue( type, function() {
+			var elem = this;
+			setTimeout(function() {
+				jQuery.dequeue( elem, type );
+			}, time );
+		});
+	},
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	},
+	// Get a promise resolved when queues of a certain type
+	// are emptied (fx is the type by default)
+	promise: function( type, object ) {
+		if ( typeof type !== "string" ) {
+			object = type;
+			type = undefined;
+		}
+		type = type || "fx";
+		var defer = jQuery.Deferred(),
+			elements = this,
+			i = elements.length,
+			count = 1,
+			deferDataKey = type + "defer",
+			queueDataKey = type + "queue",
+			markDataKey = type + "mark",
+			tmp;
+		function resolve() {
+			if ( !( --count ) ) {
+				defer.resolveWith( elements, [ elements ] );
+			}
+		}
+		while( i-- ) {
+			if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
+					( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
+						jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
+					jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
+				count++;
+				tmp.done( resolve );
+			}
+		}
+		resolve();
+		return defer.promise();
+	}
+});
+
+
+
+
+var rclass = /[\n\t\r]/g,
+	rspace = /\s+/,
+	rreturn = /\r/g,
+	rtype = /^(?:button|input)$/i,
+	rfocusable = /^(?:button|input|object|select|textarea)$/i,
+	rclickable = /^a(?:rea)?$/i,
+	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+	rinvalidChar = /\:/,
+	formHook, boolHook;
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return jQuery.access( this, name, value, true, jQuery.attr );
+	},
+
+	removeAttr: function( name ) {
+		return this.each(function() {
+			jQuery.removeAttr( this, name );
+		});
+	},
+	
+	prop: function( name, value ) {
+		return jQuery.access( this, name, value, true, jQuery.prop );
+	},
+	
+	removeProp: function( name ) {
+		name = jQuery.propFix[ name ] || name;
+		return this.each(function() {
+			// try/catch handles cases where IE balks (such as removing a property on window)
+			try {
+				this[ name ] = undefined;
+				delete this[ name ];
+			} catch( e ) {}
+		});
+	},
+
+	addClass: function( value ) {
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.addClass( value.call(this, i, self.attr("class") || "") );
+			});
+		}
+
+		if ( value && typeof value === "string" ) {
+			var classNames = (value || "").split( rspace );
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 ) {
+					if ( !elem.className ) {
+						elem.className = value;
+
+					} else {
+						var className = " " + elem.className + " ",
+							setClass = elem.className;
+
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+								setClass += " " + classNames[c];
+							}
+						}
+						elem.className = jQuery.trim( setClass );
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.removeClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( (value && typeof value === "string") || value === undefined ) {
+			var classNames = (value || "").split( rspace );
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 && elem.className ) {
+					if ( value ) {
+						var className = (" " + elem.className + " ").replace(rclass, " ");
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							className = className.replace(" " + classNames[c] + " ", " ");
+						}
+						elem.className = jQuery.trim( className );
+
+					} else {
+						elem.className = "";
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value,
+			isBool = typeof stateVal === "boolean";
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className,
+					i = 0,
+					self = jQuery( this ),
+					state = stateVal,
+					classNames = value.split( rspace );
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space seperated list
+					state = isBool ? state : !self.hasClass( className );
+					self[ state ? "addClass" : "removeClass" ]( className );
+				}
+
+			} else if ( type === "undefined" || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery._data( this, "__className__", this.className );
+				}
+
+				// toggle whole className
+				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ";
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	val: function( value ) {
+		var hooks, ret,
+			elem = this[0];
+		
+		if ( !arguments.length ) {
+			if ( elem ) {
+				hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
+
+				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+					return ret;
+				}
+
+				return (elem.value || "").replace(rreturn, "");
+			}
+
+			return undefined;
+		}
+
+		var isFunction = jQuery.isFunction( value );
+
+		return this.each(function( i ) {
+			var self = jQuery(this), val;
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call( this, i, self.val() );
+			} else {
+				val = value;
+			}
+
+			// Treat null/undefined as ""; convert numbers to string
+			if ( val == null ) {
+				val = "";
+			} else if ( typeof val === "number" ) {
+				val += "";
+			} else if ( jQuery.isArray( val ) ) {
+				val = jQuery.map(val, function ( value ) {
+					return value == null ? "" : value + "";
+				});
+			}
+
+			hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
+
+			// If set returns undefined, fall back to normal setting
+			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	valHooks: {
+		option: {
+			get: function( elem ) {
+				// attributes.value is undefined in Blackberry 4.7 but
+				// uses .value. See #6932
+				var val = elem.attributes.value;
+				return !val || val.specified ? elem.value : elem.text;
+			}
+		},
+		select: {
+			get: function( elem ) {
+				var value,
+					index = elem.selectedIndex,
+					values = [],
+					options = elem.options,
+					one = elem.type === "select-one";
+
+				// Nothing was selected
+				if ( index < 0 ) {
+					return null;
+				}
+
+				// Loop through all the selected options
+				for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+					var option = options[ i ];
+
+					// Don't return options that are disabled or in a disabled optgroup
+					if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+							(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+						// Get the specific value for the option
+						value = jQuery( option ).val();
+
+						// We don't need an array for one selects
+						if ( one ) {
+							return value;
+						}
+
+						// Multi-Selects return an array
+						values.push( value );
+					}
+				}
+
+				// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
+				if ( one && !values.length && options.length ) {
+					return jQuery( options[ index ] ).val();
+				}
+
+				return values;
+			},
+
+			set: function( elem, value ) {
+				var values = jQuery.makeArray( value );
+
+				jQuery(elem).find("option").each(function() {
+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+				});
+
+				if ( !values.length ) {
+					elem.selectedIndex = -1;
+				}
+				return values;
+			}
+		}
+	},
+
+	attrFn: {
+		val: true,
+		css: true,
+		html: true,
+		text: true,
+		data: true,
+		width: true,
+		height: true,
+		offset: true
+	},
+	
+	attrFix: {
+		// Always normalize to ensure hook usage
+		tabindex: "tabIndex"
+	},
+	
+	attr: function( elem, name, value, pass ) {
+		var nType = elem.nodeType;
+		
+		// don't get/set attributes on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return undefined;
+		}
+
+		if ( pass && name in jQuery.attrFn ) {
+			return jQuery( elem )[ name ]( value );
+		}
+
+		// Fallback to prop when attributes are not supported
+		if ( !("getAttribute" in elem) ) {
+			return jQuery.prop( elem, name, value );
+		}
+
+		var ret, hooks,
+			notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+		// Normalize the name if needed
+		name = notxml && jQuery.attrFix[ name ] || name;
+
+		hooks = jQuery.attrHooks[ name ];
+
+		if ( !hooks ) {
+			// Use boolHook for boolean attributes
+			if ( rboolean.test( name ) &&
+				(typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
+
+				hooks = boolHook;
+
+			// Use formHook for forms and if the name contains certain characters
+			} else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
+				hooks = formHook;
+			}
+		}
+
+		if ( value !== undefined ) {
+
+			if ( value === null ) {
+				jQuery.removeAttr( elem, name );
+				return undefined;
+
+			} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				elem.setAttribute( name, "" + value );
+				return value;
+			}
+
+		} else if ( hooks && "get" in hooks && notxml ) {
+			return hooks.get( elem, name );
+
+		} else {
+
+			ret = elem.getAttribute( name );
+
+			// Non-existent attributes return null, we normalize to undefined
+			return ret === null ?
+				undefined :
+				ret;
+		}
+	},
+
+	removeAttr: function( elem, name ) {
+		var propName;
+		if ( elem.nodeType === 1 ) {
+			name = jQuery.attrFix[ name ] || name;
+		
+			if ( jQuery.support.getSetAttribute ) {
+				// Use removeAttribute in browsers that support it
+				elem.removeAttribute( name );
+			} else {
+				jQuery.attr( elem, name, "" );
+				elem.removeAttributeNode( elem.getAttributeNode( name ) );
+			}
+
+			// Set corresponding property to false for boolean attributes
+			if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
+				elem[ propName ] = false;
+			}
+		}
+	},
+
+	attrHooks: {
+		type: {
+			set: function( elem, value ) {
+				// We can't allow the type property to be changed (since it causes problems in IE)
+				if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
+					jQuery.error( "type property can't be changed" );
+				} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+					// Setting the type on a radio button after the value resets the value in IE6-9
+					// Reset value to it's default in case type is set after value
+					// This is for element creation
+					var val = elem.value;
+					elem.setAttribute( "type", value );
+					if ( val ) {
+						elem.value = val;
+					}
+					return value;
+				}
+			}
+		},
+		tabIndex: {
+			get: function( elem ) {
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				var attributeNode = elem.getAttributeNode("tabIndex");
+
+				return attributeNode && attributeNode.specified ?
+					parseInt( attributeNode.value, 10 ) :
+					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+						0 :
+						undefined;
+			}
+		}
+	},
+
+	propFix: {
+		tabindex: "tabIndex",
+		readonly: "readOnly",
+		"for": "htmlFor",
+		"class": "className",
+		maxlength: "maxLength",
+		cellspacing: "cellSpacing",
+		cellpadding: "cellPadding",
+		rowspan: "rowSpan",
+		colspan: "colSpan",
+		usemap: "useMap",
+		frameborder: "frameBorder",
+		contenteditable: "contentEditable"
+	},
+	
+	prop: function( elem, name, value ) {
+		var nType = elem.nodeType;
+
+		// don't get/set properties on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return undefined;
+		}
+
+		var ret, hooks,
+			notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+		// Try to normalize/fix the name
+		name = notxml && jQuery.propFix[ name ] || name;
+		
+		hooks = jQuery.propHooks[ name ];
+
+		if ( value !== undefined ) {
+			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				return (elem[ name ] = value);
+			}
+
+		} else {
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				return elem[ name ];
+			}
+		}
+	},
+	
+	propHooks: {}
+});
+
+// Hook for boolean attributes
+boolHook = {
+	get: function( elem, name ) {
+		// Align boolean attributes with corresponding properties
+		return elem[ jQuery.propFix[ name ] || name ] ?
+			name.toLowerCase() :
+			undefined;
+	},
+	set: function( elem, value, name ) {
+		var propName;
+		if ( value === false ) {
+			// Remove boolean attributes when set to false
+			jQuery.removeAttr( elem, name );
+		} else {
+			// value is true since we know at this point it's type boolean and not false
+			// Set boolean attributes to the same name and set the DOM property
+			propName = jQuery.propFix[ name ] || name;
+			if ( propName in elem ) {
+				// Only set the IDL specifically if it already exists on the element
+				elem[ propName ] = value;
+			}
+
+			elem.setAttribute( name, name.toLowerCase() );
+		}
+		return name;
+	}
+};
+
+// Use the value property for back compat
+// Use the formHook for button elements in IE6/7 (#1954)
+jQuery.attrHooks.value = {
+	get: function( elem, name ) {
+		if ( formHook && jQuery.nodeName( elem, "button" ) ) {
+			return formHook.get( elem, name );
+		}
+		return elem.value;
+	},
+	set: function( elem, value, name ) {
+		if ( formHook && jQuery.nodeName( elem, "button" ) ) {
+			return formHook.set( elem, value, name );
+		}
+		// Does not return so that setAttribute is also used
+		elem.value = value;
+	}
+};
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !jQuery.support.getSetAttribute ) {
+
+	// propFix is more comprehensive and contains all fixes
+	jQuery.attrFix = jQuery.propFix;
+	
+	// Use this for any attribute on a form in IE6/7
+	formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
+		get: function( elem, name ) {
+			var ret;
+			ret = elem.getAttributeNode( name );
+			// Return undefined if nodeValue is empty string
+			return ret && ret.nodeValue !== "" ?
+				ret.nodeValue :
+				undefined;
+		},
+		set: function( elem, value, name ) {
+			// Check form objects in IE (multiple bugs related)
+			// Only use nodeValue if the attribute node exists on the form
+			var ret = elem.getAttributeNode( name );
+			if ( ret ) {
+				ret.nodeValue = value;
+				return value;
+			}
+		}
+	};
+
+	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
+	// This is for removals
+	jQuery.each([ "width", "height" ], function( i, name ) {
+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+			set: function( elem, value ) {
+				if ( value === "" ) {
+					elem.setAttribute( name, "auto" );
+					return value;
+				}
+			}
+		});
+	});
+}
+
+
+// Some attributes require a special call on IE
+if ( !jQuery.support.hrefNormalized ) {
+	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+			get: function( elem ) {
+				var ret = elem.getAttribute( name, 2 );
+				return ret === null ? undefined : ret;
+			}
+		});
+	});
+}
+
+if ( !jQuery.support.style ) {
+	jQuery.attrHooks.style = {
+		get: function( elem ) {
+			// Return undefined in the case of empty string
+			// Normalize to lowercase since IE uppercases css property names
+			return elem.style.cssText.toLowerCase() || undefined;
+		},
+		set: function( elem, value ) {
+			return (elem.style.cssText = "" + value);
+		}
+	};
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+		get: function( elem ) {
+			var parent = elem.parentNode;
+
+			if ( parent ) {
+				parent.selectedIndex;
+
+				// Make sure that it also works with optgroups, see #5701
+				if ( parent.parentNode ) {
+					parent.parentNode.selectedIndex;
+				}
+			}
+		}
+	});
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+	jQuery.each([ "radio", "checkbox" ], function() {
+		jQuery.valHooks[ this ] = {
+			get: function( elem ) {
+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+				return elem.getAttribute("value") === null ? "on" : elem.value;
+			}
+		};
+	});
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+		set: function( elem, value ) {
+			if ( jQuery.isArray( value ) ) {
+				return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
+			}
+		}
+	});
+});
+
+
+
+
+var hasOwn = Object.prototype.hasOwnProperty,
+	rnamespaces = /\.(.*)$/,
+	rformElems = /^(?:textarea|input|select)$/i,
+	rperiod = /\./g,
+	rspaces = / /g,
+	rescape = /[^\w\s.|`]/g,
+	fcleanup = function( nm ) {
+		return nm.replace(rescape, "\\$&");
+	};
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+	// Bind an event to an element
+	// Original by Dean Edwards
+	add: function( elem, types, handler, data ) {
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		if ( handler === false ) {
+			handler = returnFalse;
+		} else if ( !handler ) {
+			// Fixes bug #7229. Fix recommended by jdalton
+			return;
+		}
+
+		var handleObjIn, handleObj;
+
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+		}
+
+		// Make sure that the function being executed has a unique ID
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure
+		var elemData = jQuery._data( elem );
+
+		// If no elemData is found then we must be trying to bind to one of the
+		// banned noData elements
+		if ( !elemData ) {
+			return;
+		}
+
+		var events = elemData.events,
+			eventHandle = elemData.handle;
+
+		if ( !events ) {
+			elemData.events = events = {};
+		}
+
+		if ( !eventHandle ) {
+			elemData.handle = eventHandle = function( e ) {
+				// Discard the second event of a jQuery.event.trigger() and
+				// when an event is called after a page has unloaded
+				return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
+					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+					undefined;
+			};
+		}
+
+		// Add elem as a property of the handle function
+		// This is to prevent a memory leak with non-native events in IE.
+		eventHandle.elem = elem;
+
+		// Handle multiple events separated by a space
+		// jQuery(...).bind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		var type, i = 0, namespaces;
+
+		while ( (type = types[ i++ ]) ) {
+			handleObj = handleObjIn ?
+				jQuery.extend({}, handleObjIn) :
+				{ handler: handler, data: data };
+
+			// Namespaced event handlers
+			if ( type.indexOf(".") > -1 ) {
+				namespaces = type.split(".");
+				type = namespaces.shift();
+				handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+			} else {
+				namespaces = [];
+				handleObj.namespace = "";
+			}
+
+			handleObj.type = type;
+			if ( !handleObj.guid ) {
+				handleObj.guid = handler.guid;
+			}
+
+			// Get the current list of functions bound to this event
+			var handlers = events[ type ],
+				special = jQuery.event.special[ type ] || {};
+
+			// Init the event handler queue
+			if ( !handlers ) {
+				handlers = events[ type ] = [];
+
+				// Check for a special event handler
+				// Only use addEventListener/attachEvent if the special
+				// events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
+					}
+				}
+			}
+
+			if ( special.add ) {
+				special.add.call( elem, handleObj );
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add the function to the element's handler list
+			handlers.push( handleObj );
+
+			// Keep track of which events have been used, for event optimization
+			jQuery.event.global[ type ] = true;
+		}
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	global: {},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, pos ) {
+		// don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		if ( handler === false ) {
+			handler = returnFalse;
+		}
+
+		var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+			elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
+			events = elemData && elemData.events;
+
+		if ( !elemData || !events ) {
+			return;
+		}
+
+		// types is actually an event object here
+		if ( types && types.type ) {
+			handler = types.handler;
+			types = types.type;
+		}
+
+		// Unbind all events for the element
+		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+			types = types || "";
+
+			for ( type in events ) {
+				jQuery.event.remove( elem, type + types );
+			}
+
+			return;
+		}
+
+		// Handle multiple events separated by a space
+		// jQuery(...).unbind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		while ( (type = types[ i++ ]) ) {
+			origType = type;
+			handleObj = null;
+			all = type.indexOf(".") < 0;
+			namespaces = [];
+
+			if ( !all ) {
+				// Namespaced event handlers
+				namespaces = type.split(".");
+				type = namespaces.shift();
+
+				namespace = new RegExp("(^|\\.)" +
+					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
+			}
+
+			eventType = events[ type ];
+
+			if ( !eventType ) {
+				continue;
+			}
+
+			if ( !handler ) {
+				for ( j = 0; j < eventType.length; j++ ) {
+					handleObj = eventType[ j ];
+
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						jQuery.event.remove( elem, origType, handleObj.handler, j );
+						eventType.splice( j--, 1 );
+					}
+				}
+
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+
+			for ( j = pos || 0; j < eventType.length; j++ ) {
+				handleObj = eventType[ j ];
+
+				if ( handler.guid === handleObj.guid ) {
+					// remove the given handler for the given type
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						if ( pos == null ) {
+							eventType.splice( j--, 1 );
+						}
+
+						if ( special.remove ) {
+							special.remove.call( elem, handleObj );
+						}
+					}
+
+					if ( pos != null ) {
+						break;
+					}
+				}
+			}
+
+			// remove generic event handler if no more handlers exist
+			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+					jQuery.removeEvent( elem, type, elemData.handle );
+				}
+
+				ret = null;
+				delete events[ type ];
+			}
+		}
+
+		// Remove the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			var handle = elemData.handle;
+			if ( handle ) {
+				handle.elem = null;
+			}
+
+			delete elemData.events;
+			delete elemData.handle;
+
+			if ( jQuery.isEmptyObject( elemData ) ) {
+				jQuery.removeData( elem, undefined, true );
+			}
+		}
+	},
+	
+	// Events that are safe to short-circuit if no handlers are attached.
+	// Native DOM events should not be added, they may have inline handlers.
+	customEvent: {
+		"getData": true,
+		"setData": true,
+		"changeData": true
+	},
+
+	trigger: function( event, data, elem, onlyHandlers ) {
+		// Event object or event type
+		var type = event.type || event,
+			namespaces = [],
+			exclusive;
+
+		if ( type.indexOf("!") >= 0 ) {
+			// Exclusive events trigger only for the exact event (no namespaces)
+			type = type.slice(0, -1);
+			exclusive = true;
+		}
+
+		if ( type.indexOf(".") >= 0 ) {
+			// Namespaced trigger; create a regexp to match event type in handle()
+			namespaces = type.split(".");
+			type = namespaces.shift();
+			namespaces.sort();
+		}
+
+		if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
+			// No jQuery handlers for this event type, and it can't have inline handlers
+			return;
+		}
+
+		// Caller can pass in an Event, Object, or just an event type string
+		event = typeof event === "object" ?
+			// jQuery.Event object
+			event[ jQuery.expando ] ? event :
+			// Object literal
+			new jQuery.Event( type, event ) :
+			// Just the event type (string)
+			new jQuery.Event( type );
+
+		event.type = type;
+		event.exclusive = exclusive;
+		event.namespace = namespaces.join(".");
+		event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
+		
+		// triggerHandler() and global events don't bubble or run the default action
+		if ( onlyHandlers || !elem ) {
+			event.preventDefault();
+			event.stopPropagation();
+		}
+
+		// Handle a global trigger
+		if ( !elem ) {
+			// TODO: Stop taunting the data cache; remove global events and always attach to document
+			jQuery.each( jQuery.cache, function() {
+				// internalKey variable is just used to make it easier to find
+				// and potentially change this stuff later; currently it just
+				// points to jQuery.expando
+				var internalKey = jQuery.expando,
+					internalCache = this[ internalKey ];
+				if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
+					jQuery.event.trigger( event, data, internalCache.handle.elem );
+				}
+			});
+			return;
+		}
+
+		// Don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// Clean up the event in case it is being reused
+		event.result = undefined;
+		event.target = elem;
+
+		// Clone any incoming data and prepend the event, creating the handler arg list
+		data = data ? jQuery.makeArray( data ) : [];
+		data.unshift( event );
+
+		var cur = elem,
+			// IE doesn't like method names with a colon (#3533, #8272)
+			ontype = type.indexOf(":") < 0 ? "on" + type : "";
+
+		// Fire event on the current element, then bubble up the DOM tree
+		do {
+			var handle = jQuery._data( cur, "handle" );
+
+			event.currentTarget = cur;
+			if ( handle ) {
+				handle.apply( cur, data );
+			}
+
+			// Trigger an inline bound script
+			if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
+				event.result = false;
+				event.preventDefault();
+			}
+
+			// Bubble up to document, then to window
+			cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
+		} while ( cur && !event.isPropagationStopped() );
+
+		// If nobody prevented the default action, do it now
+		if ( !event.isDefaultPrevented() ) {
+			var old,
+				special = jQuery.event.special[ type ] || {};
+
+			if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
+				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+				// Call a native DOM method on the target with the same name name as the event.
+				// Can't use an .isFunction)() check here because IE6/7 fails that test.
+				// IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
+				try {
+					if ( ontype && elem[ type ] ) {
+						// Don't re-trigger an onFOO event when we call its FOO() method
+						old = elem[ ontype ];
+
+						if ( old ) {
+							elem[ ontype ] = null;
+						}
+
+						jQuery.event.triggered = type;
+						elem[ type ]();
+					}
+				} catch ( ieError ) {}
+
+				if ( old ) {
+					elem[ ontype ] = old;
+				}
+
+				jQuery.event.triggered = undefined;
+			}
+		}
+		
+		return event.result;
+	},
+
+	handle: function( event ) {
+		event = jQuery.event.fix( event || window.event );
+		// Snapshot the handlers list since a called handler may add/remove events.
+		var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
+			run_all = !event.exclusive && !event.namespace,
+			args = Array.prototype.slice.call( arguments, 0 );
+
+		// Use the fix-ed Event rather than the (read-only) native event
+		args[0] = event;
+		event.currentTarget = this;
+
+		for ( var j = 0, l = handlers.length; j < l; j++ ) {
+			var handleObj = handlers[ j ];
+
+			// Triggered event must 1) be non-exclusive and have no namespace, or
+			// 2) have namespace(s) a subset or equal to those in the bound event.
+			if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
+				// Pass in a reference to the handler function itself
+				// So that we can later remove it
+				event.handler = handleObj.handler;
+				event.data = handleObj.data;
+				event.handleObj = handleObj;
+
+				var ret = handleObj.handler.apply( this, args );
+
+				if ( ret !== undefined ) {
+					event.result = ret;
+					if ( ret === false ) {
+						event.preventDefault();
+						event.stopPropagation();
+					}
+				}
+
+				if ( event.isImmediatePropagationStopped() ) {
+					break;
+				}
+			}
+		}
+		return event.result;
+	},
+
+	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+	fix: function( event ) {
+		if ( event[ jQuery.expando ] ) {
+			return event;
+		}
+
+		// store a copy of the original event object
+		// and "clone" to set read-only properties
+		var originalEvent = event;
+		event = jQuery.Event( originalEvent );
+
+		for ( var i = this.props.length, prop; i; ) {
+			prop = this.props[ --i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Fix target property, if necessary
+		if ( !event.target ) {
+			// Fixes #1925 where srcElement might not be defined either
+			event.target = event.srcElement || document;
+		}
+
+		// check if target is a textnode (safari)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// Add relatedTarget, if necessary
+		if ( !event.relatedTarget && event.fromElement ) {
+			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+		}
+
+		// Calculate pageX/Y if missing and clientX/Y available
+		if ( event.pageX == null && event.clientX != null ) {
+			var eventDocument = event.target.ownerDocument || document,
+				doc = eventDocument.documentElement,
+				body = eventDocument.body;
+
+			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
+		}
+
+		// Add which for key events
+		if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+			event.which = event.charCode != null ? event.charCode : event.keyCode;
+		}
+
+		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+		if ( !event.metaKey && event.ctrlKey ) {
+			event.metaKey = event.ctrlKey;
+		}
+
+		// Add which for click: 1 === left; 2 === middle; 3 === right
+		// Note: button is not normalized, so don't use it
+		if ( !event.which && event.button !== undefined ) {
+			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+		}
+
+		return event;
+	},
+
+	// Deprecated, use jQuery.guid instead
+	guid: 1E8,
+
+	// Deprecated, use jQuery.proxy instead
+	proxy: jQuery.proxy,
+
+	special: {
+		ready: {
+			// Make sure the ready event is setup
+			setup: jQuery.bindReady,
+			teardown: jQuery.noop
+		},
+
+		live: {
+			add: function( handleObj ) {
+				jQuery.event.add( this,
+					liveConvert( handleObj.origType, handleObj.selector ),
+					jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
+			},
+
+			remove: function( handleObj ) {
+				jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
+			}
+		},
+
+		beforeunload: {
+			setup: function( data, namespaces, eventHandle ) {
+				// We only want to do this special case on windows
+				if ( jQuery.isWindow( this ) ) {
+					this.onbeforeunload = eventHandle;
+				}
+			},
+
+			teardown: function( namespaces, eventHandle ) {
+				if ( this.onbeforeunload === eventHandle ) {
+					this.onbeforeunload = null;
+				}
+			}
+		}
+	}
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+		if ( elem.removeEventListener ) {
+			elem.removeEventListener( type, handle, false );
+		}
+	} :
+	function( elem, type, handle ) {
+		if ( elem.detachEvent ) {
+			elem.detachEvent( "on" + type, handle );
+		}
+	};
+
+jQuery.Event = function( src, props ) {
+	// Allow instantiation without the 'new' keyword
+	if ( !this.preventDefault ) {
+		return new jQuery.Event( src, props );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+
+		// Events bubbling up the document may have been marked as prevented
+		// by a handler lower down the tree; reflect the correct value.
+		this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
+			src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
+
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// Put explicitly provided properties onto the event object
+	if ( props ) {
+		jQuery.extend( this, props );
+	}
+
+	// timeStamp is buggy for some events on Firefox(#3843)
+	// So we won't rely on the native value
+	this.timeStamp = jQuery.now();
+
+	// Mark it as fixed
+	this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+	return false;
+}
+function returnTrue() {
+	return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	preventDefault: function() {
+		this.isDefaultPrevented = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+
+		// if preventDefault exists run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+
+		// otherwise set the returnValue property of the original event to false (IE)
+		} else {
+			e.returnValue = false;
+		}
+	},
+	stopPropagation: function() {
+		this.isPropagationStopped = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		// if stopPropagation exists run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+		// otherwise set the cancelBubble property of the original event to true (IE)
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	},
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+	// Check if mouse(over|out) are still within the same parent element
+	var parent = event.relatedTarget;
+
+	// set the correct event type
+	event.type = event.data;
+
+	// Firefox sometimes assigns relatedTarget a XUL element
+	// which we cannot access the parentNode property of
+	try {
+
+		// Chrome does something similar, the parentNode property
+		// can be accessed but is null.
+		if ( parent && parent !== document && !parent.parentNode ) {
+			return;
+		}
+
+		// Traverse up the tree
+		while ( parent && parent !== this ) {
+			parent = parent.parentNode;
+		}
+
+		if ( parent !== this ) {
+			// handle event if we actually just moused on to a non sub-element
+			jQuery.event.handle.apply( this, arguments );
+		}
+
+	// assuming we've left the element since we most likely mousedover a xul element
+	} catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+	event.type = event.data;
+	jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+}, function( orig, fi

<TRUNCATED>

[3/7] karaf-decanter git commit: [KARAF-3904] Add elasticsearch-head feature

Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.ttf
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.ttf b/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.ttf
new file mode 100644
index 0000000..e89738d
Binary files /dev/null and b/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.ttf differ

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.woff
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.woff b/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.woff
new file mode 100644
index 0000000..8c1748a
Binary files /dev/null and b/elasticsearch-head/src/main/resources/fonts/fontawesome-webfont.woff differ

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/i18n.js
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/i18n.js b/elasticsearch-head/src/main/resources/i18n.js
new file mode 100644
index 0000000..de0fc51
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/i18n.js
@@ -0,0 +1,93 @@
+(function() {
+	/**
+	 * provides text formatting and i18n key storage features<br>
+	 * implements most of the Sun Java MessageFormat functionality.
+	 * @see <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html" target="sun">Sun's Documentation</a>
+	 */
+
+	var keys = {};
+
+	var format = function(message, args) {
+		var substitute = function() {
+			var format = arguments[1].split(',');
+			var substr = escape(args[format.shift()]);
+			if(format.length === 0) {
+				return substr; // simple substitution eg {0}
+			}
+			switch(format.shift()) {
+				case "number" : return (new Number(substr)).toLocaleString();
+				case "date" : return (new Date(+substr)).toLocaleDateString(); // date and time require milliseconds since epoch
+				case "time" : return (new Date(+substr)).toLocaleTimeString(); //  eg i18n.text("Key", +(new Date())); for current time
+			}
+			var styles = format.join("").split("|").map(function(style) {
+				return style.match(/(-?[\.\d]+)(#|<)([^{}]*)/);
+			});
+			var match = styles[0][3];
+			for(var i=0; i<styles.length; i++) {
+				if((styles[i][2] === "#" && (+styles[i][1]) === (+substr)) ||
+						(styles[i][2] === "<" && ((+styles[i][1]) < (+substr)))) {
+					match = styles[i][3];
+				}
+			}
+			return match;
+		};
+
+		return message && message.replace(/'(')|'([^']+)'|([^{']+)|([^']+)/g, function(x, sq, qs, ss, sub) {
+			do {} while(sub && (sub !== (sub = (sub.replace(/\{([^{}]+)\}/, substitute)))));
+			return sq || qs || ss || unescape(sub);
+		});
+	};
+
+	this.i18n = {
+
+		setKeys: function(strings) {
+			for(var key in strings) {
+				keys[key] = strings[key];
+			}
+		},
+
+		text: function() {
+			var args = Array.prototype.slice.call(arguments),
+				key = keys[args.shift()];
+			if(args.length === 0) {
+				return key;
+			}
+			return format(key, args);
+		},
+
+		complex: function() {
+			var args = Array.prototype.slice.call(arguments),
+				key = keys[args.shift()],
+				ret = [],
+				replacer = function(x, pt, sub) { ret.push(pt || args[+sub]); return ""; };
+			do {} while(key && key !== (key = key.replace(/([^{]+)|\{(\d+)\}/, replacer )));
+			return ret;
+		}
+
+	};
+
+})();
+
+(function() {
+	var nav = window.navigator;
+	var userLang = ( nav.languages && nav.languages[0] ) || nav.language || nav.userLanguage;
+	var scripts = document.getElementsByTagName('script');
+	var data = scripts[ scripts.length - 1].dataset;
+	if( ! data["langs"] ) {
+		return;
+	}
+	var langs = data["langs"].split(/\s*,\s*/);
+	var script0 = scripts[0];
+	function install( lang ) {
+		var s = document.createElement("script");
+		s.src = data["basedir"] + "/" + lang + '_strings.js';
+		s.async = false;
+		script0.parentNode.appendChild(s);
+		script0 = s;
+	}
+
+	install( langs.shift() ); // always install primary language
+	userLang && langs
+		.filter( function( lang ) { return userLang.indexOf( lang ) === 0; } )
+		.forEach( install );
+}());

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/index.html
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/index.html b/elasticsearch-head/src/main/resources/index.html
new file mode 100644
index 0000000..82e8b5f
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/index.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<meta charset="UTF-8">
+		<title>elasticsearch-head</title>
+		<link rel="stylesheet" href="base/reset.css">
+		<link rel="stylesheet" href="vendor.css">
+		<link rel="stylesheet" href="app.css">
+		<script src="i18n.js" data-baseDir="lang" data-langs="en,fr,pt,zh"></script>
+		<script src="vendor.js"></script>
+		<script src="app.js"></script>
+		<script>
+			window.onload = function() {
+				if(location.href.contains("/_plugin/")) {
+					var base_uri = location.href.replace(/_plugin\/.*/, '');
+				}
+				var args = location.search.substring(1).split("&").reduce(function(r, p) {
+					r[decodeURIComponent(p.split("=")[0])] = decodeURIComponent(p.split("=")[1]); return r;
+				}, {});
+				new app.App("body", {
+					id: "es",
+					base_uri: args["base_uri"] || base_uri,
+					auth_user : args["auth_user"] || "",
+					auth_password : args["auth_password"],
+					dashboard: args["dashboard"]
+				});
+			};
+		</script>
+		<link rel="icon" href="base/favicon.png" type="image/png">
+	</head>
+	<body></body>
+</html>

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/lang/en_strings.js
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/lang/en_strings.js b/elasticsearch-head/src/main/resources/lang/en_strings.js
new file mode 100644
index 0000000..a8f3047
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/lang/en_strings.js
@@ -0,0 +1,174 @@
+i18n.setKeys({
+	"General.Elasticsearch": "Elasticsearch",
+	"General.LoadingFacets": "Loading Facets...",
+	"General.Searching": "Searching...",
+	"General.Search": "Search",
+	"General.Help": "Help",
+	"General.HelpGlyph": "?",
+	"General.CloseGlyph": "X",
+	"General.RefreshResults": "Refresh",
+	"General.ManualRefresh": "Manual Refresh",
+	"General.RefreshQuickly": "Refresh quickly",
+	"General.Refresh5seconds": "Refresh every 5 seconds",
+	"General.Refresh1minute": "Refresh every minute",
+	"AliasForm.AliasName": "Alias Name",
+	"AliasForm.NewAliasForIndex": "New Alias for {0}",
+	"AliasForm.DeleteAliasMessage": "type ''{0}'' to delete {1}. There is no undo",
+	"AnyRequest.DisplayOptions" : "Display Options",
+	"AnyRequest.AsGraph" : "Graph Results",
+	"AnyRequest.AsJson" : "Show Raw JSON",
+	"AnyRequest.AsTable" : "Show Search Results Table",
+	"AnyRequest.History" : "History",
+	"AnyRequest.RepeatRequest" : "Repeat Request",
+	"AnyRequest.RepeatRequestSelect" : "Repeat request every ",
+	"AnyRequest.Transformer" : "Result Transformer",
+	"AnyRequest.Pretty": "Pretty",
+	"AnyRequest.Query" : "Query",
+	"AnyRequest.Request": "Request",
+	"AnyRequest.Requesting": "Requesting...",
+	"AnyRequest.ValidateJSON": "Validate JSON",
+	"Browser.Title": "Browser",
+	"Browser.ResultSourcePanelTitle": "Result Source",
+	"Command.DELETE": "DELETE",
+	"Command.SHUTDOWN": "SHUTDOWN",
+	"Command.DeleteAliasMessage": "Delete Alias?",
+	"ClusterOverView.IndexName": "Index Name",
+	"ClusterOverview.NumShards": "Number of Shards",
+	"ClusterOverview.NumReplicas": "Number of Replicas",
+	"ClusterOverview.NewIndex": "New Index",
+	"IndexActionsMenu.Title": "Actions",
+	"IndexActionsMenu.NewAlias": "New Alias...",
+	"IndexActionsMenu.Refresh": "Refresh",
+	"IndexActionsMenu.Flush": "Flush",
+	"IndexActionsMenu.Optimize": "Optimize...",
+	"IndexActionsMenu.Snapshot": "Gateway Snapshot",
+	"IndexActionsMenu.Analyser": "Test Analyser",
+	"IndexActionsMenu.Open": "Open",
+	"IndexActionsMenu.Close": "Close",
+	"IndexActionsMenu.Delete": "Delete...",
+	"IndexInfoMenu.Title": "Info",
+	"IndexInfoMenu.Status": "Index Status",
+	"IndexInfoMenu.Metadata": "Index Metadata",
+	"IndexCommand.TextToAnalyze": "Text to Analyse",
+	"IndexCommand.ShutdownMessage": "type ''{0}'' to shutdown {1}. Node can NOT be restarted from this interface",
+	"IndexOverview.PageTitle": "Indices Overview",
+	"IndexSelector.NameWithDocs": "{0} ({1} docs)",
+	"IndexSelector.SearchIndexForDocs": "Search {0} for documents where:",
+	"FilterBrowser.OutputType": "Output Results: {0}",
+	"FilterBrowser.OutputSize": "Number of Results: {0}",
+	"Header.ClusterHealth": "cluster health: {0} ({1} of {2})",
+	"Header.ClusterNotConnected": "cluster health: not connected",
+	"Header.Connect": "Connect",
+	"Nav.AnyRequest": "Any Request",
+	"Nav.Browser": "Browser",
+	"Nav.ClusterHealth": "Cluster Health",
+	"Nav.ClusterState": "Cluster State",
+	"Nav.ClusterNodes": "Cluster Nodes",
+	"Nav.Info": "Info",
+	"Nav.NodeStats": "Node Stats",
+	"Nav.Overview": "Overview",
+	"Nav.Indices": "Indices",
+	"Nav.Plugins": "Plugins",
+	"Nav.Status": "Status",
+	"Nav.Templates": "Templates",
+	"Nav.StructuredQuery": "Structured Query",
+	"NodeActionsMenu.Title": "Actions",
+	"NodeActionsMenu.Shutdown": "Shutdown...",
+	"NodeInfoMenu.Title": "Info",
+	"NodeInfoMenu.ClusterNodeInfo": "Cluster Node Info",
+	"NodeInfoMenu.NodeStats": "Node Stats",
+	"NodeType.Client": "Client Node",
+	"NodeType.Coord": "Coordinator",
+	"NodeType.Master": "Master Node",
+	"NodeType.Tribe": "Tribe Node",
+	"NodeType.Worker": "Worker Node",
+	"NodeType.Unassigned": "Unassigned",
+	"OptimizeForm.OptimizeIndex": "Optimize {0}",
+	"OptimizeForm.MaxSegments": "Maximum # Of Segments",
+	"OptimizeForm.ExpungeDeletes": "Only Expunge Deletes",
+	"OptimizeForm.FlushAfter": "Flush After Optimize",
+	"OptimizeForm.WaitForMerge": "Wait For Merge",
+	"Overview.PageTitle" : "Cluster Overview",
+	"Output.JSON": "JSON",
+	"Output.Table": "Table",
+	"Output.CSV": "CSV",
+	"Output.ShowSource": "Show query source",
+	"Preference.SortCluster": "Sort Cluster",
+	"Sort.ByName": "By Name",
+	"Sort.ByAddress": "By Address",
+	"Sort.ByType": "By Type",
+	"Preference.ViewAliases": "View Aliases",
+	"ViewAliases.Grouped": "Grouped",
+	"ViewAliases.List": "List",
+	"ViewAliases.None": "None",
+	"Overview.IndexFilter": "Index Filter",
+	"TableResults.Summary": "Searched {0} of {1} shards. {2} hits. {3} seconds",
+	"QueryFilter.AllIndices": "All Indices",
+	"QueryFilter.AnyValue": "any",
+	"QueryFilter-Header-Indices": "Indices",
+	"QueryFilter-Header-Types": "Types",
+	"QueryFilter-Header-Fields": "Fields",
+	"QueryFilter.DateRangeHint.from": "From : {0}",
+	"QueryFilter.DateRangeHint.to": "  To : {0}",
+	"Query.FailAndUndo": "Query Failed. Undoing last changes",
+	"StructuredQuery.ShowRawJson": "Show Raw JSON"
+});
+
+i18n.setKeys({
+	"AnyRequest.TransformerHelp" : "\
+		<p>The Result Transformer can be used to post process the raw json results from a request into a more useful format.</p>\
+		<p>The transformer should contain the body of a javascript function. The return value from the function becomes the new value passed to the json printer</p>\
+		<p>Example:<br>\
+		  <code>return root.hits.hits[0];</code> would traverse a result set to show just the first match<br>\
+		  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> would return the total memory used across an entire cluster<br></p>\
+		<p>The following functions are available and can be useful processing arrays and objects<br>\
+		<ul>\
+			<li><i>Object.keys</i>(object) := array</li>\
+			<li>array.<i>forEach</i>(function(prop, index))</li>\
+			<li>array.<i>map</i>(function(prop, index)) := array</li>\
+			<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\
+		</ul>\
+		<p>When Repeat Request is running, an extra parameter called prev is passed to the transformation function. This allows comparisons, and cumulative graphing</p>\
+		<p>Example:<br>\
+		<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> would return the load average on the first cluster node over the last minute\
+		This could be fed into the Graph to produce a load graph for the node\
+		"
+});
+
+i18n.setKeys({
+	"AnyRequest.DisplayOptionsHelp" : "\
+		<p>Raw Json: shows complete results of the query and transformation in raw JSON format </p>\
+		<p>Graph Results: To produce a graph of your results, use the result transformer to produce an array of values</p>\
+		<p>Search Results Table: If your query is a search, you can display the results of the search in a table.</p>\
+		"
+});
+
+i18n.setKeys({
+	"QueryFilter.DateRangeHelp" : "\
+		<p>Date fields accept a natural language query to produce a From and To date that form a range that the results are queried over.</p>\
+		<p>The following formats are supported:</p>\
+		<ul>\
+			<li><b>Keywords / Key Phrases</b><br>\
+				<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\
+				searches for dates matching the keyword. <code>last year</code> would search all of last year.</li>\
+			<li><b>Ranges</b><br>\
+				<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (spaces optional, many synonyms for range qualifiers)<br>\
+				Create a search range centered on <code>now</code> extending into the past and future by the amount specified.</li>\
+			<li><b>DateTime and Partial DateTime</b><br>\
+				<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\
+				these formats specify a specific date range. <code>2011</code> would search the whole of 2011, while <code>2011-01-18 12:32:45</code> would only search for results in that 1 second range</li>\
+			<li><b>Time and Time Partials</b><br>\
+				<code>12<br> 12:32<br> 12:32:45</code><br>\
+				these formats search for a particular time during the current day. <code>12:32</code> would search that minute during today</li>\
+			<li><b>Date Ranges</b><br>\
+				<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\
+				A Date Range is created by specifying two dates in any format (Keyword / DateTime / Time) separated by &lt; or -&gt; (both do the same thing). If either end of the date range is missing, it is the same as having no constraint in that direction.</li>\
+			<li><b>Date Range using Offset</b><br>\
+				<code>2010 -> 1yr<br> 3mins < now</code>\
+				Searches the specified date including the range in the direction specified.</li>\
+			<li><b>Anchored Ranges</b><br>\
+				<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\
+				Similar to above except the range is extend in both directions from the anchor date</li>\
+		</ul>\
+	"
+});

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/lang/fr_strings.js
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/lang/fr_strings.js b/elasticsearch-head/src/main/resources/lang/fr_strings.js
new file mode 100644
index 0000000..b4ebb09
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/lang/fr_strings.js
@@ -0,0 +1,164 @@
+i18n.setKeys({
+//	"General.Elasticsearch": "Elasticsearch",
+	"General.LoadingFacets" : "Chargement des facettes...",
+	"General.Searching": "Recherche en cours...",
+	"General.Search": "Recherche",
+	"General.Help": "Aide",
+//	"General.HelpGlyph": "?",
+//	"General.CloseGlyph": "X",
+	"General.RefreshResults": "Rafraîchir",
+	"General.ManualRefresh": "Rafraîchissement manuel",
+	"General.RefreshQuickly": "Rafraîchissement rapide",
+	"General.Refresh5seconds": "Rafraîchissement toutes les 5 secondes",
+	"General.Refresh1minute": "Rafraîchissement toutes les minutes",
+	"AliasForm.AliasName": "Alias",
+	"AliasForm.NewAliasForIndex": "Nouvel Alias pour {0}",
+	"AliasForm.DeleteAliasMessage": "Entrez ''{0}'' pour effacer {1}. Attention, action irréversible.",
+	"AnyRequest.DisplayOptions" : "Options d'affichage",
+	"AnyRequest.AsGraph" : "En graphe",
+	"AnyRequest.AsJson" : "En JSON brut",
+	"AnyRequest.AsTable" : "En tableau",
+	"AnyRequest.History" : "Historique",
+	"AnyRequest.RepeatRequest" : "Répétition automatique de la requête",
+	"AnyRequest.RepeatRequestSelect" : "Répéter la requête toutes les ",
+	"AnyRequest.Transformer" : "Transformation des résultats",
+//	"AnyRequest.Pretty": "Pretty",
+	"AnyRequest.Query" : "Recherche",
+	"AnyRequest.Request": "Requête",
+	"AnyRequest.Requesting": "Requête en cours...",
+	"AnyRequest.ValidateJSON": "Valider le JSON",
+	"Browser.Title": "Navigateur",
+	"Browser.ResultSourcePanelTitle": "Résultat au format JSON",
+	"Command.DELETE": "SUPPRIMER",
+	"Command.SHUTDOWN": "ETEINDRE",
+	"Command.DeleteAliasMessage": "Supprimer l'Alias?",
+	"ClusterOverView.IndexName": "Index",
+	"ClusterOverview.NumShards": "Nombre de shards",
+	"ClusterOverview.NumReplicas": "Nombre de replica",
+	"ClusterOverview.NewIndex": "Nouvel Index",
+//	"IndexActionsMenu.Title": "Actions",
+	"IndexActionsMenu.NewAlias": "Nouvel Alias...",
+	"IndexActionsMenu.Refresh": "Rafraîchir",
+	"IndexActionsMenu.Flush": "Flusher",
+	"IndexActionsMenu.Optimize": "Optimiser...",
+	"IndexActionsMenu.Snapshot": "Dupliquer l'index (Snapshot)",
+	"IndexActionsMenu.Analyser": "Tester un analyseur",
+	"IndexActionsMenu.Open": "Ouvrir",
+	"IndexActionsMenu.Close": "Fermer",
+	"IndexActionsMenu.Delete": "Effacer...",
+//	"IndexInfoMenu.Title": "Info",
+	"IndexInfoMenu.Status": "Etat de l'Index",
+	"IndexInfoMenu.Metadata": "Métadonnées de l'Index",
+	"IndexCommand.TextToAnalyze": "Texte à analyser",
+	"IndexCommand.ShutdownMessage": "Entrez ''{0}'' pour éteindre {1}. Le noeud NE PEUT PAS être redémarré depuis cette interface.",
+//	"IndexSelector.NameWithDocs": "{0} ({1} docs)",
+	"IndexSelector.SearchIndexForDocs": "Chercher dans {0} les documents correspondant à",
+	"FilterBrowser.OutputType": "Format d'affichage des résultats {0}",
+	"FilterBrowser.OutputSize": "Nombre de Résultats: {0}",
+	"Header.ClusterHealth": "Santé du cluster: {0} ({1} {2})",
+	"Header.ClusterNotConnected": "Santé du cluster: non connecté",
+	"Header.Connect": "Se connecter",
+	"Nav.AnyRequest": "Autres requêtes",
+	"Nav.StructuredQuery": "Requêtes structurées",
+	"Nav.Browser": "Navigateur",
+	"Nav.ClusterHealth": "Santé du cluster",
+	"Nav.ClusterState": "Etat du cluster",
+	"Nav.ClusterNodes": "Noeuds du cluster",
+//	"Nav.Info": "Info",
+	"Nav.NodeStats": "Statistiques sur les noeuds",
+	"Nav.Overview": "Aperçu",
+	"Nav.Indices": "Index",
+	"Nav.Plugins": "Plugins",
+	"Nav.Status": "Etat",
+	"Nav.Templates": "Templates",
+	"Nav.StructuredQuery": "Recherche Structurée",
+//	"NodeActionsMenu.Title": "Actions",
+	"NodeActionsMenu.Shutdown": "Eteindre...",
+//	"NodeInfoMenu.Title": "Info",
+	"NodeInfoMenu.ClusterNodeInfo": "Infos sur le noeud du cluster",
+	"NodeInfoMenu.NodeStats": "Statistiques du noeud",
+	"NodeType.Client": "Noeud Client",
+	"NodeType.Coord": "Coordinateur",
+	"NodeType.Master": "Noeud Master",
+	"NodeType.Tribe": "Noeud Tribe",
+	"NodeType.Worker": "Noeud Worker",
+	"NodeType.Unassigned": "Non assigné",
+	"OptimizeForm.OptimizeIndex": "Optimiser {0}",
+	"OptimizeForm.MaxSegments": "Nombre maximum de segments",
+	"OptimizeForm.ExpungeDeletes": "Seulement purger les suppressions",
+	"OptimizeForm.FlushAfter": "Flusher après l'optimisation",
+	"OptimizeForm.WaitForMerge": "Attendre la fin de la fusion",
+	"Overview.PageTitle" : "Aperçu du cluster",
+//	"Output.JSON": "JSON",
+	"Output.Table": "Tableau",
+	"Output.ShowSource": "Voir la requête source",
+    "TableResults.Summary": "Recherche sur {0} des {1} shards. {2} résultats. {3} secondes",
+	"QueryFilter.AllIndices": "Tous les index",
+	"QueryFilter.AnyValue": "Tout",
+	"QueryFilter-Header-Indices": "Index",
+//	"QueryFilter-Header-Types": "Types",
+	"QueryFilter-Header-Fields": "Champs",
+	"QueryFilter.DateRangeHint.from": "De : {0}",
+	"QueryFilter.DateRangeHint.to": "  A : {0}",
+	"Query.FailAndUndo": "Requête en échec. Annulation des dernières modifications.",
+	"StructuredQuery.ShowRawJson": "Voir le JSON brut"
+});
+
+i18n.setKeys({
+	"AnyRequest.TransformerHelp" : "\
+		<p>Le transformateur de résultats peut être utilisé pour modifier a posteriori les résultats JSON bruts dans un format plus utile.</p>\
+		<p>Le transformateur devrait contenir le corps d'une fonction javascript. La valeur de retour de la fonction devient la nouvelle valeur qui sera passée à l'afficheur des documents JSON.</p>\
+		<p>Exemple:<br>\
+		  <code>return root.hits.hits[0];</code> ne renverra que le premier élément de l'ensemble des résultats.<br>\
+		  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> retournera la mémoire totale utilisée dans l'ensemble du cluster.<br></p>\
+		<p>Les fonctions suivantes sont disponibles et peuvent vous être utiles pour travailler sur les tableaux et les objets:<br>\
+		<ul>\
+			<li><i>Object.keys</i>(object) := array</li>\
+			<li>array.<i>forEach</i>(function(prop, index))</li>\
+			<li>array.<i>map</i>(function(prop, index)) := array</li>\
+			<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\
+		</ul>\
+		<p>Lorsque vous activez la répétition automatique de la requête, un paramètre supplémentaire nommé prev est passé à la fonction de transformation. Cela permet les comparaisons et les graphes cumulatifs.</p>\
+		<p>Exemple:<br>\
+		<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> retournera la charge moyenne du premier noeud du cluster pour la dernière minute écoulée.\
+		Cela peut alimenter ensuite le graphe pour produire un graphe de charge du noeud.\
+		"
+});
+
+i18n.setKeys({
+	"AnyRequest.DisplayOptionsHelp" : "\
+		<p>En JSON brut: affiche les résultats complets de la recherche éventuellement transformée au format JSON brut.</p>\
+		<p>En graphe: pour fabriquer un graphe de vos résultats, utilsez la transformation de résultats pour générer un tableau de valeurs.</p>\
+		<p>En tableau: si votre requête est une recherche, vous pouvez alors afficher les résultats dans un tableau.</p>\
+		"
+});
+
+i18n.setKeys({
+	"QueryFilter.DateRangeHelp" : "\
+		<p>Les champs Date acceptent une requête en langage naturel pour produire un écart de date (from/to) correspondant.</p>\
+		<p>Les formats suivants sont acceptés :</p>\
+		<ul>\
+			<li><b>Mots clés</b><br>\
+				<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\
+				Cherchera pour des dates correspondant au mot clé. <code>last year</code> cherchera sur toute l'année précédente.</li>\
+			<li><b>Ecarts</b><br>\
+				<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (les espaces sont optionnels et il existe beaucoup de synonymes pour qualifier les écarts)<br>\
+				Créé un écart de date basé sur l'heure courante (maintenant) avec plus ou moins l'écart indiqué.</li>\
+			<li><b>Dates et Dates partielles</b><br>\
+				<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\
+				Ces formats indiquent un écart de date spécifique. <code>2011</code> cherchera sur toute l'année 2011, alors que <code>2011-01-18 12:32:45</code> ne cherchera que pour la date précise à la seconde près.</li>\
+			<li><b>Heures et heures partielles</b><br>\
+				<code>12<br> 12:32<br> 12:32:45</code><br>\
+				Ces formats indiquent un espace de temps pour la date du jour. <code>12:32</code> cherchera les éléments d'aujourd'hui à cette minute précise.</li>\
+			<li><b>Ecart de Date</b><br>\
+				<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\
+				Un écart de date est créé en spécifiant deux dates dans n'importe lequel des formats précédents (Mot clé / Dates / Heures) séparées par &lt; ou -&gt; (les deux produisent le même effet). Si la date de fin n'est pas indiquée, alors il n'y aura aucune contrainte de fin.</li>\
+			<li><b>Ecart de date avec décalage</b><br>\
+				<code>2010 -> 1yr<br> 3mins < now</code>\
+				Cherche en incluant un décalage de la date dans la direction indiquée.</li>\
+			<li><b>Ecart de date avec bornes</b><br>\
+				<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\
+				Similaire à ci-dessus excepté que le décalage est appliqué dans les deux sens à partir de la date indiquée.</li>\
+		</ul>\
+	"
+});

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/lang/pt_strings.js
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/lang/pt_strings.js b/elasticsearch-head/src/main/resources/lang/pt_strings.js
new file mode 100644
index 0000000..c935ee8
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/lang/pt_strings.js
@@ -0,0 +1,174 @@
+i18n.setKeys({
+	"General.Elasticsearch": "Elasticsearch",
+	"General.LoadingFacets": "Carregando Facetas...",
+	"General.Searching": "Buscando...",
+	"General.Search": "Busca",
+	"General.Help": "Ajuda",
+	"General.HelpGlyph": "?",
+	"General.CloseGlyph": "X",
+	"General.RefreshResults": "Atualizar",
+	"General.ManualRefresh": "Atualização Manual",
+	"General.RefreshQuickly": "Atualização rápida",
+	"General.Refresh5seconds": "Atualização a cada 5 segundos",
+	"General.Refresh1minute": "Atualização a cada minuto",
+	"AliasForm.AliasName": "Apelido",
+	"AliasForm.NewAliasForIndex": "Novo apelido para {0}",
+	"AliasForm.DeleteAliasMessage": "digite ''{0}'' para deletar {1}. Não há como voltar atrás",
+	"AnyRequest.DisplayOptions" : "Mostrar Opções",
+	"AnyRequest.AsGraph" : "Mostrar como gráfico",
+	"AnyRequest.AsJson" : "Mostrar JSON bruto",
+	"AnyRequest.AsTable" : "Mostrar tabela de resultados da consulta",
+	"AnyRequest.History" : "Histórico",
+	"AnyRequest.RepeatRequest" : "Refazer requisição",
+	"AnyRequest.RepeatRequestSelect" : "Repetir requisição a cada ",
+	"AnyRequest.Transformer" : "Transformador de resultado",
+	"AnyRequest.Pretty": "Amigável",
+	"AnyRequest.Query" : "Consulta",
+	"AnyRequest.Request": "Requisição",
+	"AnyRequest.Requesting": "Realizando requisição...",
+	"AnyRequest.ValidateJSON": "Validar JSON",
+	"Browser.Title": "Navegador",
+	"Browser.ResultSourcePanelTitle": "Resultado",
+	"Command.DELETE": "DELETAR",
+	"Command.SHUTDOWN": "DESLIGAR",
+	"Command.DeleteAliasMessage": "Remover apelido?",
+	"ClusterOverView.IndexName": "Nome do índice",
+	"ClusterOverview.NumShards": "Número de Shards",
+	"ClusterOverview.NumReplicas": "Número de Réplicas",
+	"ClusterOverview.NewIndex": "Novo índice",
+	"IndexActionsMenu.Title": "Ações",
+	"IndexActionsMenu.NewAlias": "Novo apelido...",
+	"IndexActionsMenu.Refresh": "Atualizar",
+	"IndexActionsMenu.Flush": "Flush",
+	"IndexActionsMenu.Optimize": "Otimizar...",
+	"IndexActionsMenu.Snapshot": "Snapshot do Gateway",
+	"IndexActionsMenu.Analyser": "Analizador de teste",
+	"IndexActionsMenu.Open": "Abrir",
+	"IndexActionsMenu.Close": "Fechar",
+	"IndexActionsMenu.Delete": "Deletar...",
+	"IndexInfoMenu.Title": "Info",
+	"IndexInfoMenu.Status": "Status do índice",
+	"IndexInfoMenu.Metadata": "Metadados do índice",
+	"IndexCommand.TextToAnalyze": "Texto para analizar",
+	"IndexCommand.ShutdownMessage": "digite ''{0}'' para desligar {1}. Nó NÃO PODE ser reiniciado à partir dessa interface",
+	"IndexOverview.PageTitle": "Visão Geral dos Índices",
+	"IndexSelector.NameWithDocs": "{0} ({1} documentoss)",
+	"IndexSelector.SearchIndexForDocs": "Busca {0} por documentos onde:",
+	"FilterBrowser.OutputType": "Resultados: {0}",
+	"FilterBrowser.OutputSize": "Número de Resultados: {0}",
+	"Header.ClusterHealth": "saúde do cluster: {0} ({1} {2})",
+	"Header.ClusterNotConnected": "saúde do cluster: não conectado",
+	"Header.Connect": "Conectar",
+	"Nav.AnyRequest": "Qualquer requisição",
+	"Nav.Browser": "Navegador",
+	"Nav.ClusterHealth": "Saúde do Cluster",
+	"Nav.ClusterState": "Estado do Cluster",
+	"Nav.ClusterNodes": "Nós do Cluster",
+	"Nav.Info": "Informações",
+	"Nav.NodeStats": "Estatísticas do nó",
+	"Nav.Overview": "Visão Geral",
+	"Nav.Indices": "Índices",
+	"Nav.Plugins": "Plugins",
+	"Nav.Status": "Status",
+	"Nav.Templates": "Modelos",
+	"Nav.StructuredQuery": "Consulta Estruturada",
+	"NodeActionsMenu.Title": "Ações",
+	"NodeActionsMenu.Shutdown": "Desligar...",
+	"NodeInfoMenu.Title": "Informações",
+	"NodeInfoMenu.ClusterNodeInfo": "Informações do Nó do Cluster",
+	"NodeInfoMenu.NodeStats": "Estatísticas do Nó",
+	"NodeType.Client": "Nó Cliente",
+	"NodeType.Coord": "Coordenador",
+	"NodeType.Master": "Nó Mestre",
+	"NodeType.Tribe": "Nó Tribo",
+	"NodeType.Worker": "Nó Trabalhador",
+	"NodeType.Unassigned": "Não Atribuido",
+	"OptimizeForm.OptimizeIndex": "Otimizar {0}",
+	"OptimizeForm.MaxSegments": "Num. Máximo De Segmentos",
+	"OptimizeForm.ExpungeDeletes": "Apenas Expurgar Exclusões",
+	"OptimizeForm.FlushAfter": "Flush após Otimizar",
+	"OptimizeForm.WaitForMerge": "Esperar Por Merge",
+	"Overview.PageTitle": "Visão geral do Cluster",
+	"Output.JSON": "JSON",
+	"Output.Table": "Tabela",
+	"Output.CSV": "CSV",
+	"Output.ShowSource": "Mostrar consulta original",
+	"Preference.SortCluster": "Ordenar Cluster",
+	"Sort.ByName": "Por Nome",
+	"Sort.ByAddress": "Por Endereço",
+	"Sort.ByType": "Por Tipo",
+	"Preference.ViewAliases": "Ver Alias",
+	"ViewAliases.Grouped": "Agrupado",
+	"ViewAliases.List": "Lista",
+	"ViewAliases.None": "Nenhum",
+	"Overview.IndexFilter": "Filtar Índice",
+	"TableResults.Summary": "Buscado {0} de {1} shards. {2} resultados. {3} segundos",
+	"QueryFilter.AllIndices": "Todos os Índices",
+	"QueryFilter.AnyValue": "qualquer",
+	"QueryFilter-Header-Indices": "Índices",
+	"QueryFilter-Header-Types": "Tipos",
+	"QueryFilter-Header-Fields": "Campos",
+	"QueryFilter.DateRangeHint.from": "De : {0}",
+	"QueryFilter.DateRangeHint.to": "  A : {0}",
+	"Query.FailAndUndo": "Consulta falhou. Desfazendo últimas alterações",
+	"StructuredQuery.ShowRawJson": "Mostrar JSON bruto"
+});
+
+	i18n.setKeys({
+		"AnyRequest.TransformerHelp" : "\
+		<p>O Transformador de Resultados pode ser usado para transformar os resultados de uma consulta de json bruto para um formato mais útil.</p>\
+		<p>O transformador deve possuir o corpo de uma função javascript. O retorno da função se torna o novo valor passado para o json printer</p>\
+		<p>Exemplo:<br>\
+		  <code>return root.hits.hits[0];</code> irá alterar a resposta para mostrar apenas o primeiro resultado<br>\
+		  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> irá retornar o total de memória utilizada pelo cluster<br></p>\
+		<p>As seguintes funções estão disponíveis e podem ser úteis no processamento de vetores e objetos<br>\
+		<ul>\
+			<li><i>Object.keys</i>(object) := array</li>\
+			<li>array.<i>forEach</i>(function(prop, index))</li>\
+			<li>array.<i>map</i>(function(prop, index)) := array</li>\
+			<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\
+		</ul>\
+		<p>Durante a execução da opção Refazer Requisição, um parâmetro extra chamado prev é passado para a função de transformação. Isso permite fazer comparações e marcações cumulativas</p>\
+		<p>Exemplo:<br>\
+		<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> irá retornar a carga média no primeiro nó do cluster no último minuto\
+		Essa informação pode ser inserida no Gráfico para fazer um gráfico de carga do nó\
+		"
+	});
+
+i18n.setKeys({
+	"AnyRequest.DisplayOptionsHelp" : "\
+		<p>Json Bruto: Exibe o resultado completo da consulta e da transformação no formato de JSON bruto</p>\
+		<p>Gráfico de Resultados: Para gerar um gráfico com seus resultados, utilize o tranformador de resultados para produzir um vetor de valores</p>\
+		<p>Tabela de Resultados da Consulta: Se sua consulta for uma busca, você pode exibir seus resultados no formato de uma tabela.</p>\
+		"
+});
+
+i18n.setKeys({
+	"QueryFilter.DateRangeHelp" : "\
+		<p>Campos do tipo Data aceitam consultas em linguagem natural (em inglês) para produzir um <i>From</i> e um <i>To</i> de modo a formar um intervalo dentro do qual os resultados são filtrados.</p>\
+		<p>Os seguintes formatos são suportados:</p>\
+		<ul>\
+			<li><b>Palavras-chave</b><br>\
+				<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\
+				buscam por datas de acordo com a palavra-chave. <code>last year</code> irá buscar tudo do último ano.</li>\
+			<li><b>Intervalos</b><br>\
+				<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (espaços são opcionais, diversos sinônimos para qualificadores de intervalo)<br>\
+				Cria um intervalo de busca a partir de agora (<code>now</code>), extendendo este intervalo no passado e no futuro de acordo com intervalo especificado.</li>\
+			<li><b>Data/Hora (<i>DateTime</i>) e Data/Hora parcial</b><br>\
+				<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\
+				esses formatos especificam um intervalo especifico. <code>2011</code> irá buscar todo o ano de 2011, enquanto <code>2011-01-18 12:32:45</code> irá buscar apenas por resultados dentro deste intervalo de 1 segundo</li>\
+			<li><b>Tempo (<i>Time</i>) e Tempo parcial</b><br>\
+				<code>12<br> 12:32<br> 12:32:45</code><br>\
+				esses formatos buscam por um horário específico no dia atual. <code>12:32</code> irá buscar este minuto específico do dia</li>\
+			<li><b>Intervalos de Data</b><br>\
+				<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\
+				Um intervalo de data é criado especificando-se duas datas em qualquer formato (Palavras-chave, Data/Hora ou Tempo) separados por &lt; ou -&gt; (ambos fazem a mesma coisa). Se a data de início ou fim do intervalo não for especificada é a mesma coisa que não impor limites na busca nesta direção.</li>\
+			<li><b>Intervalo de Data com Deslocamento</b><br>\
+				<code>2010 -> 1yr<br> 3mins < now</code>\
+				Busca a data especificada incluindo o intervalo na direção determinada pelo deslocamento</li>\
+			<li><b>Intervalos Bidirecionais</b><br>\
+				<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\
+				Idêntico ao exemplo anterior porém o intervalo é extendido em ambas as direções a partir da data especificada</li>\
+		</ul>\
+	"
+});

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/lang/zh_strings.js
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/lang/zh_strings.js b/elasticsearch-head/src/main/resources/lang/zh_strings.js
new file mode 100644
index 0000000..e9569d4
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/lang/zh_strings.js
@@ -0,0 +1,172 @@
+i18n.setKeys({
+	"General.Elasticsearch": "Elasticsearch",
+	"General.LoadingFacets": "加载聚合查询...",
+	"General.Searching": "搜索中...",
+	"General.Search": "搜索",
+	"General.Help": "帮助",
+	"General.HelpGlyph": "?",
+	"General.CloseGlyph": "X",
+	"General.RefreshResults": "刷新",
+	"General.ManualRefresh": "手动刷新",
+	"General.RefreshQuickly": "快速刷新",
+	"General.Refresh5seconds": "每5秒刷新",
+	"General.Refresh1minute": "每1分钟刷新",
+	"AliasForm.AliasName": "别名",
+	"AliasForm.NewAliasForIndex": "为 {0} 创建新别名",
+	"AliasForm.DeleteAliasMessage": "输入 ''{0}''  删除 {1}. 此操作无法恢复",
+	"AnyRequest.DisplayOptions" : "显示选项",
+	"AnyRequest.AsGraph" : "图形视图",
+	"AnyRequest.AsJson" : "原始 JSON",
+	"AnyRequest.AsTable" : "表格视图",
+	"AnyRequest.History" : "历史记录",
+	"AnyRequest.RepeatRequest" : "重复请求",
+	"AnyRequest.RepeatRequestSelect" : "重复周期 ",
+	"AnyRequest.Transformer" : "结果转换器",
+	"AnyRequest.Pretty": "易读",
+	"AnyRequest.Query" : "查询",
+	"AnyRequest.Request": "提交请求",
+	"AnyRequest.Requesting": "请求中...",
+	"AnyRequest.ValidateJSON": "验证 JSON",
+	"Browser.Title": "数据浏览",
+	"Browser.ResultSourcePanelTitle": "原始数据",
+	"Command.DELETE": "删除",
+	"Command.SHUTDOWN": "关闭",
+	"Command.DeleteAliasMessage": "删除别名?",
+	"ClusterOverView.IndexName": "索引名称",
+	"ClusterOverview.NumShards": "分片数",
+	"ClusterOverview.NumReplicas": "副本数",
+	"ClusterOverview.NewIndex": "新建索引",
+	"IndexActionsMenu.Title": "动作",
+	"IndexActionsMenu.NewAlias": "新建别名...",
+	"IndexActionsMenu.Refresh": "刷新",
+	"IndexActionsMenu.Flush": "Flush刷新",
+	"IndexActionsMenu.Optimize": "优化...",
+	"IndexActionsMenu.Snapshot": "网关快照",
+	"IndexActionsMenu.Analyser": "测试分析器",
+	"IndexActionsMenu.Open": "开启",
+	"IndexActionsMenu.Close": "关闭",
+	"IndexActionsMenu.Delete": "删除...",
+	"IndexInfoMenu.Title": "信息",
+	"IndexInfoMenu.Status": "索引状态",
+	"IndexInfoMenu.Metadata": "索引信息",
+	"IndexCommand.TextToAnalyze": "文本分析",
+	"IndexCommand.ShutdownMessage": "输入 ''{0}'' 以关闭 {1} 节点. 关闭的节点无法从此界面重新启动",
+	"IndexOverview.PageTitle": "索引概览",
+	"IndexSelector.NameWithDocs": "{0} ({1} 个文档)",
+	"IndexSelector.SearchIndexForDocs": "搜索 {0} 的文档, 查询条件:",
+	"FilterBrowser.OutputType": "返回格式: {0}",
+	"FilterBrowser.OutputSize": "显示数量: {0}",
+	"Header.ClusterHealth": "集群健康值: {0} ({1} of {2})",
+	"Header.ClusterNotConnected": "集群健康值: 未连接",
+	"Header.Connect": "连接",
+	"Nav.AnyRequest": "复合查询",
+	"Nav.Browser": "数据浏览",
+	"Nav.ClusterHealth": "集群健康值",
+	"Nav.ClusterState": "群集状态",
+	"Nav.ClusterNodes": "集群节点",
+	"Nav.Info": "信息",
+	"Nav.NodeStats": "节点状态",
+	"Nav.Overview": "概览",
+	"Nav.Indices": "索引",
+	"Nav.Plugins": "插件",
+	"Nav.Status": "状态",
+	"Nav.Templates": "模板",
+	"Nav.StructuredQuery": "基本查询",
+	"NodeActionsMenu.Title": "动作",
+	"NodeActionsMenu.Shutdown": "关停...",
+	"NodeInfoMenu.Title": "信息",
+	"NodeInfoMenu.ClusterNodeInfo": "集群节点信息",
+	"NodeInfoMenu.NodeStats": "节点状态",
+	"NodeType.Client": "节点客户端",
+	"NodeType.Coord": "协调器",
+	"NodeType.Master": "主节点",
+	"NodeType.Tribe": "分支结点",
+	"NodeType.Worker": "工作节点",
+	"NodeType.Unassigned": "未分配",
+	"OptimizeForm.OptimizeIndex": "优化 {0}",
+	"OptimizeForm.MaxSegments": "最大索引段数",
+	"OptimizeForm.ExpungeDeletes": "只删除被标记为删除的",
+	"OptimizeForm.FlushAfter": "优化后刷新",
+	"OptimizeForm.WaitForMerge": "等待合并",
+	"Overview.PageTitle" : "集群概览",
+	"Output.JSON": "JSON",
+	"Output.Table": "Table",
+	"Output.CSV": "CSV",
+	"Output.ShowSource": "显示查询语句",
+	"Preference.SortCluster": "集群排序",
+	"Sort.ByName": "按名称",
+	"Sort.ByAddress": "按地址",
+	"Sort.ByType": "按类型",
+	"TableResults.Summary": "查询 {1} 个分片中用的 {0} 个. {2} 命中. 耗时 {3} 秒",
+	"QueryFilter.AllIndices": "所有索引",
+	"QueryFilter.AnyValue": "任意",
+	"QueryFilter-Header-Indices": "索引",
+	"QueryFilter-Header-Types": "类型",
+	"QueryFilter-Header-Fields": "字段",
+	"QueryFilter.DateRangeHint.from": "从 : {0}",
+	"QueryFilter.DateRangeHint.to": "  到 : {0}",
+	"Query.FailAndUndo": "查询失败. 撤消最近的更改",
+	"StructuredQuery.ShowRawJson": "显示原始 JSON"
+});
+
+i18n.setKeys({
+	"AnyRequest.TransformerHelp" : "\
+		<p>结果转换器用于返回结果原始JSON的后续处理, 将结果转换为更有用的格式.</p>\
+		<p>转换器应当包含javascript函数体. 函数的返回值将传递给json分析器</p>\
+		<p>Example:<br>\
+		  <code>return root.hits.hits[0];</code><br>\
+		  遍历结果并只显示第一个元素<br>\
+		  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code><br>\
+		  将返回整个集群使用的总内存<br></p>\
+		<p>以下函数可以方便的处理数组与对象<br>\
+		<ul>\
+			<li><i>Object.keys</i>(object) := array</li>\
+			<li>array.<i>forEach</i>(function(prop, index))</li>\
+			<li>array.<i>map</i>(function(prop, index)) := array</li>\
+			<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\
+		</ul>\
+		<p>当启用重复请求时, prev 参数将会传递给转换器函数. 这将用于比较并累加图形</p>\
+		<p>Example:<br>\
+		<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code><br>\
+		将返回第一个集群节点最近一分钟内的平均负载\
+		将会把结果送人图表以产生一个负载曲线图\
+		"
+});
+
+i18n.setKeys({
+	"AnyRequest.DisplayOptionsHelp" : "\
+		<p>原始 Json: 将完整的查询结果转换为原始JSON格式 </p>\
+		<p>图形视图: 将查询结果图形化, 将查询结果转换为数组值的形式</p>\
+		<p>表格视图: 如果查询是一个搜索, 可以将搜索结果以表格形式显示.</p>\
+		"
+});
+
+i18n.setKeys({
+	"QueryFilter.DateRangeHelp" : "\
+		<p>Date 字段接受日期范围的形式查询.</p>\
+		<p>一下格式被支持:</p>\
+		<ul>\
+			<li><b>关键词 / 关键短语</b><br>\
+				<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\
+				搜索关键字匹配的日期. <code>last year</code> 将搜索过去全年.</li>\
+			<li><b>范围</b><br>\
+				<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (空格可选, 同等于多个范围修饰词)<br>\
+				创建一个指定时间范围的搜索, 将围绕<code>现在</code> 并延伸至过去与未来时间段.</li>\
+			<li><b>DateTime 与 DateTime局部</b><br>\
+				<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\
+				指定一个特定的日期范围. <code>2011</code>会搜索整个 2011年, 而 <code>2011-01-18 12:32:45</code> 将只搜索1秒范围内</li>\
+			<li><b>Time 与 Time局部</b><br>\
+				<code>12<br> 12:32<br> 12:32:45</code><br>\
+				这些格式只搜索当天的特定时间. <code>12:32</code> 将搜索当天的那一分钟</li>\
+			<li><b>日期范围</b><br>\
+				<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\
+				日期范围是将两个日期格式串 (日期关键字 / DateTime / Time) 用  &lt; 或 -&gt; (效果相同) 分隔. 如果缺少任意一端,那么在这个方向上时间将没有限制.</li>\
+			<li><b>偏移日期范围</b><br>\
+				<code>2010 -> 1yr<br> 3mins < now</code>\
+				搜索包括指定方向上偏移的日期.</li>\
+			<li><b>锚定范围</b><br>\
+				<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\
+				类似于上面的便宜日期,在两个方向上将锚定的日期延长</li>\
+		</ul>\
+	"
+});

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/c4719b9d/elasticsearch-head/src/main/resources/vendor.css
----------------------------------------------------------------------
diff --git a/elasticsearch-head/src/main/resources/vendor.css b/elasticsearch-head/src/main/resources/vendor.css
new file mode 100644
index 0000000..be7e15c
--- /dev/null
+++ b/elasticsearch-head/src/main/resources/vendor.css
@@ -0,0 +1,1338 @@
+/*!
+ *  Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+/* FONT PATH
+ * -------------------------- */
+@font-face {
+  font-family: 'FontAwesome';
+  src: url('fonts/fontawesome-webfont.eot?v=4.0.3');
+  src: url('fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'), url('fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+.fa {
+  display: inline-block;
+  font-family: FontAwesome;
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+/* makes the font 33% larger relative to the icon container */
+.fa-lg {
+  font-size: 1.3333333333333333em;
+  line-height: 0.75em;
+  vertical-align: -15%;
+}
+.fa-2x {
+  font-size: 2em;
+}
+.fa-3x {
+  font-size: 3em;
+}
+.fa-4x {
+  font-size: 4em;
+}
+.fa-5x {
+  font-size: 5em;
+}
+.fa-fw {
+  width: 1.2857142857142858em;
+  text-align: center;
+}
+.fa-ul {
+  padding-left: 0;
+  margin-left: 2.142857142857143em;
+  list-style-type: none;
+}
+.fa-ul > li {
+  position: relative;
+}
+.fa-li {
+  position: absolute;
+  left: -2.142857142857143em;
+  width: 2.142857142857143em;
+  top: 0.14285714285714285em;
+  text-align: center;
+}
+.fa-li.fa-lg {
+  left: -1.8571428571428572em;
+}
+.fa-border {
+  padding: .2em .25em .15em;
+  border: solid 0.08em #eeeeee;
+  border-radius: .1em;
+}
+.pull-right {
+  float: right;
+}
+.pull-left {
+  float: left;
+}
+.fa.pull-left {
+  margin-right: .3em;
+}
+.fa.pull-right {
+  margin-left: .3em;
+}
+.fa-spin {
+  -webkit-animation: spin 2s infinite linear;
+  -moz-animation: spin 2s infinite linear;
+  -o-animation: spin 2s infinite linear;
+  animation: spin 2s infinite linear;
+}
+@-moz-keyframes spin {
+  0% {
+    -moz-transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+  }
+}
+@-webkit-keyframes spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+  }
+}
+@-o-keyframes spin {
+  0% {
+    -o-transform: rotate(0deg);
+  }
+  100% {
+    -o-transform: rotate(359deg);
+  }
+}
+@-ms-keyframes spin {
+  0% {
+    -ms-transform: rotate(0deg);
+  }
+  100% {
+    -ms-transform: rotate(359deg);
+  }
+}
+@keyframes spin {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(359deg);
+  }
+}
+.fa-rotate-90 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
+  -webkit-transform: rotate(90deg);
+  -moz-transform: rotate(90deg);
+  -ms-transform: rotate(90deg);
+  -o-transform: rotate(90deg);
+  transform: rotate(90deg);
+}
+.fa-rotate-180 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  -webkit-transform: rotate(180deg);
+  -moz-transform: rotate(180deg);
+  -ms-transform: rotate(180deg);
+  -o-transform: rotate(180deg);
+  transform: rotate(180deg);
+}
+.fa-rotate-270 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
+  -webkit-transform: rotate(270deg);
+  -moz-transform: rotate(270deg);
+  -ms-transform: rotate(270deg);
+  -o-transform: rotate(270deg);
+  transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
+  -webkit-transform: scale(-1, 1);
+  -moz-transform: scale(-1, 1);
+  -ms-transform: scale(-1, 1);
+  -o-transform: scale(-1, 1);
+  transform: scale(-1, 1);
+}
+.fa-flip-vertical {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
+  -webkit-transform: scale(1, -1);
+  -moz-transform: scale(1, -1);
+  -ms-transform: scale(1, -1);
+  -o-transform: scale(1, -1);
+  transform: scale(1, -1);
+}
+.fa-stack {
+  position: relative;
+  display: inline-block;
+  width: 2em;
+  height: 2em;
+  line-height: 2em;
+  vertical-align: middle;
+}
+.fa-stack-1x,
+.fa-stack-2x {
+  position: absolute;
+  left: 0;
+  width: 100%;
+  text-align: center;
+}
+.fa-stack-1x {
+  line-height: inherit;
+}
+.fa-stack-2x {
+  font-size: 2em;
+}
+.fa-inverse {
+  color: #ffffff;
+}
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+   readers do not read off random characters that represent icons */
+.fa-glass:before {
+  content: "\f000";
+}
+.fa-music:before {
+  content: "\f001";
+}
+.fa-search:before {
+  content: "\f002";
+}
+.fa-envelope-o:before {
+  content: "\f003";
+}
+.fa-heart:before {
+  content: "\f004";
+}
+.fa-star:before {
+  content: "\f005";
+}
+.fa-star-o:before {
+  content: "\f006";
+}
+.fa-user:before {
+  content: "\f007";
+}
+.fa-film:before {
+  content: "\f008";
+}
+.fa-th-large:before {
+  content: "\f009";
+}
+.fa-th:before {
+  content: "\f00a";
+}
+.fa-th-list:before {
+  content: "\f00b";
+}
+.fa-check:before {
+  content: "\f00c";
+}
+.fa-times:before {
+  content: "\f00d";
+}
+.fa-search-plus:before {
+  content: "\f00e";
+}
+.fa-search-minus:before {
+  content: "\f010";
+}
+.fa-power-off:before {
+  content: "\f011";
+}
+.fa-signal:before {
+  content: "\f012";
+}
+.fa-gear:before,
+.fa-cog:before {
+  content: "\f013";
+}
+.fa-trash-o:before {
+  content: "\f014";
+}
+.fa-home:before {
+  content: "\f015";
+}
+.fa-file-o:before {
+  content: "\f016";
+}
+.fa-clock-o:before {
+  content: "\f017";
+}
+.fa-road:before {
+  content: "\f018";
+}
+.fa-download:before {
+  content: "\f019";
+}
+.fa-arrow-circle-o-down:before {
+  content: "\f01a";
+}
+.fa-arrow-circle-o-up:before {
+  content: "\f01b";
+}
+.fa-inbox:before {
+  content: "\f01c";
+}
+.fa-play-circle-o:before {
+  content: "\f01d";
+}
+.fa-rotate-right:before,
+.fa-repeat:before {
+  content: "\f01e";
+}
+.fa-refresh:before {
+  content: "\f021";
+}
+.fa-list-alt:before {
+  content: "\f022";
+}
+.fa-lock:before {
+  content: "\f023";
+}
+.fa-flag:before {
+  content: "\f024";
+}
+.fa-headphones:before {
+  content: "\f025";
+}
+.fa-volume-off:before {
+  content: "\f026";
+}
+.fa-volume-down:before {
+  content: "\f027";
+}
+.fa-volume-up:before {
+  content: "\f028";
+}
+.fa-qrcode:before {
+  content: "\f029";
+}
+.fa-barcode:before {
+  content: "\f02a";
+}
+.fa-tag:before {
+  content: "\f02b";
+}
+.fa-tags:before {
+  content: "\f02c";
+}
+.fa-book:before {
+  content: "\f02d";
+}
+.fa-bookmark:before {
+  content: "\f02e";
+}
+.fa-print:before {
+  content: "\f02f";
+}
+.fa-camera:before {
+  content: "\f030";
+}
+.fa-font:before {
+  content: "\f031";
+}
+.fa-bold:before {
+  content: "\f032";
+}
+.fa-italic:before {
+  content: "\f033";
+}
+.fa-text-height:before {
+  content: "\f034";
+}
+.fa-text-width:before {
+  content: "\f035";
+}
+.fa-align-left:before {
+  content: "\f036";
+}
+.fa-align-center:before {
+  content: "\f037";
+}
+.fa-align-right:before {
+  content: "\f038";
+}
+.fa-align-justify:before {
+  content: "\f039";
+}
+.fa-list:before {
+  content: "\f03a";
+}
+.fa-dedent:before,
+.fa-outdent:before {
+  content: "\f03b";
+}
+.fa-indent:before {
+  content: "\f03c";
+}
+.fa-video-camera:before {
+  content: "\f03d";
+}
+.fa-picture-o:before {
+  content: "\f03e";
+}
+.fa-pencil:before {
+  content: "\f040";
+}
+.fa-map-marker:before {
+  content: "\f041";
+}
+.fa-adjust:before {
+  content: "\f042";
+}
+.fa-tint:before {
+  content: "\f043";
+}
+.fa-edit:before,
+.fa-pencil-square-o:before {
+  content: "\f044";
+}
+.fa-share-square-o:before {
+  content: "\f045";
+}
+.fa-check-square-o:before {
+  content: "\f046";
+}
+.fa-arrows:before {
+  content: "\f047";
+}
+.fa-step-backward:before {
+  content: "\f048";
+}
+.fa-fast-backward:before {
+  content: "\f049";
+}
+.fa-backward:before {
+  content: "\f04a";
+}
+.fa-play:before {
+  content: "\f04b";
+}
+.fa-pause:before {
+  content: "\f04c";
+}
+.fa-stop:before {
+  content: "\f04d";
+}
+.fa-forward:before {
+  content: "\f04e";
+}
+.fa-fast-forward:before {
+  content: "\f050";
+}
+.fa-step-forward:before {
+  content: "\f051";
+}
+.fa-eject:before {
+  content: "\f052";
+}
+.fa-chevron-left:before {
+  content: "\f053";
+}
+.fa-chevron-right:before {
+  content: "\f054";
+}
+.fa-plus-circle:before {
+  content: "\f055";
+}
+.fa-minus-circle:before {
+  content: "\f056";
+}
+.fa-times-circle:before {
+  content: "\f057";
+}
+.fa-check-circle:before {
+  content: "\f058";
+}
+.fa-question-circle:before {
+  content: "\f059";
+}
+.fa-info-circle:before {
+  content: "\f05a";
+}
+.fa-crosshairs:before {
+  content: "\f05b";
+}
+.fa-times-circle-o:before {
+  content: "\f05c";
+}
+.fa-check-circle-o:before {
+  content: "\f05d";
+}
+.fa-ban:before {
+  content: "\f05e";
+}
+.fa-arrow-left:before {
+  content: "\f060";
+}
+.fa-arrow-right:before {
+  content: "\f061";
+}
+.fa-arrow-up:before {
+  content: "\f062";
+}
+.fa-arrow-down:before {
+  content: "\f063";
+}
+.fa-mail-forward:before,
+.fa-share:before {
+  content: "\f064";
+}
+.fa-expand:before {
+  content: "\f065";
+}
+.fa-compress:before {
+  content: "\f066";
+}
+.fa-plus:before {
+  content: "\f067";
+}
+.fa-minus:before {
+  content: "\f068";
+}
+.fa-asterisk:before {
+  content: "\f069";
+}
+.fa-exclamation-circle:before {
+  content: "\f06a";
+}
+.fa-gift:before {
+  content: "\f06b";
+}
+.fa-leaf:before {
+  content: "\f06c";
+}
+.fa-fire:before {
+  content: "\f06d";
+}
+.fa-eye:before {
+  content: "\f06e";
+}
+.fa-eye-slash:before {
+  content: "\f070";
+}
+.fa-warning:before,
+.fa-exclamation-triangle:before {
+  content: "\f071";
+}
+.fa-plane:before {
+  content: "\f072";
+}
+.fa-calendar:before {
+  content: "\f073";
+}
+.fa-random:before {
+  content: "\f074";
+}
+.fa-comment:before {
+  content: "\f075";
+}
+.fa-magnet:before {
+  content: "\f076";
+}
+.fa-chevron-up:before {
+  content: "\f077";
+}
+.fa-chevron-down:before {
+  content: "\f078";
+}
+.fa-retweet:before {
+  content: "\f079";
+}
+.fa-shopping-cart:before {
+  content: "\f07a";
+}
+.fa-folder:before {
+  content: "\f07b";
+}
+.fa-folder-open:before {
+  content: "\f07c";
+}
+.fa-arrows-v:before {
+  content: "\f07d";
+}
+.fa-arrows-h:before {
+  content: "\f07e";
+}
+.fa-bar-chart-o:before {
+  content: "\f080";
+}
+.fa-twitter-square:before {
+  content: "\f081";
+}
+.fa-facebook-square:before {
+  content: "\f082";
+}
+.fa-camera-retro:before {
+  content: "\f083";
+}
+.fa-key:before {
+  content: "\f084";
+}
+.fa-gears:before,
+.fa-cogs:before {
+  content: "\f085";
+}
+.fa-comments:before {
+  content: "\f086";
+}
+.fa-thumbs-o-up:before {
+  content: "\f087";
+}
+.fa-thumbs-o-down:before {
+  content: "\f088";
+}
+.fa-star-half:before {
+  content: "\f089";
+}
+.fa-heart-o:before {
+  content: "\f08a";
+}
+.fa-sign-out:before {
+  content: "\f08b";
+}
+.fa-linkedin-square:before {
+  content: "\f08c";
+}
+.fa-thumb-tack:before {
+  content: "\f08d";
+}
+.fa-external-link:before {
+  content: "\f08e";
+}
+.fa-sign-in:before {
+  content: "\f090";
+}
+.fa-trophy:before {
+  content: "\f091";
+}
+.fa-github-square:before {
+  content: "\f092";
+}
+.fa-upload:before {
+  content: "\f093";
+}
+.fa-lemon-o:before {
+  content: "\f094";
+}
+.fa-phone:before {
+  content: "\f095";
+}
+.fa-square-o:before {
+  content: "\f096";
+}
+.fa-bookmark-o:before {
+  content: "\f097";
+}
+.fa-phone-square:before {
+  content: "\f098";
+}
+.fa-twitter:before {
+  content: "\f099";
+}
+.fa-facebook:before {
+  content: "\f09a";
+}
+.fa-github:before {
+  content: "\f09b";
+}
+.fa-unlock:before {
+  content: "\f09c";
+}
+.fa-credit-card:before {
+  content: "\f09d";
+}
+.fa-rss:before {
+  content: "\f09e";
+}
+.fa-hdd-o:before {
+  content: "\f0a0";
+}
+.fa-bullhorn:before {
+  content: "\f0a1";
+}
+.fa-bell:before {
+  content: "\f0f3";
+}
+.fa-certificate:before {
+  content: "\f0a3";
+}
+.fa-hand-o-right:before {
+  content: "\f0a4";
+}
+.fa-hand-o-left:before {
+  content: "\f0a5";
+}
+.fa-hand-o-up:before {
+  content: "\f0a6";
+}
+.fa-hand-o-down:before {
+  content: "\f0a7";
+}
+.fa-arrow-circle-left:before {
+  content: "\f0a8";
+}
+.fa-arrow-circle-right:before {
+  content: "\f0a9";
+}
+.fa-arrow-circle-up:before {
+  content: "\f0aa";
+}
+.fa-arrow-circle-down:before {
+  content: "\f0ab";
+}
+.fa-globe:before {
+  content: "\f0ac";
+}
+.fa-wrench:before {
+  content: "\f0ad";
+}
+.fa-tasks:before {
+  content: "\f0ae";
+}
+.fa-filter:before {
+  content: "\f0b0";
+}
+.fa-briefcase:before {
+  content: "\f0b1";
+}
+.fa-arrows-alt:before {
+  content: "\f0b2";
+}
+.fa-group:before,
+.fa-users:before {
+  content: "\f0c0";
+}
+.fa-chain:before,
+.fa-link:before {
+  content: "\f0c1";
+}
+.fa-cloud:before {
+  content: "\f0c2";
+}
+.fa-flask:before {
+  content: "\f0c3";
+}
+.fa-cut:before,
+.fa-scissors:before {
+  content: "\f0c4";
+}
+.fa-copy:before,
+.fa-files-o:before {
+  content: "\f0c5";
+}
+.fa-paperclip:before {
+  content: "\f0c6";
+}
+.fa-save:before,
+.fa-floppy-o:before {
+  content: "\f0c7";
+}
+.fa-square:before {
+  content: "\f0c8";
+}
+.fa-bars:before {
+  content: "\f0c9";
+}
+.fa-list-ul:before {
+  content: "\f0ca";
+}
+.fa-list-ol:before {
+  content: "\f0cb";
+}
+.fa-strikethrough:before {
+  content: "\f0cc";
+}
+.fa-underline:before {
+  content: "\f0cd";
+}
+.fa-table:before {
+  content: "\f0ce";
+}
+.fa-magic:before {
+  content: "\f0d0";
+}
+.fa-truck:before {
+  content: "\f0d1";
+}
+.fa-pinterest:before {
+  content: "\f0d2";
+}
+.fa-pinterest-square:before {
+  content: "\f0d3";
+}
+.fa-google-plus-square:before {
+  content: "\f0d4";
+}
+.fa-google-plus:before {
+  content: "\f0d5";
+}
+.fa-money:before {
+  content: "\f0d6";
+}
+.fa-caret-down:before {
+  content: "\f0d7";
+}
+.fa-caret-up:before {
+  content: "\f0d8";
+}
+.fa-caret-left:before {
+  content: "\f0d9";
+}
+.fa-caret-right:before {
+  content: "\f0da";
+}
+.fa-columns:before {
+  content: "\f0db";
+}
+.fa-unsorted:before,
+.fa-sort:before {
+  content: "\f0dc";
+}
+.fa-sort-down:before,
+.fa-sort-asc:before {
+  content: "\f0dd";
+}
+.fa-sort-up:before,
+.fa-sort-desc:before {
+  content: "\f0de";
+}
+.fa-envelope:before {
+  content: "\f0e0";
+}
+.fa-linkedin:before {
+  content: "\f0e1";
+}
+.fa-rotate-left:before,
+.fa-undo:before {
+  content: "\f0e2";
+}
+.fa-legal:before,
+.fa-gavel:before {
+  content: "\f0e3";
+}
+.fa-dashboard:before,
+.fa-tachometer:before {
+  content: "\f0e4";
+}
+.fa-comment-o:before {
+  content: "\f0e5";
+}
+.fa-comments-o:before {
+  content: "\f0e6";
+}
+.fa-flash:before,
+.fa-bolt:before {
+  content: "\f0e7";
+}
+.fa-sitemap:before {
+  content: "\f0e8";
+}
+.fa-umbrella:before {
+  content: "\f0e9";
+}
+.fa-paste:before,
+.fa-clipboard:before {
+  content: "\f0ea";
+}
+.fa-lightbulb-o:before {
+  content: "\f0eb";
+}
+.fa-exchange:before {
+  content: "\f0ec";
+}
+.fa-cloud-download:before {
+  content: "\f0ed";
+}
+.fa-cloud-upload:before {
+  content: "\f0ee";
+}
+.fa-user-md:before {
+  content: "\f0f0";
+}
+.fa-stethoscope:before {
+  content: "\f0f1";
+}
+.fa-suitcase:before {
+  content: "\f0f2";
+}
+.fa-bell-o:before {
+  content: "\f0a2";
+}
+.fa-coffee:before {
+  content: "\f0f4";
+}
+.fa-cutlery:before {
+  content: "\f0f5";
+}
+.fa-file-text-o:before {
+  content: "\f0f6";
+}
+.fa-building-o:before {
+  content: "\f0f7";
+}
+.fa-hospital-o:before {
+  content: "\f0f8";
+}
+.fa-ambulance:before {
+  content: "\f0f9";
+}
+.fa-medkit:before {
+  content: "\f0fa";
+}
+.fa-fighter-jet:before {
+  content: "\f0fb";
+}
+.fa-beer:before {
+  content: "\f0fc";
+}
+.fa-h-square:before {
+  content: "\f0fd";
+}
+.fa-plus-square:before {
+  content: "\f0fe";
+}
+.fa-angle-double-left:before {
+  content: "\f100";
+}
+.fa-angle-double-right:before {
+  content: "\f101";
+}
+.fa-angle-double-up:before {
+  content: "\f102";
+}
+.fa-angle-double-down:before {
+  content: "\f103";
+}
+.fa-angle-left:before {
+  content: "\f104";
+}
+.fa-angle-right:before {
+  content: "\f105";
+}
+.fa-angle-up:before {
+  content: "\f106";
+}
+.fa-angle-down:before {
+  content: "\f107";
+}
+.fa-desktop:before {
+  content: "\f108";
+}
+.fa-laptop:before {
+  content: "\f109";
+}
+.fa-tablet:before {
+  content: "\f10a";
+}
+.fa-mobile-phone:before,
+.fa-mobile:before {
+  content: "\f10b";
+}
+.fa-circle-o:before {
+  content: "\f10c";
+}
+.fa-quote-left:before {
+  content: "\f10d";
+}
+.fa-quote-right:before {
+  content: "\f10e";
+}
+.fa-spinner:before {
+  content: "\f110";
+}
+.fa-circle:before {
+  content: "\f111";
+}
+.fa-mail-reply:before,
+.fa-reply:before {
+  content: "\f112";
+}
+.fa-github-alt:before {
+  content: "\f113";
+}
+.fa-folder-o:before {
+  content: "\f114";
+}
+.fa-folder-open-o:before {
+  content: "\f115";
+}
+.fa-smile-o:before {
+  content: "\f118";
+}
+.fa-frown-o:before {
+  content: "\f119";
+}
+.fa-meh-o:before {
+  content: "\f11a";
+}
+.fa-gamepad:before {
+  content: "\f11b";
+}
+.fa-keyboard-o:before {
+  content: "\f11c";
+}
+.fa-flag-o:before {
+  content: "\f11d";
+}
+.fa-flag-checkered:before {
+  content: "\f11e";
+}
+.fa-terminal:before {
+  content: "\f120";
+}
+.fa-code:before {
+  content: "\f121";
+}
+.fa-reply-all:before {
+  content: "\f122";
+}
+.fa-mail-reply-all:before {
+  content: "\f122";
+}
+.fa-star-half-empty:before,
+.fa-star-half-full:before,
+.fa-star-half-o:before {
+  content: "\f123";
+}
+.fa-location-arrow:before {
+  content: "\f124";
+}
+.fa-crop:before {
+  content: "\f125";
+}
+.fa-code-fork:before {
+  content: "\f126";
+}
+.fa-unlink:before,
+.fa-chain-broken:before {
+  content: "\f127";
+}
+.fa-question:before {
+  content: "\f128";
+}
+.fa-info:before {
+  content: "\f129";
+}
+.fa-exclamation:before {
+  content: "\f12a";
+}
+.fa-superscript:before {
+  content: "\f12b";
+}
+.fa-subscript:before {
+  content: "\f12c";
+}
+.fa-eraser:before {
+  content: "\f12d";
+}
+.fa-puzzle-piece:before {
+  content: "\f12e";
+}
+.fa-microphone:before {
+  content: "\f130";
+}
+.fa-microphone-slash:before {
+  content: "\f131";
+}
+.fa-shield:before {
+  content: "\f132";
+}
+.fa-calendar-o:before {
+  content: "\f133";
+}
+.fa-fire-extinguisher:before {
+  content: "\f134";
+}
+.fa-rocket:before {
+  content: "\f135";
+}
+.fa-maxcdn:before {
+  content: "\f136";
+}
+.fa-chevron-circle-left:before {
+  content: "\f137";
+}
+.fa-chevron-circle-right:before {
+  content: "\f138";
+}
+.fa-chevron-circle-up:before {
+  content: "\f139";
+}
+.fa-chevron-circle-down:before {
+  content: "\f13a";
+}
+.fa-html5:before {
+  content: "\f13b";
+}
+.fa-css3:before {
+  content: "\f13c";
+}
+.fa-anchor:before {
+  content: "\f13d";
+}
+.fa-unlock-alt:before {
+  content: "\f13e";
+}
+.fa-bullseye:before {
+  content: "\f140";
+}
+.fa-ellipsis-h:before {
+  content: "\f141";
+}
+.fa-ellipsis-v:before {
+  content: "\f142";
+}
+.fa-rss-square:before {
+  content: "\f143";
+}
+.fa-play-circle:before {
+  content: "\f144";
+}
+.fa-ticket:before {
+  content: "\f145";
+}
+.fa-minus-square:before {
+  content: "\f146";
+}
+.fa-minus-square-o:before {
+  content: "\f147";
+}
+.fa-level-up:before {
+  content: "\f148";
+}
+.fa-level-down:before {
+  content: "\f149";
+}
+.fa-check-square:before {
+  content: "\f14a";
+}
+.fa-pencil-square:before {
+  content: "\f14b";
+}
+.fa-external-link-square:before {
+  content: "\f14c";
+}
+.fa-share-square:before {
+  content: "\f14d";
+}
+.fa-compass:before {
+  content: "\f14e";
+}
+.fa-toggle-down:before,
+.fa-caret-square-o-down:before {
+  content: "\f150";
+}
+.fa-toggle-up:before,
+.fa-caret-square-o-up:before {
+  content: "\f151";
+}
+.fa-toggle-right:before,
+.fa-caret-square-o-right:before {
+  content: "\f152";
+}
+.fa-euro:before,
+.fa-eur:before {
+  content: "\f153";
+}
+.fa-gbp:before {
+  content: "\f154";
+}
+.fa-dollar:before,
+.fa-usd:before {
+  content: "\f155";
+}
+.fa-rupee:before,
+.fa-inr:before {
+  content: "\f156";
+}
+.fa-cny:before,
+.fa-rmb:before,
+.fa-yen:before,
+.fa-jpy:before {
+  content: "\f157";
+}
+.fa-ruble:before,
+.fa-rouble:before,
+.fa-rub:before {
+  content: "\f158";
+}
+.fa-won:before,
+.fa-krw:before {
+  content: "\f159";
+}
+.fa-bitcoin:before,
+.fa-btc:before {
+  content: "\f15a";
+}
+.fa-file:before {
+  content: "\f15b";
+}
+.fa-file-text:before {
+  content: "\f15c";
+}
+.fa-sort-alpha-asc:before {
+  content: "\f15d";
+}
+.fa-sort-alpha-desc:before {
+  content: "\f15e";
+}
+.fa-sort-amount-asc:before {
+  content: "\f160";
+}
+.fa-sort-amount-desc:before {
+  content: "\f161";
+}
+.fa-sort-numeric-asc:before {
+  content: "\f162";
+}
+.fa-sort-numeric-desc:before {
+  content: "\f163";
+}
+.fa-thumbs-up:before {
+  content: "\f164";
+}
+.fa-thumbs-down:before {
+  content: "\f165";
+}
+.fa-youtube-square:before {
+  content: "\f166";
+}
+.fa-youtube:before {
+  content: "\f167";
+}
+.fa-xing:before {
+  content: "\f168";
+}
+.fa-xing-square:before {
+  content: "\f169";
+}
+.fa-youtube-play:before {
+  content: "\f16a";
+}
+.fa-dropbox:before {
+  content: "\f16b";
+}
+.fa-stack-overflow:before {
+  content: "\f16c";
+}
+.fa-instagram:before {
+  content: "\f16d";
+}
+.fa-flickr:before {
+  content: "\f16e";
+}
+.fa-adn:before {
+  content: "\f170";
+}
+.fa-bitbucket:before {
+  content: "\f171";
+}
+.fa-bitbucket-square:before {
+  content: "\f172";
+}
+.fa-tumblr:before {
+  content: "\f173";
+}
+.fa-tumblr-square:before {
+  content: "\f174";
+}
+.fa-long-arrow-down:before {
+  content: "\f175";
+}
+.fa-long-arrow-up:before {
+  content: "\f176";
+}
+.fa-long-arrow-left:before {
+  content: "\f177";
+}
+.fa-long-arrow-right:before {
+  content: "\f178";
+}
+.fa-apple:before {
+  content: "\f179";
+}
+.fa-windows:before {
+  content: "\f17a";
+}
+.fa-android:before {
+  content: "\f17b";
+}
+.fa-linux:before {
+  content: "\f17c";
+}
+.fa-dribbble:before {
+  content: "\f17d";
+}
+.fa-skype:before {
+  content: "\f17e";
+}
+.fa-foursquare:before {
+  content: "\f180";
+}
+.fa-trello:before {
+  content: "\f181";
+}
+.fa-female:before {
+  content: "\f182";
+}
+.fa-male:before {
+  content: "\f183";
+}
+.fa-gittip:before {
+  content: "\f184";
+}
+.fa-sun-o:before {
+  content: "\f185";
+}
+.fa-moon-o:before {
+  content: "\f186";
+}
+.fa-archive:before {
+  content: "\f187";
+}
+.fa-bug:before {
+  content: "\f188";
+}
+.fa-vk:before {
+  content: "\f189";
+}
+.fa-weibo:before {
+  content: "\f18a";
+}
+.fa-renren:before {
+  content: "\f18b";
+}
+.fa-pagelines:before {
+  content: "\f18c";
+}
+.fa-stack-exchange:before {
+  content: "\f18d";
+}
+.fa-arrow-circle-o-right:before {
+  content: "\f18e";
+}
+.fa-arrow-circle-o-left:before {
+  content: "\f190";
+}
+.fa-toggle-left:before,
+.fa-caret-square-o-left:before {
+  content: "\f191";
+}
+.fa-dot-circle-o:before {
+  content: "\f192";
+}
+.fa-wheelchair:before {
+  content: "\f193";
+}
+.fa-vimeo-square:before {
+  content: "\f194";
+}
+.fa-turkish-lira:before,
+.fa-try:before {
+  content: "\f195";
+}
+.fa-plus-square-o:before {
+  content: "\f196";
+}