You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/02/18 11:36:53 UTC

[01/27] brooklyn-ui git commit: tweak buttons for composer, following @tbouron and @hellberg suggestions

Repository: brooklyn-ui
Updated Branches:
  refs/heads/master c2e374eb8 -> b9ba6544d


tweak buttons for composer, following @tbouron and @hellberg suggestions

also adjust height w custom codemirror styling


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/4cd4fead
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/4cd4fead
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/4cd4fead

Branch: refs/heads/master
Commit: 4cd4fead9ee387768e9e6a017a351eaef094d135
Parents: d67739c
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 17:35:41 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 .../webapp/assets/css/codemirror-brooklyn.css   | 29 ++++++++
 src/main/webapp/assets/js/view/editor.js        | 78 ++++++++++++--------
 src/main/webapp/assets/tpl/editor/page.html     | 36 +++++++--
 src/main/webapp/index.html                      |  1 +
 4 files changed, 108 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/4cd4fead/src/main/webapp/assets/css/codemirror-brooklyn.css
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/css/codemirror-brooklyn.css b/src/main/webapp/assets/css/codemirror-brooklyn.css
new file mode 100644
index 0000000..c293ed4
--- /dev/null
+++ b/src/main/webapp/assets/css/codemirror-brooklyn.css
@@ -0,0 +1,29 @@
+/*
+ * 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.
+*/
+
+/* overrides for brooklyn */
+
+.CodeMirror {
+  height: auto;
+}
+.CodeMirror-scroll {
+  min-height: 480px;
+}
+.CodeMirror .CodeMirror-gutter.CodeMirror-linenumbers {
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/4cd4fead/src/main/webapp/assets/js/view/editor.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/editor.js b/src/main/webapp/assets/js/view/editor.js
index 1b4dce3..f9ce5b6 100644
--- a/src/main/webapp/assets/js/view/editor.js
+++ b/src/main/webapp/assets/js/view/editor.js
@@ -60,8 +60,8 @@ define([
         events: {
             'click #button-run':'runBlueprint',
             'click #button-delete':'removeBlueprint',
-            'click #button-convert':'convertBlueprint',
-            'click #button-switch':'switchMode',
+            'click #button-switch-app':'switchModeApp',
+            'click #button-switch-catalog':'switchModeCatalog',
             'click #button-example':'populateExampleBlueprint',
         },
         editorTemplate:_.template(EditorHtml),
@@ -99,36 +99,39 @@ define([
         },
         refresh: function() {
             $("#button-run", this.$el).html(this.mode==MODE_CATALOG ? "Add to Catalog" : "Deploy");
-            $("#button-delete", this.$el).html("Clear");
-            $("#button-example", this.$el).html(this.mode==MODE_CATALOG ? "Insert Catalog Example" : "Insert Blueprint Example");
-            $("#button-switch", this.$el).html(this.mode==MODE_CATALOG ? "Switch to Application Blueprint Mode" : "Switch to Catalog Mode");
+            if (this.mode==MODE_CATALOG) {
+                $("#button-switch-catalog", this.$el).addClass('active')
+                $("#button-switch-app", this.$el).removeClass('active')
+            } else {
+                $("#button-switch-app", this.$el).addClass('active')
+                $("#button-switch-catalog", this.$el).removeClass('active')
+            }
             this.refreshOnMinorChange();
         },
         refreshOnMinorChange: function() {
             var yaml = this.editor && this.editor.getValue();
             var parse = this.parse();
             
-            if (!yaml || parse.problem || this.mode==MODE_CATALOG) {
-                $("#button-convert", this.$el).hide();
+            // fine to switch to catalog
+            /* always enable the switch to app button -- worst case it's invalid
+            if (this.mode==MODE_CATALOG && yaml && (parse.problem || parse.result['brooklyn.catalog']) {
+                $("#button-switch-app", this.$el).attr('disabled', 'disabled');
             } else {
-                $("#button-convert", this.$el).html("Convert to Catalog Item");
-                $("#button-convert", this.$el).show();
+                $("#button-switch-app", this.$el).attr('disabled', false);
             }
+            */
             
             if (!yaml) {
                 // no yaml
                 $("#button-run", this.$el).attr('disabled','disabled');
-                $("#button-delete", this.$el).hide();
-                // example and switch mode only shown when empty
+                $("#button-delete", this.$el).attr('disabled','disabled');
+                // example only shown when empty
                 $("#button-example", this.$el).show();
-                $("#button-switch", this.$el).show();
             } else {
-                $("#button-run", this.$el).attr('disabled','false');
+                $("#button-run", this.$el).attr('disabled',false);
                 // we have yaml
-                $("#button-run", this.$el).show();
-                $("#button-delete", this.$el).show();
+                $("#button-delete", this.$el).attr('disabled',false);
                 $("#button-example", this.$el).hide();
-                $("#button-switch", this.$el).hide();
             }
         },
         initializeEditor: function() {
@@ -167,6 +170,7 @@ define([
             if (this.editor == null) {
                 this.editor = CodeMirror.fromTextArea(this.$("#yaml_code")[0], {
                     lineNumbers: true,
+                    viewportMargin: Infinity, /* recommended if height auto */
                     extraKeys: {"Ctrl-Space": "autocomplete"},
                     mode: {
                         name: "yaml",
@@ -205,28 +209,33 @@ define([
             var yaml = this.editor.getValue();
             try{
                 var parsed = this.parse(true);
+                console.log('parse', parsed);
                 if (parsed.problem) throw parsed.problem;
+                if (this.mode!=MODE_CATALOG && parsed.result['brooklyn.catalog'] &&
+                      !parsed.result['services']) {
+                    console.log("This document is using brooklyn.catalog syntax but you are attempting to deploy it.");
+                    throw "This document is using brooklyn.catalog syntax but you are attempting to deploy it."; 
+                }
                 return true;
             }catch (e){
-                this.showFailure(e.message);
+                this.showFailure(e.message || e);
                 return false;
             }
         },
-        convertBlueprint: function() {
-            if (this.mode === MODE_CATALOG) {
-                // not yet supported
-            } else {
+        convertBlueprintToCatalog: function() {
+            if (this.mode === MODE_APP && this.lastParse && !this.lastParse.problems && this.lastParse.result && this.lastParse.result['services']) {
+                // convert to catalog syntax if it has services at the root
                 var newBlueprint = "brooklyn.catalog:\n"+
                     "  version: 0.0.1\n"+
-                    "    items:\n"+
-                    "    - id: TODO_identifier_for_this_item \n"+
-                    "      description: Some text to display about this\n"+
-                    "      iconUrl: http://www.apache.org/foundation/press/kit/poweredBy/Apache_PoweredBy.png\n"+
-                    "      itemType: template\n"+
-                    "      item:\n"+
-                    "      - \n"+
-                    // indent 8 spaces:
-                    this.editor.getValue().replace(/(\n|^)(.*\n|.+$)/gm,'        $1$2');
+                    "  items:\n"+
+                    "  - id: TODO_identifier_for_this_item \n"+
+                    "    description: Some text to display about this\n"+
+                    "    iconUrl: http://www.apache.org/foundation/press/kit/poweredBy/Apache_PoweredBy.png\n"+
+                    "    itemType: template\n"+
+                    "    item:\n"+
+                    "    - \n"+
+                // indent 6 spaces:
+                this.editor.getValue().replace(/^(.*$)/gm,'      $1');
                 this.mode = MODE_CATALOG;
                 this.editor.setValue(newBlueprint);
                 this.refresh();
@@ -247,6 +256,15 @@ define([
         switchMode: function() {
             this.setMode(this.mode == MODE_CATALOG ? MODE_APP : MODE_CATALOG);
         },
+        switchModeApp: function() { this.setMode(MODE_APP); },
+        switchModeCatalog: function() {
+            var plan = this.parse().result;
+            if (plan && plan.services) {
+                this.convertBlueprintToCatalog();
+            } else { 
+                this.setMode(MODE_CATALOG);
+            } 
+        },
         populateExampleBlueprint: function() {
             this.editor.setValue(this.mode==MODE_CATALOG ? _DEFAULT_CATALOG : _DEFAULT_BLUEPRINT);
         },

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/4cd4fead/src/main/webapp/assets/tpl/editor/page.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/editor/page.html b/src/main/webapp/assets/tpl/editor/page.html
index fb4410b..67bb09c 100644
--- a/src/main/webapp/assets/tpl/editor/page.html
+++ b/src/main/webapp/assets/tpl/editor/page.html
@@ -21,14 +21,26 @@ under the License.
         <div class="span12 composer" id="composer">
             <div class="navbar_top">
                 <h3 style="margin-top: 6px;">Blueprint Composer</h3>
-                <div class="apps-tree-toolbar" style="margin-top: -24px !important;">
-                    <!-- text will be changed by JS -->
-                    <button id="button-convert" class="btn btn-sm">Convert</button>
-                    <button id="button-switch" class="btn btn-sm">Switch</button>
-                    <button id="button-example" class="btn btn-sm">Insert Example</button>
+                <div class="apps-tree-toolbar btn-toolbar" style="margin-top: -24px !important;">
+                    <span class="btn-group">
+                    <button id="button-example" class="btn btn-sm" style="margin-right: 12px;">Insert Example</button>
+                    </span>
+                    
+                    <!-- no need for this
+                    <span class="btn-group">
                     <button id="button-delete" class="btn btn-danger btn-sm">Clear</button>
+                    </span>
+                    -->
                     
-                    <button id="button-run" class="btn btn-success btn-sm" style="margin-left: 36px;">Run</button>
+                    <span class="btn-group" role="group">
+                        <button id="button-switch-app" class="btn btn-sm">Application</button>
+                        <button id="button-switch-catalog" class="btn btn-sm">Catalog</button>
+                    </span>
+                    
+                    <!-- text will be changed by JS -->
+                    <span class="btn-group" style="width: 12em;">
+                            <button id="button-run" class="btn btn-success btn-sm" style="margin-left: 24px; float: right;">Go</button>
+                    </span>
                 </div>
             </div>
             <div class="navbar_main_wrapper">
@@ -45,6 +57,18 @@ under the License.
                     </div>
                 </div>
             </div>
+            <div class="navbar_main_wrapper" style="background-color: #f0f0f0 !important;">
+                <div class="apps-tree-toolbar btn-toolbar" style="margin: 9px 12px 6px 12px !important; float: none;">
+                    <span class="btn-group" style="float: left;">
+                        <button id="button-delete" class="btn btn-danger btn-sm">Clear</button>
+                    </span>
+                    
+                    <!-- text will be changed by JS -->
+                    <span class="btn-group" style="width: 12em;">
+                            <button id="button-run" class="btn btn-success btn-sm" style="margin-left: 24px; float: right;">Go</button>
+                    </span>
+                </div>
+            </div>
         </div>
     </div>
 </div>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/4cd4fead/src/main/webapp/index.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html
index 40ffd04..3570ca9 100644
--- a/src/main/webapp/index.html
+++ b/src/main/webapp/index.html
@@ -27,6 +27,7 @@
     <title>Brooklyn JS REST client</title>
 
     <link rel="stylesheet" href="/assets/css/codemirror.css">
+    <link rel="stylesheet" href="/assets/css/codemirror-brooklyn.css">
     <link rel="stylesheet" href="/assets/css/show-hint.css">
     <link rel="stylesheet" href="/assets/css/styles.css">
     <link rel="stylesheet" href="/assets/css/brooklyn.css">


[22/27] brooklyn-ui git commit: tell people about code completion.

Posted by he...@apache.org.
tell people about code completion.


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/500b5fa8
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/500b5fa8
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/500b5fa8

Branch: refs/heads/master
Commit: 500b5fa8eba2e9fd4d4c665bd73380362cd163f6
Parents: d4d88aa
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Feb 16 17:49:16 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Feb 16 17:49:16 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/tpl/editor/page.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/500b5fa8/src/main/webapp/assets/tpl/editor/page.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/editor/page.html b/src/main/webapp/assets/tpl/editor/page.html
index 05b62db..c0c4338 100644
--- a/src/main/webapp/assets/tpl/editor/page.html
+++ b/src/main/webapp/assets/tpl/editor/page.html
@@ -57,7 +57,7 @@ under the License.
                         <div class="composer-toolbar">
                             <!-- the toolbar -->
                         </div>
-                        <textarea id="yaml_code" placeholder="<enter blueprint yaml here>" mode="yaml" class="code-textarea" style="height:760px; width:98%"></textarea>
+                        <textarea id="yaml_code" placeholder="# Enter blueprint yaml here. Press Ctrl+Space for completion." mode="yaml" class="code-textarea" style="height:760px; width:98%"></textarea>
                     </div>
                 </div>
             </div>


[25/27] brooklyn-ui git commit: This closes #5

Posted by he...@apache.org.
This closes #5


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/b7954f13
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/b7954f13
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/b7954f13

Branch: refs/heads/master
Commit: b7954f13d70b66af3a9a1ab2edaa0ceb1897cbe0
Parents: c2e374e 438132f
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 18 09:12:05 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 18 09:12:05 2016 +0000

----------------------------------------------------------------------
 .../webapp/assets/css/codemirror-brooklyn.css   |   29 +
 src/main/webapp/assets/js/libs/js-yaml.js       | 5703 +++++++++---------
 .../assets/js/model/catalog-application.js      |    1 -
 src/main/webapp/assets/js/router.js             |    8 +-
 .../assets/js/view/application-add-wizard.js    |  290 +-
 src/main/webapp/assets/js/view/catalog.js       |    9 +-
 src/main/webapp/assets/js/view/editor.js        |  193 +-
 .../tpl/app-add-wizard/create-entity-entry.html |   64 -
 .../assets/tpl/app-add-wizard/create.html       |   46 +-
 .../assets/tpl/app-add-wizard/modal-wizard.html |    4 +-
 .../assets/tpl/catalog/details-entity.html      |    1 +
 src/main/webapp/assets/tpl/editor/page.html     |   39 +-
 src/main/webapp/index.html                      |    1 +
 13 files changed, 3132 insertions(+), 3256 deletions(-)
----------------------------------------------------------------------



[07/27] brooklyn-ui git commit: update js-yaml to latest (snapshot) version

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/1e17eeef/src/main/webapp/assets/js/libs/js-yaml.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/js-yaml.js b/src/main/webapp/assets/js/libs/js-yaml.js
index fbc53e6..25bf133 100644
--- a/src/main/webapp/assets/js/libs/js-yaml.js
+++ b/src/main/webapp/assets/js/libs/js-yaml.js
@@ -1,492 +1,471 @@
-/* js-yaml 3.5.2 https://github.com/nodeca/js-yaml */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jsyaml = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-  'use strict';
+/* js-yaml 3.5.2 https://github.com/nodeca/js-yaml */
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jsyaml = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+'use strict';
 
 
-  var loader = require('./js-yaml/loader');
-  var dumper = require('./js-yaml/dumper');
+var loader = require('./js-yaml/loader');
+var dumper = require('./js-yaml/dumper');
 
 
-  function deprecated(name) {
-    return function () {
-      throw new Error('Function ' + name + ' is deprecated and cannot be used.');
-    };
-  }
-
-
-  module.exports.Type                = require('./js-yaml/type');
-  module.exports.Schema              = require('./js-yaml/schema');
-  module.exports.FAILSAFE_SCHEMA     = require('./js-yaml/schema/failsafe');
-  module.exports.JSON_SCHEMA         = require('./js-yaml/schema/json');
-  module.exports.CORE_SCHEMA         = require('./js-yaml/schema/core');
-  module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
-  module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full');
-  module.exports.load                = loader.load;
-  module.exports.loadAll             = loader.loadAll;
-  module.exports.safeLoad            = loader.safeLoad;
-  module.exports.safeLoadAll         = loader.safeLoadAll;
-  module.exports.dump                = dumper.dump;
-  module.exports.safeDump            = dumper.safeDump;
-  module.exports.YAMLException       = require('./js-yaml/exception');
+function deprecated(name) {
+  return function () {
+    throw new Error('Function ' + name + ' is deprecated and cannot be used.');
+  };
+}
+
+
+module.exports.Type                = require('./js-yaml/type');
+module.exports.Schema              = require('./js-yaml/schema');
+module.exports.FAILSAFE_SCHEMA     = require('./js-yaml/schema/failsafe');
+module.exports.JSON_SCHEMA         = require('./js-yaml/schema/json');
+module.exports.CORE_SCHEMA         = require('./js-yaml/schema/core');
+module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
+module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full');
+module.exports.load                = loader.load;
+module.exports.loadAll             = loader.loadAll;
+module.exports.safeLoad            = loader.safeLoad;
+module.exports.safeLoadAll         = loader.safeLoadAll;
+module.exports.dump                = dumper.dump;
+module.exports.safeDump            = dumper.safeDump;
+module.exports.YAMLException       = require('./js-yaml/exception');
 
 // Deprecated schema names from JS-YAML 2.0.x
-  module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe');
-  module.exports.SAFE_SCHEMA    = require('./js-yaml/schema/default_safe');
-  module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full');
+module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe');
+module.exports.SAFE_SCHEMA    = require('./js-yaml/schema/default_safe');
+module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full');
 
 // Deprecated functions from JS-YAML 1.x.x
-  module.exports.scan           = deprecated('scan');
-  module.exports.parse          = deprecated('parse');
-  module.exports.compose        = deprecated('compose');
-  module.exports.addConstructor = deprecated('addConstructor');
+module.exports.scan           = deprecated('scan');
+module.exports.parse          = deprecated('parse');
+module.exports.compose        = deprecated('compose');
+module.exports.addConstructor = deprecated('addConstructor');
 
 },{"./js-yaml/dumper":3,"./js-yaml/exception":4,"./js-yaml/loader":5,"./js-yaml/schema":7,"./js-yaml/schema/core":8,"./js-yaml/schema/default_full":9,"./js-yaml/schema/default_safe":10,"./js-yaml/schema/failsafe":11,"./js-yaml/schema/json":12,"./js-yaml/type":13}],2:[function(require,module,exports){
-  'use strict';
-
-
-  function isNothing(subject) {
-    return (typeof subject === 'undefined') || (null === subject);
-  }
-
+'use strict';
 
-  function isObject(subject) {
-    return (typeof subject === 'object') && (null !== subject);
-  }
 
+function isNothing(subject) {
+  return (typeof subject === 'undefined') || (null === subject);
+}
 
-  function toArray(sequence) {
-    if (Array.isArray(sequence)) {
-      return sequence;
-    } else if (isNothing(sequence)) {
-      return [];
-    }
-    return [ sequence ];
-  }
 
+function isObject(subject) {
+  return (typeof subject === 'object') && (null !== subject);
+}
 
-  function extend(target, source) {
-    var index, length, key, sourceKeys;
 
-    if (source) {
-      sourceKeys = Object.keys(source);
+function toArray(sequence) {
+  if (Array.isArray(sequence)) return sequence;
+  else if (isNothing(sequence)) return [];
 
-      for (index = 0, length = sourceKeys.length; index < length; index += 1) {
-        key = sourceKeys[index];
-        target[key] = source[key];
-      }
-    }
+  return [ sequence ];
+}
 
-    return target;
-  }
 
+function extend(target, source) {
+  var index, length, key, sourceKeys;
 
-  function repeat(string, count) {
-    var result = '', cycle;
+  if (source) {
+    sourceKeys = Object.keys(source);
 
-    for (cycle = 0; cycle < count; cycle += 1) {
-      result += string;
+    for (index = 0, length = sourceKeys.length; index < length; index += 1) {
+      key = sourceKeys[index];
+      target[key] = source[key];
     }
-
-    return result;
   }
 
-
-  function isNegativeZero(number) {
-    return (0 === number) && (Number.NEGATIVE_INFINITY === 1 / number);
-  }
+  return target;
+}
 
 
-  module.exports.isNothing      = isNothing;
-  module.exports.isObject       = isObject;
-  module.exports.toArray        = toArray;
-  module.exports.repeat         = repeat;
-  module.exports.isNegativeZero = isNegativeZero;
-  module.exports.extend         = extend;
+function repeat(string, count) {
+  var result = '', cycle;
 
-},{}],3:[function(require,module,exports){
-  'use strict';
-
-  /*eslint-disable no-use-before-define*/
-
-  var common              = require('./common');
-  var YAMLException       = require('./exception');
-  var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
-  var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
-
-  var _toString       = Object.prototype.toString;
-  var _hasOwnProperty = Object.prototype.hasOwnProperty;
-
-  var CHAR_TAB                  = 0x09; /* Tab */
-  var CHAR_LINE_FEED            = 0x0A; /* LF */
-  var CHAR_CARRIAGE_RETURN      = 0x0D; /* CR */
-  var CHAR_SPACE                = 0x20; /* Space */
-  var CHAR_EXCLAMATION          = 0x21; /* ! */
-  var CHAR_DOUBLE_QUOTE         = 0x22; /* " */
-  var CHAR_SHARP                = 0x23; /* # */
-  var CHAR_PERCENT              = 0x25; /* % */
-  var CHAR_AMPERSAND            = 0x26; /* & */
-  var CHAR_SINGLE_QUOTE         = 0x27; /* ' */
-  var CHAR_ASTERISK             = 0x2A; /* * */
-  var CHAR_COMMA                = 0x2C; /* , */
-  var CHAR_MINUS                = 0x2D; /* - */
-  var CHAR_COLON                = 0x3A; /* : */
-  var CHAR_GREATER_THAN         = 0x3E; /* > */
-  var CHAR_QUESTION             = 0x3F; /* ? */
-  var CHAR_COMMERCIAL_AT        = 0x40; /* @ */
-  var CHAR_LEFT_SQUARE_BRACKET  = 0x5B; /* [ */
-  var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
-  var CHAR_GRAVE_ACCENT         = 0x60; /* ` */
-  var CHAR_LEFT_CURLY_BRACKET   = 0x7B; /* { */
-  var CHAR_VERTICAL_LINE        = 0x7C; /* | */
-  var CHAR_RIGHT_CURLY_BRACKET  = 0x7D; /* } */
-
-  var ESCAPE_SEQUENCES = {};
-
-  ESCAPE_SEQUENCES[0x00]   = '\\0';
-  ESCAPE_SEQUENCES[0x07]   = '\\a';
-  ESCAPE_SEQUENCES[0x08]   = '\\b';
-  ESCAPE_SEQUENCES[0x09]   = '\\t';
-  ESCAPE_SEQUENCES[0x0A]   = '\\n';
-  ESCAPE_SEQUENCES[0x0B]   = '\\v';
-  ESCAPE_SEQUENCES[0x0C]   = '\\f';
-  ESCAPE_SEQUENCES[0x0D]   = '\\r';
-  ESCAPE_SEQUENCES[0x1B]   = '\\e';
-  ESCAPE_SEQUENCES[0x22]   = '\\"';
-  ESCAPE_SEQUENCES[0x5C]   = '\\\\';
-  ESCAPE_SEQUENCES[0x85]   = '\\N';
-  ESCAPE_SEQUENCES[0xA0]   = '\\_';
-  ESCAPE_SEQUENCES[0x2028] = '\\L';
-  ESCAPE_SEQUENCES[0x2029] = '\\P';
-
-  var DEPRECATED_BOOLEANS_SYNTAX = [
-    'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
-    'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
-  ];
-
-  function compileStyleMap(schema, map) {
-    var result, keys, index, length, tag, style, type;
-
-    if (null === map) {
-      return {};
-    }
-
-    result = {};
-    keys = Object.keys(map);
-
-    for (index = 0, length = keys.length; index < length; index += 1) {
-      tag = keys[index];
-      style = String(map[tag]);
-
-      if ('!!' === tag.slice(0, 2)) {
-        tag = 'tag:yaml.org,2002:' + tag.slice(2);
-      }
+  for (cycle = 0; cycle < count; cycle += 1) {
+    result += string;
+  }
 
-      type = schema.compiledTypeMap[tag];
+  return result;
+}
 
-      if (type && _hasOwnProperty.call(type.styleAliases, style)) {
-        style = type.styleAliases[style];
-      }
 
-      result[tag] = style;
-    }
+function isNegativeZero(number) {
+  return (0 === number) && (Number.NEGATIVE_INFINITY === 1 / number);
+}
 
-    return result;
-  }
 
-  function encodeHex(character) {
-    var string, handle, length;
+module.exports.isNothing      = isNothing;
+module.exports.isObject       = isObject;
+module.exports.toArray        = toArray;
+module.exports.repeat         = repeat;
+module.exports.isNegativeZero = isNegativeZero;
+module.exports.extend         = extend;
 
-    string = character.toString(16).toUpperCase();
+},{}],3:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable no-use-before-define*/
+
+var common              = require('./common');
+var YAMLException       = require('./exception');
+var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
+var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
+
+var _toString       = Object.prototype.toString;
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+
+var CHAR_TAB                  = 0x09; /* Tab */
+var CHAR_LINE_FEED            = 0x0A; /* LF */
+var CHAR_CARRIAGE_RETURN      = 0x0D; /* CR */
+var CHAR_SPACE                = 0x20; /* Space */
+var CHAR_EXCLAMATION          = 0x21; /* ! */
+var CHAR_DOUBLE_QUOTE         = 0x22; /* " */
+var CHAR_SHARP                = 0x23; /* # */
+var CHAR_PERCENT              = 0x25; /* % */
+var CHAR_AMPERSAND            = 0x26; /* & */
+var CHAR_SINGLE_QUOTE         = 0x27; /* ' */
+var CHAR_ASTERISK             = 0x2A; /* * */
+var CHAR_COMMA                = 0x2C; /* , */
+var CHAR_MINUS                = 0x2D; /* - */
+var CHAR_COLON                = 0x3A; /* : */
+var CHAR_GREATER_THAN         = 0x3E; /* > */
+var CHAR_QUESTION             = 0x3F; /* ? */
+var CHAR_COMMERCIAL_AT        = 0x40; /* @ */
+var CHAR_LEFT_SQUARE_BRACKET  = 0x5B; /* [ */
+var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
+var CHAR_GRAVE_ACCENT         = 0x60; /* ` */
+var CHAR_LEFT_CURLY_BRACKET   = 0x7B; /* { */
+var CHAR_VERTICAL_LINE        = 0x7C; /* | */
+var CHAR_RIGHT_CURLY_BRACKET  = 0x7D; /* } */
+
+var ESCAPE_SEQUENCES = {};
+
+ESCAPE_SEQUENCES[0x00]   = '\\0';
+ESCAPE_SEQUENCES[0x07]   = '\\a';
+ESCAPE_SEQUENCES[0x08]   = '\\b';
+ESCAPE_SEQUENCES[0x09]   = '\\t';
+ESCAPE_SEQUENCES[0x0A]   = '\\n';
+ESCAPE_SEQUENCES[0x0B]   = '\\v';
+ESCAPE_SEQUENCES[0x0C]   = '\\f';
+ESCAPE_SEQUENCES[0x0D]   = '\\r';
+ESCAPE_SEQUENCES[0x1B]   = '\\e';
+ESCAPE_SEQUENCES[0x22]   = '\\"';
+ESCAPE_SEQUENCES[0x5C]   = '\\\\';
+ESCAPE_SEQUENCES[0x85]   = '\\N';
+ESCAPE_SEQUENCES[0xA0]   = '\\_';
+ESCAPE_SEQUENCES[0x2028] = '\\L';
+ESCAPE_SEQUENCES[0x2029] = '\\P';
+
+var DEPRECATED_BOOLEANS_SYNTAX = [
+  'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
+  'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
+];
+
+function compileStyleMap(schema, map) {
+  var result, keys, index, length, tag, style, type;
+
+  if (null === map) return {};
+
+  result = {};
+  keys = Object.keys(map);
+
+  for (index = 0, length = keys.length; index < length; index += 1) {
+    tag = keys[index];
+    style = String(map[tag]);
+
+    if ('!!' === tag.slice(0, 2)) {
+      tag = 'tag:yaml.org,2002:' + tag.slice(2);
+    }
+
+    type = schema.compiledTypeMap[tag];
+
+    if (type && _hasOwnProperty.call(type.styleAliases, style)) {
+      style = type.styleAliases[style];
+    }
+
+    result[tag] = style;
+  }
+
+  return result;
+}
+
+function encodeHex(character) {
+  var string, handle, length;
+
+  string = character.toString(16).toUpperCase();
+
+  if (character <= 0xFF) {
+    handle = 'x';
+    length = 2;
+  } else if (character <= 0xFFFF) {
+    handle = 'u';
+    length = 4;
+  } else if (character <= 0xFFFFFFFF) {
+    handle = 'U';
+    length = 8;
+  } else {
+    throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
+  }
+
+  return '\\' + handle + common.repeat('0', length - string.length) + string;
+}
+
+function State(options) {
+  this.schema      = options['schema'] || DEFAULT_FULL_SCHEMA;
+  this.indent      = Math.max(1, (options['indent'] || 2));
+  this.skipInvalid = options['skipInvalid'] || false;
+  this.flowLevel   = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
+  this.styleMap    = compileStyleMap(this.schema, options['styles'] || null);
+  this.sortKeys    = options['sortKeys'] || false;
+  this.lineWidth   = options['lineWidth'] || 80;
+  this.noRefs      = options['noRefs'] || false;
+
+  this.implicitTypes = this.schema.compiledImplicit;
+  this.explicitTypes = this.schema.compiledExplicit;
+
+  this.tag = null;
+  this.result = '';
+
+  this.duplicates = [];
+  this.usedDuplicates = null;
+}
+
+function indentString(string, spaces) {
+  var ind = common.repeat(' ', spaces),
+      position = 0,
+      next = -1,
+      result = '',
+      line,
+      length = string.length;
 
-    if (character <= 0xFF) {
-      handle = 'x';
-      length = 2;
-    } else if (character <= 0xFFFF) {
-      handle = 'u';
-      length = 4;
-    } else if (character <= 0xFFFFFFFF) {
-      handle = 'U';
-      length = 8;
+  while (position < length) {
+    next = string.indexOf('\n', position);
+    if (next === -1) {
+      line = string.slice(position);
+      position = length;
     } else {
-      throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
+      line = string.slice(position, next + 1);
+      position = next + 1;
     }
 
-    return '\\' + handle + common.repeat('0', length - string.length) + string;
+    if (line.length && line !== '\n') result += ind;
+
+    result += line;
   }
 
-  function State(options) {
-    this.schema      = options['schema'] || DEFAULT_FULL_SCHEMA;
-    this.indent      = Math.max(1, (options['indent'] || 2));
-    this.skipInvalid = options['skipInvalid'] || false;
-    this.flowLevel   = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
-    this.styleMap    = compileStyleMap(this.schema, options['styles'] || null);
-    this.sortKeys    = options['sortKeys'] || false;
-    this.lineWidth   = options['lineWidth'] || 80;
-    this.noRefs      = options['noRefs'] || false;
+  return result;
+}
+
+function generateNextLine(state, level) {
+  return '\n' + common.repeat(' ', state.indent * level);
+}
 
-    this.implicitTypes = this.schema.compiledImplicit;
-    this.explicitTypes = this.schema.compiledExplicit;
+function testImplicitResolving(state, str) {
+  var index, length, type;
 
-    this.tag = null;
-    this.result = '';
+  for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
+    type = state.implicitTypes[index];
 
-    this.duplicates = [];
-    this.usedDuplicates = null;
+    if (type.resolve(str)) {
+      return true;
+    }
   }
 
-  function indentString(string, spaces) {
-    var ind = common.repeat(' ', spaces),
-        position = 0,
-        next = -1,
-        result = '',
-        line,
-        length = string.length;
+  return false;
+}
 
-    while (position < length) {
-      next = string.indexOf('\n', position);
-      if (next === -1) {
-        line = string.slice(position);
-        position = length;
-      } else {
-        line = string.slice(position, next + 1);
-        position = next + 1;
-      }
-      if (line.length && line !== '\n') {
-        result += ind;
-      }
-      result += line;
-    }
+function StringBuilder(source) {
+  this.source = source;
+  this.result = '';
+  this.checkpoint = 0;
+}
 
-    return result;
-  }
+StringBuilder.prototype.takeUpTo = function (position) {
+  var er;
 
-  function generateNextLine(state, level) {
-    return '\n' + common.repeat(' ', state.indent * level);
+  if (position < this.checkpoint) {
+    er = new Error('position should be > checkpoint');
+    er.position = position;
+    er.checkpoint = this.checkpoint;
+    throw er;
   }
 
-  function testImplicitResolving(state, str) {
-    var index, length, type;
+  this.result += this.source.slice(this.checkpoint, position);
+  this.checkpoint = position;
+  return this;
+};
 
-    for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
-      type = state.implicitTypes[index];
+StringBuilder.prototype.escapeChar = function () {
+  var character, esc;
 
-      if (type.resolve(str)) {
-        return true;
-      }
-    }
+  character = this.source.charCodeAt(this.checkpoint);
+  esc = ESCAPE_SEQUENCES[character] || encodeHex(character);
+  this.result += esc;
+  this.checkpoint += 1;
 
-    return false;
-  }
+  return this;
+};
 
-  function StringBuilder(source) {
-    this.source = source;
-    this.result = '';
-    this.checkpoint = 0;
+StringBuilder.prototype.finish = function () {
+  if (this.source.length > this.checkpoint) {
+    this.takeUpTo(this.source.length);
   }
+};
 
-  StringBuilder.prototype.takeUpTo = function (position) {
-    var er;
+function writeScalar(state, object, level, iskey) {
+  var simple, first, spaceWrap, folded, literal, single, double,
+      sawLineFeed, linePosition, longestLine, indent, max, character,
+      position, escapeSeq, hexEsc, previous, lineLength, modifier,
+      trailingLineBreaks, result;
 
-    if (position < this.checkpoint) {
-      er = new Error('position should be > checkpoint');
-      er.position = position;
-      er.checkpoint = this.checkpoint;
-      throw er;
-    }
+  if (0 === object.length) {
+    state.dump = "''";
+    return;
+  }
 
-    this.result += this.source.slice(this.checkpoint, position);
-    this.checkpoint = position;
-    return this;
-  };
+  if (-1 !== DEPRECATED_BOOLEANS_SYNTAX.indexOf(object)) {
+    state.dump = "'" + object + "'";
+    return;
+  }
 
-  StringBuilder.prototype.escapeChar = function () {
-    var character, esc;
+  simple = true;
+  first = object.length ? object.charCodeAt(0) : 0;
+  spaceWrap = (CHAR_SPACE === first ||
+               CHAR_SPACE === object.charCodeAt(object.length - 1));
 
-    character = this.source.charCodeAt(this.checkpoint);
-    esc = ESCAPE_SEQUENCES[character] || encodeHex(character);
-    this.result += esc;
-    this.checkpoint += 1;
+  // Simplified check for restricted first characters
+  // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29
+  if (CHAR_MINUS         === first ||
+      CHAR_QUESTION      === first ||
+      CHAR_COMMERCIAL_AT === first ||
+      CHAR_GRAVE_ACCENT  === first) {
+    simple = false;
+  }
 
-    return this;
-  };
+  // Can only use > and | if not wrapped in spaces or is not a key.
+  // Also, don't use if in flow mode.
+  if (spaceWrap || (state.flowLevel > -1 && state.flowLevel <= level)) {
+    if (spaceWrap) simple = false;
 
-  StringBuilder.prototype.finish = function () {
-    if (this.source.length > this.checkpoint) {
-      this.takeUpTo(this.source.length);
-    }
-  };
+    folded = false;
+    literal = false;
+  } else {
+    folded = !iskey;
+    literal = !iskey;
+  }
 
-  function writeScalar(state, object, level, iskey) {
-    var simple, first, spaceWrap, folded, literal, single, double,
-        sawLineFeed, linePosition, longestLine, indent, max, character,
-        position, escapeSeq, hexEsc, previous, lineLength, modifier,
-        trailingLineBreaks, result;
+  single = true;
+  double = new StringBuilder(object);
 
-    if (0 === object.length) {
-      state.dump = "''";
-      return;
-    }
+  sawLineFeed = false;
+  linePosition = 0;
+  longestLine = 0;
 
-    if (-1 !== DEPRECATED_BOOLEANS_SYNTAX.indexOf(object)) {
-      state.dump = "'" + object + "'";
-      return;
-    }
+  indent = state.indent * level;
+  max = state.lineWidth;
 
-    simple = true;
-    first = object.length ? object.charCodeAt(0) : 0;
-    spaceWrap = (CHAR_SPACE === first ||
-    CHAR_SPACE === object.charCodeAt(object.length - 1));
+  // Replace -1 with biggest ingeger number according to
+  // http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
+  if (max === -1) max = 9007199254740991;
 
-    // Simplified check for restricted first characters
-    // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29
-    if (CHAR_MINUS         === first ||
-        CHAR_QUESTION      === first ||
-        CHAR_COMMERCIAL_AT === first ||
-        CHAR_GRAVE_ACCENT  === first) {
-      simple = false;
-    }
+  if (indent < 40) max -= indent;
+  else max = 40;
 
-    // Can only use > and | if not wrapped in spaces or is not a key.
-    // Also, don't use if in flow mode.
-    if (spaceWrap || (state.flowLevel > -1 && state.flowLevel <= level)) {
-      if (spaceWrap) {
+  for (position = 0; position < object.length; position++) {
+    character = object.charCodeAt(position);
+    if (simple) {
+      // Characters that can never appear in the simple scalar
+      if (!simpleChar(character)) {
         simple = false;
+      } else {
+        // Still simple.  If we make it all the way through like
+        // this, then we can just dump the string as-is.
+        continue;
       }
-      folded = false;
-      literal = false;
-    } else {
-      folded = !iskey;
-      literal = !iskey;
     }
 
-    single = true;
-    double = new StringBuilder(object);
-
-    sawLineFeed = false;
-    linePosition = 0;
-    longestLine = 0;
-
-    indent = state.indent * level;
-    max = state.lineWidth;
-    if (max === -1) {
-      // Replace -1 with biggest ingeger number according to
-      // http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
-      max = 9007199254740991;
+    if (single && character === CHAR_SINGLE_QUOTE) {
+      single = false;
     }
 
-    if (indent < 40) {
-      max -= indent;
-    } else {
-      max = 40;
+    escapeSeq = ESCAPE_SEQUENCES[character];
+    hexEsc = needsHexEscape(character);
+
+    if (!escapeSeq && !hexEsc) {
+      continue;
     }
 
-    for (position = 0; position < object.length; position++) {
-      character = object.charCodeAt(position);
-      if (simple) {
-        // Characters that can never appear in the simple scalar
-        if (!simpleChar(character)) {
-          simple = false;
-        } else {
-          // Still simple.  If we make it all the way through like
-          // this, then we can just dump the string as-is.
-          continue;
+    if (character !== CHAR_LINE_FEED &&
+        character !== CHAR_DOUBLE_QUOTE &&
+        character !== CHAR_SINGLE_QUOTE) {
+      folded = false;
+      literal = false;
+    } else if (character === CHAR_LINE_FEED) {
+      sawLineFeed = true;
+      single = false;
+      if (position > 0) {
+        previous = object.charCodeAt(position - 1);
+        if (previous === CHAR_SPACE) {
+          literal = false;
+          folded = false;
         }
       }
-
-      if (single && character === CHAR_SINGLE_QUOTE) {
-        single = false;
-      }
-
-      escapeSeq = ESCAPE_SEQUENCES[character];
-      hexEsc = needsHexEscape(character);
-
-      if (!escapeSeq && !hexEsc) {
-        continue;
-      }
-
-      if (character !== CHAR_LINE_FEED &&
-          character !== CHAR_DOUBLE_QUOTE &&
-          character !== CHAR_SINGLE_QUOTE) {
-        folded = false;
-        literal = false;
-      } else if (character === CHAR_LINE_FEED) {
-        sawLineFeed = true;
-        single = false;
-        if (position > 0) {
-          previous = object.charCodeAt(position - 1);
-          if (previous === CHAR_SPACE) {
-            literal = false;
-            folded = false;
-          }
-        }
-        if (folded) {
-          lineLength = position - linePosition;
-          linePosition = position;
-          if (lineLength > longestLine) {
-            longestLine = lineLength;
-          }
-        }
+      if (folded) {
+        lineLength = position - linePosition;
+        linePosition = position;
+        if (lineLength > longestLine) longestLine = lineLength;
       }
+    }
 
-      if (character !== CHAR_DOUBLE_QUOTE) {
-        single = false;
-      }
+    if (character !== CHAR_DOUBLE_QUOTE) single = false;
 
-      double.takeUpTo(position);
-      double.escapeChar();
-    }
+    double.takeUpTo(position);
+    double.escapeChar();
+  }
 
-    if (simple && testImplicitResolving(state, object)) {
-      simple = false;
-    }
+  if (simple && testImplicitResolving(state, object)) simple = false;
 
-    modifier = '';
-    if (folded || literal) {
-      trailingLineBreaks = 0;
-      if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) {
+  modifier = '';
+  if (folded || literal) {
+    trailingLineBreaks = 0;
+    if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) {
+      trailingLineBreaks += 1;
+      if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) {
         trailingLineBreaks += 1;
-        if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) {
-          trailingLineBreaks += 1;
-        }
-      }
-
-      if (trailingLineBreaks === 0) {
-        modifier = '-';
-      } else if (trailingLineBreaks === 2) {
-        modifier = '+';
       }
     }
 
-    if (literal && longestLine < max || state.tag !== null) {
-      folded = false;
-    }
+    if (trailingLineBreaks === 0) modifier = '-';
+    else if (trailingLineBreaks === 2) modifier = '+';
+  }
 
-    // If it's literally one line, then don't bother with the literal.
-    // We may still want to do a fold, though, if it's a super long line.
-    if (!sawLineFeed) {
-      literal = false;
-    }
+  if (literal && longestLine < max || state.tag !== null) {
+    folded = false;
+  }
 
-    if (simple) {
-      state.dump = object;
-    } else if (single) {
-      state.dump = '\'' + object + '\'';
-    } else if (folded) {
-      result = fold(object, max);
-      state.dump = '>' + modifier + '\n' + indentString(result, indent);
-    } else if (literal) {
-      if (!modifier) {
-        object = object.replace(/\n$/, '');
-      }
-      state.dump = '|' + modifier + '\n' + indentString(object, indent);
-    } else if (double) {
-      double.finish();
-      state.dump = '"' + double.result + '"';
-    } else {
-      throw new Error('Failed to dump scalar value');
-    }
+  // If it's literally one line, then don't bother with the literal.
+  // We may still want to do a fold, though, if it's a super long line.
+  if (!sawLineFeed) literal = false;
 
-    return;
-  }
+  if (simple) {
+    state.dump = object;
+  } else if (single) {
+    state.dump = '\'' + object + '\'';
+  } else if (folded) {
+    result = fold(object, max);
+    state.dump = '>' + modifier + '\n' + indentString(result, indent);
+  } else if (literal) {
+    if (!modifier) object = object.replace(/\n$/, '');
+    state.dump = '|' + modifier + '\n' + indentString(object, indent);
+  } else if (double) {
+    double.finish();
+    state.dump = '"' + double.result + '"';
+  } else {
+    throw new Error('Failed to dump scalar value');
+  }
+
+  return;
+}
 
 // The `trailing` var is a regexp match of any trailing `\n` characters.
 //
@@ -500,1549 +479,1517 @@
 // In the case of `>+`, these line breaks are *not* doubled (like the line
 // breaks within the string), so it's important to only end with the exact
 // same number as we started.
-  function fold(object, max) {
-    var result = '',
-        position = 0,
-        length = object.length,
-        trailing = /\n+$/.exec(object),
-        newLine;
-
-    if (trailing) {
-      length = trailing.index + 1;
-    }
-
-    while (position < length) {
-      newLine = object.indexOf('\n', position);
-      if (newLine > length || newLine === -1) {
-        if (result) {
-          result += '\n\n';
-        }
-        result += foldLine(object.slice(position, length), max);
-        position = length;
-      } else {
-        if (result) {
-          result += '\n\n';
-        }
-        result += foldLine(object.slice(position, newLine), max);
-        position = newLine + 1;
-      }
-    }
-    if (trailing && trailing[0] !== '\n') {
-      result += trailing[0];
-    }
+function fold(object, max) {
+  var result = '',
+      position = 0,
+      length = object.length,
+      trailing = /\n+$/.exec(object),
+      newLine;
 
-    return result;
+  if (trailing) {
+    length = trailing.index + 1;
   }
 
-  function foldLine(line, max) {
-    if (line === '') {
-      return line;
-    }
+  while (position < length) {
+    newLine = object.indexOf('\n', position);
+    if (newLine > length || newLine === -1) {
+      if (result) result += '\n\n';
+      result += foldLine(object.slice(position, length), max);
+      position = length;
 
-    var foldRe = /[^\s] [^\s]/g,
-        result = '',
-        prevMatch = 0,
-        foldStart = 0,
-        match = foldRe.exec(line),
-        index,
-        foldEnd,
-        folded;
+    } else {
+      if (result) result += '\n\n';
+      result += foldLine(object.slice(position, newLine), max);
+      position = newLine + 1;
+    }
+  }
 
-    while (match) {
-      index = match.index;
+  if (trailing && trailing[0] !== '\n') result += trailing[0];
 
-      // when we cross the max len, if the previous match would've
-      // been ok, use that one, and carry on.  If there was no previous
-      // match on this fold section, then just have a long line.
-      if (index - foldStart > max) {
-        if (prevMatch !== foldStart) {
-          foldEnd = prevMatch;
-        } else {
-          foldEnd = index;
-        }
+  return result;
+}
 
-        if (result) {
-          result += '\n';
-        }
-        folded = line.slice(foldStart, foldEnd);
-        result += folded;
-        foldStart = foldEnd + 1;
-      }
-      prevMatch = index + 1;
-      match = foldRe.exec(line);
-    }
+function foldLine(line, max) {
+  if (line === '') return line;
 
-    if (result) {
-      result += '\n';
-    }
+  var foldRe = /[^\s] [^\s]/g,
+      result = '',
+      prevMatch = 0,
+      foldStart = 0,
+      match = foldRe.exec(line),
+      index,
+      foldEnd,
+      folded;
 
-    // if we end up with one last word at the end, then the last bit might
-    // be slightly bigger than we wanted, because we exited out of the loop.
-    if (foldStart !== prevMatch && line.length - foldStart > max) {
-      result += line.slice(foldStart, prevMatch) + '\n' +
-          line.slice(prevMatch + 1);
-    } else {
-      result += line.slice(foldStart);
-    }
+  while (match) {
+    index = match.index;
 
-    return result;
-  }
+    // when we cross the max len, if the previous match would've
+    // been ok, use that one, and carry on.  If there was no previous
+    // match on this fold section, then just have a long line.
+    if (index - foldStart > max) {
+      if (prevMatch !== foldStart) foldEnd = prevMatch;
+      else foldEnd = index;
 
-// Returns true if character can be found in a simple scalar
-  function simpleChar(character) {
-    return CHAR_TAB                  !== character &&
-        CHAR_LINE_FEED            !== character &&
-        CHAR_CARRIAGE_RETURN      !== character &&
-        CHAR_COMMA                !== character &&
-        CHAR_LEFT_SQUARE_BRACKET  !== character &&
-        CHAR_RIGHT_SQUARE_BRACKET !== character &&
-        CHAR_LEFT_CURLY_BRACKET   !== character &&
-        CHAR_RIGHT_CURLY_BRACKET  !== character &&
-        CHAR_SHARP                !== character &&
-        CHAR_AMPERSAND            !== character &&
-        CHAR_ASTERISK             !== character &&
-        CHAR_EXCLAMATION          !== character &&
-        CHAR_VERTICAL_LINE        !== character &&
-        CHAR_GREATER_THAN         !== character &&
-        CHAR_SINGLE_QUOTE         !== character &&
-        CHAR_DOUBLE_QUOTE         !== character &&
-        CHAR_PERCENT              !== character &&
-        CHAR_COLON                !== character &&
-        !ESCAPE_SEQUENCES[character]            &&
-        !needsHexEscape(character);
+      if (result) result += '\n';
+      folded = line.slice(foldStart, foldEnd);
+      result += folded;
+      foldStart = foldEnd + 1;
+    }
+    prevMatch = index + 1;
+    match = foldRe.exec(line);
   }
 
-// Returns true if the character code needs to be escaped.
-  function needsHexEscape(character) {
-    return !((0x00020 <= character && character <= 0x00007E) ||
-    (0x00085 === character)                         ||
-    (0x000A0 <= character && character <= 0x00D7FF) ||
-    (0x0E000 <= character && character <= 0x00FFFD) ||
-    (0x10000 <= character && character <= 0x10FFFF));
-  }
-
-  function writeFlowSequence(state, level, object) {
-    var _result = '',
-        _tag    = state.tag,
-        index,
-        length;
-
-    for (index = 0, length = object.length; index < length; index += 1) {
-      // Write only valid elements.
-      if (writeNode(state, level, object[index], false, false)) {
-        if (0 !== index) {
-          _result += ', ';
-        }
-        _result += state.dump;
-      }
-    }
+  if (result) result += '\n';
 
-    state.tag = _tag;
-    state.dump = '[' + _result + ']';
+  // if we end up with one last word at the end, then the last bit might
+  // be slightly bigger than we wanted, because we exited out of the loop.
+  if (foldStart !== prevMatch && line.length - foldStart > max) {
+    result += line.slice(foldStart, prevMatch) + '\n' +
+              line.slice(prevMatch + 1);
+  } else {
+    result += line.slice(foldStart);
   }
 
-  function writeBlockSequence(state, level, object, compact) {
-    var _result = '',
-        _tag    = state.tag,
-        index,
-        length;
+  return result;
+}
 
-    for (index = 0, length = object.length; index < length; index += 1) {
-      // Write only valid elements.
-      if (writeNode(state, level + 1, object[index], true, true)) {
-        if (!compact || 0 !== index) {
-          _result += generateNextLine(state, level);
-        }
-        _result += '- ' + state.dump;
+// Returns true if character can be found in a simple scalar
+function simpleChar(character) {
+  return CHAR_TAB                  !== character &&
+         CHAR_LINE_FEED            !== character &&
+         CHAR_CARRIAGE_RETURN      !== character &&
+         CHAR_COMMA                !== character &&
+         CHAR_LEFT_SQUARE_BRACKET  !== character &&
+         CHAR_RIGHT_SQUARE_BRACKET !== character &&
+         CHAR_LEFT_CURLY_BRACKET   !== character &&
+         CHAR_RIGHT_CURLY_BRACKET  !== character &&
+         CHAR_SHARP                !== character &&
+         CHAR_AMPERSAND            !== character &&
+         CHAR_ASTERISK             !== character &&
+         CHAR_EXCLAMATION          !== character &&
+         CHAR_VERTICAL_LINE        !== character &&
+         CHAR_GREATER_THAN         !== character &&
+         CHAR_SINGLE_QUOTE         !== character &&
+         CHAR_DOUBLE_QUOTE         !== character &&
+         CHAR_PERCENT              !== character &&
+         CHAR_COLON                !== character &&
+         !ESCAPE_SEQUENCES[character]            &&
+         !needsHexEscape(character);
+}
+
+// Returns true if the character code needs to be escaped.
+function needsHexEscape(character) {
+  return !((0x00020 <= character && character <= 0x00007E) ||
+           (0x00085 === character)                         ||
+           (0x000A0 <= character && character <= 0x00D7FF) ||
+           (0x0E000 <= character && character <= 0x00FFFD) ||
+           (0x10000 <= character && character <= 0x10FFFF));
+}
+
+function writeFlowSequence(state, level, object) {
+  var _result = '',
+      _tag    = state.tag,
+      index,
+      length;
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    // Write only valid elements.
+    if (writeNode(state, level, object[index], false, false)) {
+      if (0 !== index) _result += ', ';
+      _result += state.dump;
+    }
+  }
+
+  state.tag = _tag;
+  state.dump = '[' + _result + ']';
+}
+
+function writeBlockSequence(state, level, object, compact) {
+  var _result = '',
+      _tag    = state.tag,
+      index,
+      length;
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    // Write only valid elements.
+    if (writeNode(state, level + 1, object[index], true, true)) {
+      if (!compact || 0 !== index) {
+        _result += generateNextLine(state, level);
       }
+      _result += '- ' + state.dump;
     }
-
-    state.tag = _tag;
-    state.dump = _result || '[]'; // Empty sequence if no valid values.
   }
 
-  function writeFlowMapping(state, level, object) {
-    var _result       = '',
-        _tag          = state.tag,
-        objectKeyList = Object.keys(object),
-        index,
-        length,
-        objectKey,
-        objectValue,
-        pairBuffer;
+  state.tag = _tag;
+  state.dump = _result || '[]'; // Empty sequence if no valid values.
+}
 
-    for (index = 0, length = objectKeyList.length; index < length; index += 1) {
-      pairBuffer = '';
+function writeFlowMapping(state, level, object) {
+  var _result       = '',
+      _tag          = state.tag,
+      objectKeyList = Object.keys(object),
+      index,
+      length,
+      objectKey,
+      objectValue,
+      pairBuffer;
 
-      if (0 !== index) {
-        pairBuffer += ', ';
-      }
-
-      objectKey = objectKeyList[index];
-      objectValue = object[objectKey];
+  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+    pairBuffer = '';
 
-      if (!writeNode(state, level, objectKey, false, false)) {
-        continue; // Skip this pair because of invalid key;
-      }
+    if (0 !== index) pairBuffer += ', ';
 
-      if (state.dump.length > 1024) {
-        pairBuffer += '? ';
-      }
+    objectKey = objectKeyList[index];
+    objectValue = object[objectKey];
 
-      pairBuffer += state.dump + ': ';
+    if (!writeNode(state, level, objectKey, false, false)) {
+      continue; // Skip this pair because of invalid key;
+    }
 
-      if (!writeNode(state, level, objectValue, false, false)) {
-        continue; // Skip this pair because of invalid value.
-      }
+    if (state.dump.length > 1024) pairBuffer += '? ';
 
-      pairBuffer += state.dump;
+    pairBuffer += state.dump + ': ';
 
-      // Both key and value are valid.
-      _result += pairBuffer;
+    if (!writeNode(state, level, objectValue, false, false)) {
+      continue; // Skip this pair because of invalid value.
     }
 
-    state.tag = _tag;
-    state.dump = '{' + _result + '}';
-  }
-
-  function writeBlockMapping(state, level, object, compact) {
-    var _result       = '',
-        _tag          = state.tag,
-        objectKeyList = Object.keys(object),
-        index,
-        length,
-        objectKey,
-        objectValue,
-        explicitPair,
-        pairBuffer;
-
-    // Allow sorting keys so that the output file is deterministic
-    if (state.sortKeys === true) {
-      // Default sorting
-      objectKeyList.sort();
-    } else if (typeof state.sortKeys === 'function') {
-      // Custom sort function
-      objectKeyList.sort(state.sortKeys);
-    } else if (state.sortKeys) {
-      // Something is wrong
-      throw new YAMLException('sortKeys must be a boolean or a function');
-    }
-
-    for (index = 0, length = objectKeyList.length; index < length; index += 1) {
-      pairBuffer = '';
+    pairBuffer += state.dump;
 
-      if (!compact || 0 !== index) {
-        pairBuffer += generateNextLine(state, level);
-      }
+    // Both key and value are valid.
+    _result += pairBuffer;
+  }
 
-      objectKey = objectKeyList[index];
-      objectValue = object[objectKey];
+  state.tag = _tag;
+  state.dump = '{' + _result + '}';
+}
 
-      if (!writeNode(state, level + 1, objectKey, true, true, true)) {
-        continue; // Skip this pair because of invalid key.
-      }
+function writeBlockMapping(state, level, object, compact) {
+  var _result       = '',
+      _tag          = state.tag,
+      objectKeyList = Object.keys(object),
+      index,
+      length,
+      objectKey,
+      objectValue,
+      explicitPair,
+      pairBuffer;
 
-      explicitPair = (null !== state.tag && '?' !== state.tag) ||
-          (state.dump && state.dump.length > 1024);
+  // Allow sorting keys so that the output file is deterministic
+  if (state.sortKeys === true) {
+    // Default sorting
+    objectKeyList.sort();
+  } else if (typeof state.sortKeys === 'function') {
+    // Custom sort function
+    objectKeyList.sort(state.sortKeys);
+  } else if (state.sortKeys) {
+    // Something is wrong
+    throw new YAMLException('sortKeys must be a boolean or a function');
+  }
 
-      if (explicitPair) {
-        if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
-          pairBuffer += '?';
-        } else {
-          pairBuffer += '? ';
-        }
-      }
+  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+    pairBuffer = '';
 
-      pairBuffer += state.dump;
+    if (!compact || 0 !== index) {
+      pairBuffer += generateNextLine(state, level);
+    }
 
-      if (explicitPair) {
-        pairBuffer += generateNextLine(state, level);
-      }
+    objectKey = objectKeyList[index];
+    objectValue = object[objectKey];
 
-      if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
-        continue; // Skip this pair because of invalid value.
-      }
+    if (!writeNode(state, level + 1, objectKey, true, true, true)) {
+      continue; // Skip this pair because of invalid key.
+    }
 
+    explicitPair = (null !== state.tag && '?' !== state.tag) ||
+                   (state.dump && state.dump.length > 1024);
+
+    if (explicitPair) {
       if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
-        pairBuffer += ':';
+        pairBuffer += '?';
       } else {
-        pairBuffer += ': ';
+        pairBuffer += '? ';
       }
+    }
 
-      pairBuffer += state.dump;
+    pairBuffer += state.dump;
 
-      // Both key and value are valid.
-      _result += pairBuffer;
+    if (explicitPair) {
+      pairBuffer += generateNextLine(state, level);
     }
 
-    state.tag = _tag;
-    state.dump = _result || '{}'; // Empty mapping if no valid pairs.
+    if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
+      continue; // Skip this pair because of invalid value.
+    }
+
+    if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
+      pairBuffer += ':';
+    } else {
+      pairBuffer += ': ';
+    }
+
+    pairBuffer += state.dump;
+
+    // Both key and value are valid.
+    _result += pairBuffer;
   }
 
-  function detectType(state, object, explicit) {
-    var _result, typeList, index, length, type, style;
+  state.tag = _tag;
+  state.dump = _result || '{}'; // Empty mapping if no valid pairs.
+}
 
-    typeList = explicit ? state.explicitTypes : state.implicitTypes;
+function detectType(state, object, explicit) {
+  var _result, typeList, index, length, type, style;
 
-    for (index = 0, length = typeList.length; index < length; index += 1) {
-      type = typeList[index];
+  typeList = explicit ? state.explicitTypes : state.implicitTypes;
 
-      if ((type.instanceOf  || type.predicate) &&
-          (!type.instanceOf || (('object' === typeof object) && (object instanceof type.instanceOf))) &&
-          (!type.predicate  || type.predicate(object))) {
+  for (index = 0, length = typeList.length; index < length; index += 1) {
+    type = typeList[index];
 
-        state.tag = explicit ? type.tag : '?';
+    if ((type.instanceOf  || type.predicate) &&
+        (!type.instanceOf || (('object' === typeof object) && (object instanceof type.instanceOf))) &&
+        (!type.predicate  || type.predicate(object))) {
 
-        if (type.represent) {
-          style = state.styleMap[type.tag] || type.defaultStyle;
+      state.tag = explicit ? type.tag : '?';
 
-          if ('[object Function]' === _toString.call(type.represent)) {
-            _result = type.represent(object, style);
-          } else if (_hasOwnProperty.call(type.represent, style)) {
-            _result = type.represent[style](object, style);
-          } else {
-            throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
-          }
+      if (type.represent) {
+        style = state.styleMap[type.tag] || type.defaultStyle;
 
-          state.dump = _result;
+        if ('[object Function]' === _toString.call(type.represent)) {
+          _result = type.represent(object, style);
+        } else if (_hasOwnProperty.call(type.represent, style)) {
+          _result = type.represent[style](object, style);
+        } else {
+          throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
         }
 
-        return true;
+        state.dump = _result;
       }
-    }
 
-    return false;
+      return true;
+    }
   }
 
+  return false;
+}
+
 // Serializes `object` and writes it to global `result`.
 // Returns true on success, or false on invalid object.
 //
-  function writeNode(state, level, object, block, compact, iskey) {
-    state.tag = null;
-    state.dump = object;
+function writeNode(state, level, object, block, compact, iskey) {
+  state.tag = null;
+  state.dump = object;
 
-    if (!detectType(state, object, false)) {
-      detectType(state, object, true);
-    }
+  if (!detectType(state, object, false)) {
+    detectType(state, object, true);
+  }
 
-    var type = _toString.call(state.dump);
+  var type = _toString.call(state.dump);
 
-    if (block) {
-      block = (0 > state.flowLevel || state.flowLevel > level);
-    }
+  if (block) {
+    block = (0 > state.flowLevel || state.flowLevel > level);
+  }
 
-    var objectOrArray = '[object Object]' === type || '[object Array]' === type,
-        duplicateIndex,
-        duplicate;
+  var objectOrArray = '[object Object]' === type || '[object Array]' === type,
+      duplicateIndex,
+      duplicate;
 
-    if (objectOrArray) {
-      duplicateIndex = state.duplicates.indexOf(object);
-      duplicate = duplicateIndex !== -1;
-    }
+  if (objectOrArray) {
+    duplicateIndex = state.duplicates.indexOf(object);
+    duplicate = duplicateIndex !== -1;
+  }
 
-    if ((null !== state.tag && '?' !== state.tag) || duplicate || (2 !== state.indent && level > 0)) {
-      compact = false;
-    }
+  if ((null !== state.tag && '?' !== state.tag) || duplicate || (2 !== state.indent && level > 0)) {
+    compact = false;
+  }
 
-    if (duplicate && state.usedDuplicates[duplicateIndex]) {
-      state.dump = '*ref_' + duplicateIndex;
-    } else {
-      if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
-        state.usedDuplicates[duplicateIndex] = true;
-      }
-      if ('[object Object]' === type) {
-        if (block && (0 !== Object.keys(state.dump).length)) {
-          writeBlockMapping(state, level, state.dump, compact);
-          if (duplicate) {
-            state.dump = '&ref_' + duplicateIndex + state.dump;
-          }
-        } else {
-          writeFlowMapping(state, level, state.dump);
-          if (duplicate) {
-            state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
-          }
+  if (duplicate && state.usedDuplicates[duplicateIndex]) {
+    state.dump = '*ref_' + duplicateIndex;
+  } else {
+    if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
+      state.usedDuplicates[duplicateIndex] = true;
+    }
+    if ('[object Object]' === type) {
+      if (block && (0 !== Object.keys(state.dump).length)) {
+        writeBlockMapping(state, level, state.dump, compact);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + state.dump;
         }
-      } else if ('[object Array]' === type) {
-        if (block && (0 !== state.dump.length)) {
-          writeBlockSequence(state, level, state.dump, compact);
-          if (duplicate) {
-            state.dump = '&ref_' + duplicateIndex + state.dump;
-          }
-        } else {
-          writeFlowSequence(state, level, state.dump);
-          if (duplicate) {
-            state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
-          }
+      } else {
+        writeFlowMapping(state, level, state.dump);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
         }
-      } else if ('[object String]' === type) {
-        if ('?' !== state.tag) {
-          writeScalar(state, state.dump, level, iskey);
+      }
+    } else if ('[object Array]' === type) {
+      if (block && (0 !== state.dump.length)) {
+        writeBlockSequence(state, level, state.dump, compact);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + state.dump;
         }
       } else {
-        if (state.skipInvalid) {
-          return false;
+        writeFlowSequence(state, level, state.dump);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
         }
-        throw new YAMLException('unacceptable kind of an object to dump ' + type);
       }
-
-      if (null !== state.tag && '?' !== state.tag) {
-        state.dump = '!<' + state.tag + '> ' + state.dump;
+    } else if ('[object String]' === type) {
+      if ('?' !== state.tag) {
+        writeScalar(state, state.dump, level, iskey);
       }
+    } else {
+      if (state.skipInvalid) return false;
+      throw new YAMLException('unacceptable kind of an object to dump ' + type);
     }
 
-    return true;
+    if (null !== state.tag && '?' !== state.tag) {
+      state.dump = '!<' + state.tag + '> ' + state.dump;
+    }
   }
 
-  function getDuplicateReferences(object, state) {
-    var objects = [],
-        duplicatesIndexes = [],
-        index,
-        length;
+  return true;
+}
 
-    inspectNode(object, objects, duplicatesIndexes);
+function getDuplicateReferences(object, state) {
+  var objects = [],
+      duplicatesIndexes = [],
+      index,
+      length;
 
-    for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
-      state.duplicates.push(objects[duplicatesIndexes[index]]);
-    }
-    state.usedDuplicates = new Array(length);
+  inspectNode(object, objects, duplicatesIndexes);
+
+  for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
+    state.duplicates.push(objects[duplicatesIndexes[index]]);
   }
+  state.usedDuplicates = new Array(length);
+}
+
+function inspectNode(object, objects, duplicatesIndexes) {
+  var objectKeyList,
+      index,
+      length;
 
-  function inspectNode(object, objects, duplicatesIndexes) {
-    var objectKeyList,
-        index,
-        length;
+  if (null !== object && 'object' === typeof object) {
+    index = objects.indexOf(object);
+    if (-1 !== index) {
+      if (-1 === duplicatesIndexes.indexOf(index)) {
+        duplicatesIndexes.push(index);
+      }
+    } else {
+      objects.push(object);
 
-    if (null !== object && 'object' === typeof object) {
-      index = objects.indexOf(object);
-      if (-1 !== index) {
-        if (-1 === duplicatesIndexes.indexOf(index)) {
-          duplicatesIndexes.push(index);
+      if (Array.isArray(object)) {
+        for (index = 0, length = object.length; index < length; index += 1) {
+          inspectNode(object[index], objects, duplicatesIndexes);
         }
       } else {
-        objects.push(object);
+        objectKeyList = Object.keys(object);
 
-        if (Array.isArray(object)) {
-          for (index = 0, length = object.length; index < length; index += 1) {
-            inspectNode(object[index], objects, duplicatesIndexes);
-          }
-        } else {
-          objectKeyList = Object.keys(object);
-
-          for (index = 0, length = objectKeyList.length; index < length; index += 1) {
-            inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
-          }
+        for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+          inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
         }
       }
     }
   }
+}
 
-  function dump(input, options) {
-    options = options || {};
+function dump(input, options) {
+  options = options || {};
 
-    var state = new State(options);
+  var state = new State(options);
 
-    if (!state.noRefs) {
-      getDuplicateReferences(input, state);
-    }
+  if (!state.noRefs) getDuplicateReferences(input, state);
 
-    if (writeNode(state, 0, input, true, true)) {
-      return state.dump + '\n';
-    }
-    return '';
-  }
+  if (writeNode(state, 0, input, true, true)) return state.dump + '\n';
 
-  function safeDump(input, options) {
-    return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
-  }
+  return '';
+}
 
-  module.exports.dump     = dump;
-  module.exports.safeDump = safeDump;
+function safeDump(input, options) {
+  return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
+}
+
+module.exports.dump     = dump;
+module.exports.safeDump = safeDump;
 
 },{"./common":2,"./exception":4,"./schema/default_full":9,"./schema/default_safe":10}],4:[function(require,module,exports){
 // YAML error class. http://stackoverflow.com/questions/8458984
 //
-  'use strict';
-
-  function YAMLException(reason, mark) {
-    // Super constructor
-    Error.call(this);
+'use strict';
 
-    // Include stack trace in error object
-    if (Error.captureStackTrace) {
-      // Chrome and NodeJS
-      Error.captureStackTrace(this, this.constructor);
-    } else {
-      // FF, IE 10+ and Safari 6+. Fallback for others
-      this.stack = (new Error()).stack || '';
-    }
+function YAMLException(reason, mark) {
+  // Super constructor
+  Error.call(this);
 
-    this.name = 'YAMLException';
-    this.reason = reason;
-    this.mark = mark;
-    this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');
+  // Include stack trace in error object
+  if (Error.captureStackTrace) {
+    // Chrome and NodeJS
+    Error.captureStackTrace(this, this.constructor);
+  } else {
+    // FF, IE 10+ and Safari 6+. Fallback for others
+    this.stack = (new Error()).stack || '';
   }
 
+  this.name = 'YAMLException';
+  this.reason = reason;
+  this.mark = mark;
+  this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');
+}
+
 
 // Inherit from Error
-  YAMLException.prototype = Object.create(Error.prototype);
-  YAMLException.prototype.constructor = YAMLException;
+YAMLException.prototype = Object.create(Error.prototype);
+YAMLException.prototype.constructor = YAMLException;
 
 
-  YAMLException.prototype.toString = function toString(compact) {
-    var result = this.name + ': ';
+YAMLException.prototype.toString = function toString(compact) {
+  var result = this.name + ': ';
 
-    result += this.reason || '(unknown reason)';
+  result += this.reason || '(unknown reason)';
 
-    if (!compact && this.mark) {
-      result += ' ' + this.mark.toString();
-    }
+  if (!compact && this.mark) {
+    result += ' ' + this.mark.toString();
+  }
 
-    return result;
-  };
+  return result;
+};
 
 
-  module.exports = YAMLException;
+module.exports = YAMLException;
 
 },{}],5:[function(require,module,exports){
-  'use strict';
+'use strict';
 
-  /*eslint-disable max-len,no-use-before-define*/
+/*eslint-disable max-len,no-use-before-define*/
 
-  var common              = require('./common');
-  var YAMLException       = require('./exception');
-  var Mark                = require('./mark');
-  var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
-  var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
+var common              = require('./common');
+var YAMLException       = require('./exception');
+var Mark                = require('./mark');
+var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
+var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
 
 
-  var _hasOwnProperty = Object.prototype.hasOwnProperty;
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
 
 
-  var CONTEXT_FLOW_IN   = 1;
-  var CONTEXT_FLOW_OUT  = 2;
-  var CONTEXT_BLOCK_IN  = 3;
-  var CONTEXT_BLOCK_OUT = 4;
+var CONTEXT_FLOW_IN   = 1;
+var CONTEXT_FLOW_OUT  = 2;
+var CONTEXT_BLOCK_IN  = 3;
+var CONTEXT_BLOCK_OUT = 4;
 
 
-  var CHOMPING_CLIP  = 1;
-  var CHOMPING_STRIP = 2;
-  var CHOMPING_KEEP  = 3;
+var CHOMPING_CLIP  = 1;
+var CHOMPING_STRIP = 2;
+var CHOMPING_KEEP  = 3;
 
 
-  var PATTERN_NON_PRINTABLE         = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
-  var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
-  var PATTERN_FLOW_INDICATORS       = /[,\[\]\{\}]/;
-  var PATTERN_TAG_HANDLE            = /^(?:!|!!|![a-z\-]+!)$/i;
-  var PATTERN_TAG_URI               = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
+var PATTERN_NON_PRINTABLE         = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
+var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
+var PATTERN_FLOW_INDICATORS       = /[,\[\]\{\}]/;
+var PATTERN_TAG_HANDLE            = /^(?:!|!!|![a-z\-]+!)$/i;
+var PATTERN_TAG_URI               = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
 
 
-  function is_EOL(c) {
-    return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);
-  }
-
-  function is_WHITE_SPACE(c) {
-    return (c === 0x09/* Tab */) || (c === 0x20/* Space */);
-  }
+function is_EOL(c) {
+  return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);
+}
 
-  function is_WS_OR_EOL(c) {
-    return (c === 0x09/* Tab */) ||
-        (c === 0x20/* Space */) ||
-        (c === 0x0A/* LF */) ||
-        (c === 0x0D/* CR */);
-  }
+function is_WHITE_SPACE(c) {
+  return (c === 0x09/* Tab */) || (c === 0x20/* Space */);
+}
 
-  function is_FLOW_INDICATOR(c) {
-    return 0x2C/* , */ === c ||
-        0x5B/* [ */ === c ||
-        0x5D/* ] */ === c ||
-        0x7B/* { */ === c ||
-        0x7D/* } */ === c;
-  }
+function is_WS_OR_EOL(c) {
+  return (c === 0x09/* Tab */) ||
+         (c === 0x20/* Space */) ||
+         (c === 0x0A/* LF */) ||
+         (c === 0x0D/* CR */);
+}
 
-  function fromHexCode(c) {
-    var lc;
+function is_FLOW_INDICATOR(c) {
+  return 0x2C/* , */ === c ||
+         0x5B/* [ */ === c ||
+         0x5D/* ] */ === c ||
+         0x7B/* { */ === c ||
+         0x7D/* } */ === c;
+}
 
-    if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
-      return c - 0x30;
-    }
+function fromHexCode(c) {
+  var lc;
 
-    /*eslint-disable no-bitwise*/
-    lc = c | 0x20;
+  if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
+    return c - 0x30;
+  }
 
-    if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {
-      return lc - 0x61 + 10;
-    }
+  /*eslint-disable no-bitwise*/
+  lc = c | 0x20;
 
-    return -1;
+  if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {
+    return lc - 0x61 + 10;
   }
 
-  function escapedHexLen(c) {
-    if (c === 0x78/* x */) { return 2; }
-    if (c === 0x75/* u */) { return 4; }
-    if (c === 0x55/* U */) { return 8; }
-    return 0;
-  }
+  return -1;
+}
 
-  function fromDecimalCode(c) {
-    if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
-      return c - 0x30;
-    }
+function escapedHexLen(c) {
+  if (c === 0x78/* x */) { return 2; }
+  if (c === 0x75/* u */) { return 4; }
+  if (c === 0x55/* U */) { return 8; }
+  return 0;
+}
 
-    return -1;
+function fromDecimalCode(c) {
+  if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
+    return c - 0x30;
   }
 
-  function simpleEscapeSequence(c) {
-    return (c === 0x30/* 0 */) ? '\x00' :
+  return -1;
+}
+
+function simpleEscapeSequence(c) {
+  return (c === 0x30/* 0 */) ? '\x00' :
         (c === 0x61/* a */) ? '\x07' :
-            (c === 0x62/* b */) ? '\x08' :
-                (c === 0x74/* t */) ? '\x09' :
-                    (c === 0x09/* Tab */) ? '\x09' :
-                        (c === 0x6E/* n */) ? '\x0A' :
-                            (c === 0x76/* v */) ? '\x0B' :
-                                (c === 0x66/* f */) ? '\x0C' :
-                                    (c === 0x72/* r */) ? '\x0D' :
-                                        (c === 0x65/* e */) ? '\x1B' :
-                                            (c === 0x20/* Space */) ? ' ' :
-                                                (c === 0x22/* " */) ? '\x22' :
-                                                    (c === 0x2F/* / */) ? '/' :
-                                                        (c === 0x5C/* \ */) ? '\x5C' :
-                                                            (c === 0x4E/* N */) ? '\x85' :
-                                                                (c === 0x5F/* _ */) ? '\xA0' :
-                                                                    (c === 0x4C/* L */) ? '\u2028' :
-                                                                        (c === 0x50/* P */) ? '\u2029' : '';
-  }
+        (c === 0x62/* b */) ? '\x08' :
+        (c === 0x74/* t */) ? '\x09' :
+        (c === 0x09/* Tab */) ? '\x09' :
+        (c === 0x6E/* n */) ? '\x0A' :
+        (c === 0x76/* v */) ? '\x0B' :
+        (c === 0x66/* f */) ? '\x0C' :
+        (c === 0x72/* r */) ? '\x0D' :
+        (c === 0x65/* e */) ? '\x1B' :
+        (c === 0x20/* Space */) ? ' ' :
+        (c === 0x22/* " */) ? '\x22' :
+        (c === 0x2F/* / */) ? '/' :
+        (c === 0x5C/* \ */) ? '\x5C' :
+        (c === 0x4E/* N */) ? '\x85' :
+        (c === 0x5F/* _ */) ? '\xA0' :
+        (c === 0x4C/* L */) ? '\u2028' :
+        (c === 0x50/* P */) ? '\u2029' : '';
+}
 
-  function charFromCodepoint(c) {
-    if (c <= 0xFFFF) {
-      return String.fromCharCode(c);
-    }
-    // Encode UTF-16 surrogate pair
-    // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF
-    return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800,
-        ((c - 0x010000) & 0x03FF) + 0xDC00);
+function charFromCodepoint(c) {
+  if (c <= 0xFFFF) {
+    return String.fromCharCode(c);
   }
+  // Encode UTF-16 surrogate pair
+  // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF
+  return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800,
+                             ((c - 0x010000) & 0x03FF) + 0xDC00);
+}
 
-  var simpleEscapeCheck = new Array(256); // integer, for fast access
-  var simpleEscapeMap = new Array(256);
-  for (var i = 0; i < 256; i++) {
-    simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
-    simpleEscapeMap[i] = simpleEscapeSequence(i);
-  }
+var simpleEscapeCheck = new Array(256); // integer, for fast access
+var simpleEscapeMap = new Array(256);
+for (var i = 0; i < 256; i++) {
+  simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
+  simpleEscapeMap[i] = simpleEscapeSequence(i);
+}
 
 
-  function State(input, options) {
-    this.input = input;
+function State(input, options) {
+  this.input = input;
 
-    this.filename  = options['filename']  || null;
-    this.schema    = options['schema']    || DEFAULT_FULL_SCHEMA;
-    this.onWarning = options['onWarning'] || null;
-    this.legacy    = options['legacy']    || false;
-    this.json      = options['json']      || false;
+  this.filename  = options['filename']  || null;
+  this.schema    = options['schema']    || DEFAULT_FULL_SCHEMA;
+  this.onWarning = options['onWarning'] || null;
+  this.legacy    = options['legacy']    || false;
+  this.json      = options['json']      || false;
+  this.listener  = options['listener']  || null;
 
-    this.implicitTypes = this.schema.compiledImplicit;
-    this.typeMap       = this.schema.compiledTypeMap;
+  this.implicitTypes = this.schema.compiledImplicit;
+  this.typeMap       = this.schema.compiledTypeMap;
 
-    this.length     = input.length;
-    this.position   = 0;
-    this.line       = 0;
-    this.lineStart  = 0;
-    this.lineIndent = 0;
+  this.length     = input.length;
+  this.position   = 0;
+  this.line       = 0;
+  this.lineStart  = 0;
+  this.lineIndent = 0;
 
-    this.documents = [];
+  this.documents = [];
 
-    /*
-     this.version;
-     this.checkLineBreaks;
-     this.tagMap;
-     this.anchorMap;
-     this.tag;
-     this.anchor;
-     this.kind;
-     this.result;*/
+  /*
+  this.version;
+  this.checkLineBreaks;
+  this.tagMap;
+  this.anchorMap;
+  this.tag;
+  this.anchor;
+  this.kind;
+  this.result;*/
 
-  }
+}
 
 
-  function generateError(state, message) {
-    return new YAMLException(
-        message,
-        new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart)));
-  }
+function generateError(state, message) {
+  return new YAMLException(
+    message,
+    new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart)));
+}
 
-  function throwError(state, message) {
-    throw generateError(state, message);
-  }
+function throwError(state, message) {
+  throw generateError(state, message);
+}
 
-  function throwWarning(state, message) {
-    if (state.onWarning) {
-      state.onWarning.call(null, generateError(state, message));
-    }
+function throwWarning(state, message) {
+  if (state.onWarning) {
+    state.onWarning.call(null, generateError(state, message));
   }
+}
 
 
-  var directiveHandlers = {
-
-    YAML: function handleYamlDirective(state, name, args) {
+var directiveHandlers = {
 
-      var match, major, minor;
+  YAML: function handleYamlDirective(state, name, args) {
 
-      if (null !== state.version) {
-        throwError(state, 'duplication of %YAML directive');
-      }
+    var match, major, minor;
 
-      if (1 !== args.length) {
-        throwError(state, 'YAML directive accepts exactly one argument');
-      }
+    if (null !== state.version) {
+      throwError(state, 'duplication of %YAML directive');
+    }
 
-      match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
+    if (1 !== args.length) {
+      throwError(state, 'YAML directive accepts exactly one argument');
+    }
 
-      if (null === match) {
-        throwError(state, 'ill-formed argument of the YAML directive');
-      }
+    match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
 
-      major = parseInt(match[1], 10);
-      minor = parseInt(match[2], 10);
+    if (null === match) {
+      throwError(state, 'ill-formed argument of the YAML directive');
+    }
 
-      if (1 !== major) {
-        throwError(state, 'unacceptable YAML version of the document');
-      }
+    major = parseInt(match[1], 10);
+    minor = parseInt(match[2], 10);
 
-      state.version = args[0];
-      state.checkLineBreaks = (minor < 2);
+    if (1 !== major) {
+      throwError(state, 'unacceptable YAML version of the document');
+    }
 
-      if (1 !== minor && 2 !== minor) {
-        throwWarning(state, 'unsupported YAML version of the document');
-      }
-    },
+    state.version = args[0];
+    state.checkLineBreaks = (minor < 2);
 
-    TAG: function handleTagDirective(state, name, args) {
+    if (1 !== minor && 2 !== minor) {
+      throwWarning(state, 'unsupported YAML version of the document');
+    }
+  },
 
-      var handle, prefix;
+  TAG: function handleTagDirective(state, name, args) {
 
-      if (2 !== args.length) {
-        throwError(state, 'TAG directive accepts exactly two arguments');
-      }
+    var handle, prefix;
 
-      handle = args[0];
-      prefix = args[1];
+    if (2 !== args.length) {
+      throwError(state, 'TAG directive accepts exactly two arguments');
+    }
 
-      if (!PATTERN_TAG_HANDLE.test(handle)) {
-        throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');
-      }
+    handle = args[0];
+    prefix = args[1];
 
-      if (_hasOwnProperty.call(state.tagMap, handle)) {
-        throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
-      }
+    if (!PATTERN_TAG_HANDLE.test(handle)) {
+      throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');
+    }
 
-      if (!PATTERN_TAG_URI.test(prefix)) {
-        throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');
-      }
+    if (_hasOwnProperty.call(state.tagMap, handle)) {
+      throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
+    }
 
-      state.tagMap[handle] = prefix;
+    if (!PATTERN_TAG_URI.test(prefix)) {
+      throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');
     }
-  };
 
+    state.tagMap[handle] = prefix;
+  }
+};
 
-  function captureSegment(state, start, end, checkJson) {
-    var _position, _length, _character, _result;
 
-    if (start < end) {
-      _result = state.input.slice(start, end);
+function captureSegment(state, start, end, checkJson) {
+  var _position, _length, _character, _result;
 
-      if (checkJson) {
-        for (_position = 0, _length = _result.length;
-             _position < _length;
-             _position += 1) {
-          _character = _result.charCodeAt(_position);
-          if (!(0x09 === _character ||
+  if (start < end) {
+    _result = state.input.slice(start, end);
+
+    if (checkJson) {
+      for (_position = 0, _length = _result.length;
+           _position < _length;
+           _position += 1) {
+        _character = _result.charCodeAt(_position);
+        if (!(0x09 === _character ||
               0x20 <= _character && _character <= 0x10FFFF)) {
-            throwError(state, 'expected valid JSON character');
-          }
+          throwError(state, 'expected valid JSON character');
         }
-      } else if (PATTERN_NON_PRINTABLE.test(_result)) {
-        throwError(state, 'the stream contains non-printable characters');
       }
-
-      state.result += _result;
+    } else if (PATTERN_NON_PRINTABLE.test(_result)) {
+      throwError(state, 'the stream contains non-printable characters');
     }
+
+    state.result += _result;
   }
+}
 
-  function mergeMappings(state, destination, source, overridableKeys) {
-    var sourceKeys, key, index, quantity;
+function mergeMappings(state, destination, source, overridableKeys) {
+  var sourceKeys, key, index, quantity;
 
-    if (!common.isObject(source)) {
-      throwError(state, 'cannot merge mappings; the provided source object is unacceptable');
-    }
+  if (!common.isObject(source)) {
+    throwError(state, 'cannot merge mappings; the provided source object is unacceptable');
+  }
 
-    sourceKeys = Object.keys(source);
+  sourceKeys = Object.keys(source);
 
-    for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
-      key = sourceKeys[index];
+  for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
+    key = sourceKeys[index];
 
-      if (!_hasOwnProperty.call(destination, key)) {
-        destination[key] = source[key];
-        overridableKeys[key] = true;
-      }
+    if (!_hasOwnProperty.call(destination, key)) {
+      destination[key] = source[key];
+      overridableKeys[key] = true;
     }
   }
+}
 
-  function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) {
-    var index, quantity;
+function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) {
+  var index, quantity;
 
-    keyNode = String(keyNode);
+  keyNode = String(keyNode);
 
-    if (null === _result) {
-      _result = {};
-    }
+  if (null === _result) {
+    _result = {};
+  }
 
-    if ('tag:yaml.org,2002:merge' === keyTag) {
-      if (Array.isArray(valueNode)) {
-        for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
-          mergeMappings(state, _result, valueNode[index], overridableKeys);
-        }
-      } else {
-        mergeMappings(state, _result, valueNode, overridableKeys);
+  if ('tag:yaml.org,2002:merge' === keyTag) {
+    if (Array.isArray(valueNode)) {
+      for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
+        mergeMappings(state, _result, valueNode[index], overridableKeys);
       }
     } else {
-      if (!state.json &&
-          !_hasOwnProperty.call(overridableKeys, keyNode) &&
-          _hasOwnProperty.call(_result, keyNode)) {
-        throwError(state, 'duplicated mapping key');
-      }
-      _result[keyNode] = valueNode;
-      delete overridableKeys[keyNode];
+      mergeMappings(state, _result, valueNode, overridableKeys);
     }
-
-    return _result;
+  } else {
+    if (!state.json &&
+        !_hasOwnProperty.call(overridableKeys, keyNode) &&
+        _hasOwnProperty.call(_result, keyNode)) {
+      throwError(state, 'duplicated mapping key');
+    }
+    _result[keyNode] = valueNode;
+    delete overridableKeys[keyNode];
   }
 
-  function readLineBreak(state) {
-    var ch;
+  return _result;
+}
 
-    ch = state.input.charCodeAt(state.position);
+function readLineBreak(state) {
+  var ch;
 
-    if (0x0A/* LF */ === ch) {
-      state.position++;
-    } else if (0x0D/* CR */ === ch) {
+  ch = state.input.charCodeAt(state.position);
+
+  if (0x0A/* LF */ === ch) {
+    state.position++;
+  } else if (0x0D/* CR */ === ch) {
+    state.position++;
+    if (0x0A/* LF */ === state.input.charCodeAt(state.position)) {
       state.position++;
-      if (0x0A/* LF */ === state.input.charCodeAt(state.position)) {
-        state.position++;
-      }
-    } else {
-      throwError(state, 'a line break is expected');
     }
-
-    state.line += 1;
-    state.lineStart = state.position;
+  } else {
+    throwError(state, 'a line break is expected');
   }
 
-  function skipSeparationSpace(state, allowComments, checkIndent) {
-    var lineBreaks = 0,
-        ch = state.input.charCodeAt(state.position);
+  state.line += 1;
+  state.lineStart = state.position;
+}
 
-    while (0 !== ch) {
-      while (is_WHITE_SPACE(ch)) {
-        ch = state.input.charCodeAt(++state.position);
-      }
+function skipSeparationSpace(state, allowComments, checkIndent) {
+  var lineBreaks = 0,
+      ch = state.input.charCodeAt(state.position);
 
-      if (allowComments && 0x23/* # */ === ch) {
-        do {
-          ch = state.input.charCodeAt(++state.position);
-        } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && 0 !== ch);
-      }
+  while (0 !== ch) {
+    while (is_WHITE_SPACE(ch)) {
+      ch = state.input.charCodeAt(++state.position);
+    }
 
-      if (is_EOL(ch)) {
-        readLineBreak(state);
+    if (allowComments && 0x23/* # */ === ch) {
+      do {
+        ch = state.input.charCodeAt(++state.position);
+      } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && 0 !== ch);
+    }
 
-        ch = state.input.charCodeAt(state.position);
-        lineBreaks++;
-        state.lineIndent = 0;
+    if (is_EOL(ch)) {
+      readLineBreak(state);
 
-        while (0x20/* Space */ === ch) {
-          state.lineIndent++;
-          ch = state.input.charCodeAt(++state.position);
-        }
-      } else {
-        break;
-      }
-    }
+      ch = state.input.charCodeAt(state.position);
+      lineBreaks++;
+      state.lineIndent = 0;
 
-    if (-1 !== checkIndent && 0 !== lineBreaks && state.lineIndent < checkIndent) {
-      throwWarning(state, 'deficient indentation');
+      while (0x20/* Space */ === ch) {
+        state.lineIndent++;
+        ch = state.input.charCodeAt(++state.position);
+      }
+    } else {
+      break;
     }
-
-    return lineBreaks;
   }
 
-  function testDocumentSeparator(state) {
-    var _position = state.position,
-        ch;
+  if (-1 !== checkIndent && 0 !== lineBreaks && state.lineIndent < checkIndent) {
+    throwWarning(state, 'deficient indentation');
+  }
 
-    ch = state.input.charCodeAt(_position);
+  return lineBreaks;
+}
 
-    // Condition state.position === state.lineStart is tested
-    // in parent on each call, for efficiency. No needs to test here again.
-    if ((0x2D/* - */ === ch || 0x2E/* . */ === ch) &&
-        state.input.charCodeAt(_position + 1) === ch &&
-        state.input.charCodeAt(_position + 2) === ch) {
+function testDocumentSeparator(state) {
+  var _position = state.position,
+      ch;
 
-      _position += 3;
+  ch = state.input.charCodeAt(_position);
 
-      ch = state.input.charCodeAt(_position);
+  // Condition state.position === state.lineStart is tested
+  // in parent on each call, for efficiency. No needs to test here again.
+  if ((0x2D/* - */ === ch || 0x2E/* . */ === ch) &&
+      state.input.charCodeAt(_position + 1) === ch &&
+      state.input.charCodeAt(_position + 2) === ch) {
 
-      if (ch === 0 || is_WS_OR_EOL(ch)) {
-        return true;
-      }
-    }
+    _position += 3;
 
-    return false;
-  }
+    ch = state.input.charCodeAt(_position);
 
-  function writeFoldedLines(state, count) {
-    if (1 === count) {
-      state.result += ' ';
-    } else if (count > 1) {
-      state.result += common.repeat('\n', count - 1);
+    if (ch === 0 || is_WS_OR_EOL(ch)) {
+      return true;
     }
   }
 
+  return false;
+}
+
+function writeFoldedLines(state, count) {
+  if (1 === count) {
+    state.result += ' ';
+  } else if (count > 1) {
+    state.result += common.repeat('\n', count - 1);
+  }
+}
+
+
+function readPlainScalar(state, nodeIndent, withinFlowCollection) {
+  var preceding,
+      following,
+      captureStart,
+      captureEnd,
+      hasPendingContent,
+      _line,
+      _lineStart,
+      _lineIndent,
+      _kind = state.kind,
+      _result = state.result,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (is_WS_OR_EOL(ch)             ||
+      is_FLOW_INDICATOR(ch)        ||
+      0x23/* # */           === ch ||
+      0x26/* & */           === ch ||
+      0x2A/* * */           === ch ||
+      0x21/* ! */           === ch ||
+      0x7C/* | */           === ch ||
+      0x3E/* > */           === ch ||
+      0x27/* ' */           === ch ||
+      0x22/* " */           === ch ||
+      0x25/* % */           === ch ||
+      0x40/* @ */           === ch ||
+      0x60/* ` */           === ch) {
+    return false;
+  }
 
-  function readPlainScalar(state, nodeIndent, withinFlowCollection) {
-    var preceding,
-        following,
-        captureStart,
-        captureEnd,
-        hasPendingContent,
-        _line,
-        _lineStart,
-        _lineIndent,
-        _kind = state.kind,
-        _result = state.result,
-        ch;
-
-    ch = state.input.charCodeAt(state.position);
+  if (0x3F/* ? */ === ch || 0x2D/* - */ === ch) {
+    following = state.input.charCodeAt(state.position + 1);
 
-    if (is_WS_OR_EOL(ch)             ||
-        is_FLOW_INDICATOR(ch)        ||
-        0x23/* # */           === ch ||
-        0x26/* & */           === ch ||
-        0x2A/* * */           === ch ||
-        0x21/* ! */           === ch ||
-        0x7C/* | */           === ch ||
-        0x3E/* > */           === ch ||
-        0x27/* ' */           === ch ||
-        0x22/* " */           === ch ||
-        0x25/* % */           === ch ||
-        0x40/* @ */           === ch ||
-        0x60/* ` */           === ch) {
+    if (is_WS_OR_EOL(following) ||
+        withinFlowCollection && is_FLOW_INDICATOR(following)) {
       return false;
     }
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+  captureStart = captureEnd = state.position;
+  hasPendingContent = false;
 
-    if (0x3F/* ? */ === ch || 0x2D/* - */ === ch) {
+  while (0 !== ch) {
+    if (0x3A/* : */ === ch) {
       following = state.input.charCodeAt(state.position + 1);
 
       if (is_WS_OR_EOL(following) ||
           withinFlowCollection && is_FLOW_INDICATOR(following)) {
-        return false;
+        break;
       }
-    }
-
-    state.kind = 'scalar';
-    state.result = '';
-    captureStart = captureEnd = state.position;
-    hasPendingContent = false;
-
-    while (0 !== ch) {
-      if (0x3A/* : */ === ch) {
-        following = state.input.charCodeAt(state.position + 1);
 
-        if (is_WS_OR_EOL(following) ||
-            withinFlowCollection && is_FLOW_INDICATOR(following)) {
-          break;
-        }
-
-      } else if (0x23/* # */ === ch) {
-        preceding = state.input.charCodeAt(state.position - 1);
-
-        if (is_WS_OR_EOL(preceding)) {
-          break;
-        }
+    } else if (0x23/* # */ === ch) {
+      preceding = state.input.charCodeAt(state.position - 1);
 
-      } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||
-          withinFlowCollection && is_FLOW_INDICATOR(ch)) {
+      if (is_WS_OR_EOL(preceding)) {
         break;
-
-      } else if (is_EOL(ch)) {
-        _line = state.line;
-        _lineStart = state.lineStart;
-        _lineIndent = state.lineIndent;
-        skipSeparationSpace(state, false, -1);
-
-        if (state.lineIndent >= nodeIndent) {
-          hasPendingContent = true;
-          ch = state.input.charCodeAt(state.position);
-          continue;
-        } else {
-          state.position = captureEnd;
-          state.line = _line;
-          state.lineStart = _lineStart;
-          state.lineIndent = _lineIndent;
-          break;
-        }
       }
 
-      if (hasPendingContent) {
-        captureSegment(state, captureStart, captureEnd, false);
-        writeFoldedLines(state, state.line - _line);
-        captureStart = captureEnd = state.position;
-        hasPendingContent = false;
-      }
+    } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||
+               withinFlowCollection && is_FLOW_INDICATOR(ch)) {
+      break;
 
-      if (!is_WHITE_SPACE(ch)) {
-        captureEnd = state.position + 1;
-      }
+    } else if (is_EOL(ch)) {
+      _line = state.line;
+      _lineStart = state.lineStart;
+      _lineIndent = state.lineIndent;
+      skipSeparationSpace(state, false, -1);
 
-      ch = state.input.charCodeAt(++state.position);
+      if (state.lineIndent >= nodeIndent) {
+        hasPendingContent = true;
+        ch = state.input.charCodeAt(state.position);
+        continue;
+      } else {
+        state.position = captureEnd;
+        state.line = _line;
+        state.lineStart = _lineStart;
+        state.lineIndent = _lineIndent;
+        break;
+      }
     }
 
-    captureSegment(state, captureStart, captureEnd, false);
+    if (hasPendingContent) {
+      captureSegment(state, captureStart, captureEnd, false);
+      writeFoldedLines(state, state.line - _line);
+      captureStart = captureEnd = state.position;
+      hasPendingContent = false;
+    }
 
-    if (state.result) {
-      return true;
+    if (!is_WHITE_SPACE(ch)) {
+      captureEnd = state.position + 1;
     }
 
-    state.kind = _kind;
-    state.result = _result;
-    return false;
+    ch = state.input.charCodeAt(++state.position);
   }
 
-  function readSingleQuotedScalar(state, nodeIndent) {
-    var ch,
-        captureStart, captureEnd;
+  captureSegment(state, captureStart, captureEnd, false);
 
-    ch = state.input.charCodeAt(state.position);
+  if (state.result) {
+    return true;
+  }
 
-    if (0x27/* ' */ !== ch) {
-      return false;
-    }
+  state.kind = _kind;
+  state.result = _result;
+  return false;
+}
 
-    state.kind = 'scalar';
-    state.result = '';
-    state.position++;
-    captureStart = captureEnd = state.position;
+function readSingleQuotedScalar(state, nodeIndent) {
+  var ch,
+      captureStart, captureEnd;
 
-    while (0 !== (ch = state.input.charCodeAt(state.position))) {
-      if (0x27/* ' */ === ch) {
-        captureSegment(state, captureStart, state.position, true);
-        ch = state.input.charCodeAt(++state.position);
+  ch = state.input.charCodeAt(state.position);
 
-        if (0x27/* ' */ === ch) {
-          captureStart = captureEnd = state.position;
-          state.position++;
-        } else {
-          return true;
-        }
+  if (0x27/* ' */ !== ch) {
+    return false;
+  }
 
-      } else if (is_EOL(ch)) {
-        captureSegment(state, captureStart, captureEnd, true);
-        writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
-        captureStart = captureEnd = state.position;
+  state.kind = 'scalar';
+  state.result = '';
+  state.position++;
+  captureStart = captureEnd = state.position;
 
-      } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
-        throwError(state, 'unexpected end of the document within a single quoted scalar');
+  while (0 !== (ch = state.input.charCodeAt(state.position))) {
+    if (0x27/* ' */ === ch) {
+      captureSegment(state, captureStart, state.position, true);
+      ch = state.input.charCodeAt(++state.position);
 
-      } else {
+      if (0x27/* ' */ === ch) {
+        captureStart = captureEnd = state.position;
         state.position++;
-        captureEnd = state.position;
+      } else {
+        return true;
       }
-    }
-
-    throwError(state, 'unexpected end of the stream within a single quoted scalar');
-  }
 
-  function readDoubleQuotedScalar(state, nodeIndent) {
-    var captureStart,
-        captureEnd,
-        hexLength,
-        hexResult,
-        tmp,
-        ch;
+    } else if (is_EOL(ch)) {
+      captureSegment(state, captureStart, captureEnd, true);
+      writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
+      captureStart = captureEnd = state.position;
 
-    ch = state.input.charCodeAt(state.position);
+    } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
+      throwError(state, 'unexpected end of the document within a single quoted scalar');
 
-    if (0x22/* " */ !== ch) {
-      return false;
+    } else {
+      state.position++;
+      captureEnd = state.position;
     }
+  }
 
-    state.kind = 'scalar';
-    state.result = '';
-    state.position++;
-    captureStart = captureEnd = state.position;
+  throwError(state, 'unexpected end of the stream within a single quoted scalar');
+}
 
-    while (0 !== (ch = state.input.charCodeAt(state.position))) {
-      if (0x22/* " */ === ch) {
-        captureSegment(state, captureStart, state.position, true);
-        state.position++;
-        return true;
+function readDoubleQuotedScalar(state, nodeIndent) {
+  var captureStart,
+      captureEnd,
+      hexLength,
+      hexResult,
+      tmp,
+      ch;
 
-      } else if (0x5C/* \ */ === ch) {
-        captureSegment(state, capture

<TRUNCATED>

[20/27] brooklyn-ui git commit: add font awesome

Posted by he...@apache.org.
add font awesome


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/631292f7
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/631292f7
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/631292f7

Branch: refs/heads/master
Commit: 631292f73e3924b703410195af19465c2c114a69
Parents: 1058fa7
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Feb 16 16:57:46 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Feb 16 16:57:46 2016 +0000

----------------------------------------------------------------------
 src/main/license/source-inclusions.yaml         |    3 +
 .../assets/js/libs/font-awesome/HELP-US-OUT.txt |    7 +
 .../js/libs/font-awesome/css/font-awesome.css   | 2086 ++++++++++++++++++
 .../libs/font-awesome/css/font-awesome.min.css  |    4 +
 .../js/libs/font-awesome/fonts/FontAwesome.otf  |  Bin 0 -> 109688 bytes
 .../font-awesome/fonts/fontawesome-webfont.eot  |  Bin 0 -> 70807 bytes
 .../font-awesome/fonts/fontawesome-webfont.svg  |  655 ++++++
 .../font-awesome/fonts/fontawesome-webfont.ttf  |  Bin 0 -> 142072 bytes
 .../font-awesome/fonts/fontawesome-webfont.woff |  Bin 0 -> 83588 bytes
 .../fonts/fontawesome-webfont.woff2             |  Bin 0 -> 66624 bytes
 .../js/libs/font-awesome/less/animated.less     |   34 +
 .../libs/font-awesome/less/bordered-pulled.less |   25 +
 .../assets/js/libs/font-awesome/less/core.less  |   12 +
 .../js/libs/font-awesome/less/fixed-width.less  |    6 +
 .../js/libs/font-awesome/less/font-awesome.less |   17 +
 .../assets/js/libs/font-awesome/less/icons.less |  697 ++++++
 .../js/libs/font-awesome/less/larger.less       |   13 +
 .../assets/js/libs/font-awesome/less/list.less  |   19 +
 .../js/libs/font-awesome/less/mixins.less       |   26 +
 .../assets/js/libs/font-awesome/less/path.less  |   15 +
 .../libs/font-awesome/less/rotated-flipped.less |   20 +
 .../js/libs/font-awesome/less/stacked.less      |   20 +
 .../js/libs/font-awesome/less/variables.less    |  708 ++++++
 .../js/libs/font-awesome/scss/_animated.scss    |   34 +
 .../font-awesome/scss/_bordered-pulled.scss     |   25 +
 .../assets/js/libs/font-awesome/scss/_core.scss |   12 +
 .../js/libs/font-awesome/scss/_fixed-width.scss |    6 +
 .../js/libs/font-awesome/scss/_icons.scss       |  697 ++++++
 .../js/libs/font-awesome/scss/_larger.scss      |   13 +
 .../assets/js/libs/font-awesome/scss/_list.scss |   19 +
 .../js/libs/font-awesome/scss/_mixins.scss      |   26 +
 .../assets/js/libs/font-awesome/scss/_path.scss |   15 +
 .../font-awesome/scss/_rotated-flipped.scss     |   20 +
 .../js/libs/font-awesome/scss/_stacked.scss     |   20 +
 .../js/libs/font-awesome/scss/_variables.scss   |  708 ++++++
 .../js/libs/font-awesome/scss/font-awesome.scss |   17 +
 src/main/webapp/index.html                      |    1 +
 37 files changed, 5980 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/license/source-inclusions.yaml
----------------------------------------------------------------------
diff --git a/src/main/license/source-inclusions.yaml b/src/main/license/source-inclusions.yaml
index d1bb072..d61d6d6 100644
--- a/src/main/license/source-inclusions.yaml
+++ b/src/main/license/source-inclusions.yaml
@@ -41,3 +41,6 @@
 - id: jquery.form.js
 - id: marked.js
 - id: codemirror.js
+- id: font-awesome-fonts
+- id: font-awesome-code
+

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/HELP-US-OUT.txt
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/HELP-US-OUT.txt b/src/main/webapp/assets/js/libs/font-awesome/HELP-US-OUT.txt
new file mode 100644
index 0000000..cfd9d9f
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/HELP-US-OUT.txt
@@ -0,0 +1,7 @@
+I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
+Fonticons (https://fonticons.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
+comprehensive icon sets or copy and paste your own.
+
+Please. Check it out.
+
+-Dave Gandy

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/css/font-awesome.css
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/css/font-awesome.css b/src/main/webapp/assets/js/libs/font-awesome/css/font-awesome.css
new file mode 100644
index 0000000..b2a5fe2
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/css/font-awesome.css
@@ -0,0 +1,2086 @@
+/*!
+ *  Font Awesome 4.5.0 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.5.0');
+  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+.fa {
+  display: inline-block;
+  font: normal normal normal 14px/1 FontAwesome;
+  font-size: inherit;
+  text-rendering: auto;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+/* makes the font 33% larger relative to the icon container */
+.fa-lg {
+  font-size: 1.33333333em;
+  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.28571429em;
+  text-align: center;
+}
+.fa-ul {
+  padding-left: 0;
+  margin-left: 2.14285714em;
+  list-style-type: none;
+}
+.fa-ul > li {
+  position: relative;
+}
+.fa-li {
+  position: absolute;
+  left: -2.14285714em;
+  width: 2.14285714em;
+  top: 0.14285714em;
+  text-align: center;
+}
+.fa-li.fa-lg {
+  left: -1.85714286em;
+}
+.fa-border {
+  padding: .2em .25em .15em;
+  border: solid 0.08em #eeeeee;
+  border-radius: .1em;
+}
+.fa-pull-left {
+  float: left;
+}
+.fa-pull-right {
+  float: right;
+}
+.fa.fa-pull-left {
+  margin-right: .3em;
+}
+.fa.fa-pull-right {
+  margin-left: .3em;
+}
+/* Deprecated as of 4.4.0 */
+.pull-right {
+  float: right;
+}
+.pull-left {
+  float: left;
+}
+.fa.pull-left {
+  margin-right: .3em;
+}
+.fa.pull-right {
+  margin-left: .3em;
+}
+.fa-spin {
+  -webkit-animation: fa-spin 2s infinite linear;
+  animation: fa-spin 2s infinite linear;
+}
+.fa-pulse {
+  -webkit-animation: fa-spin 1s infinite steps(8);
+  animation: fa-spin 1s infinite steps(8);
+}
+@-webkit-keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+.fa-rotate-90 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
+  -webkit-transform: rotate(90deg);
+  -ms-transform: rotate(90deg);
+  transform: rotate(90deg);
+}
+.fa-rotate-180 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  -webkit-transform: rotate(180deg);
+  -ms-transform: rotate(180deg);
+  transform: rotate(180deg);
+}
+.fa-rotate-270 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
+  -webkit-transform: rotate(270deg);
+  -ms-transform: rotate(270deg);
+  transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
+  -webkit-transform: scale(-1, 1);
+  -ms-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);
+  -ms-transform: scale(1, -1);
+  transform: scale(1, -1);
+}
+:root .fa-rotate-90,
+:root .fa-rotate-180,
+:root .fa-rotate-270,
+:root .fa-flip-horizontal,
+:root .fa-flip-vertical {
+  filter: none;
+}
+.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-remove:before,
+.fa-close:before,
+.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-photo:before,
+.fa-image:before,
+.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,
+.fa-bar-chart: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-f:before,
+.fa-facebook:before {
+  content: "\f09a";
+}
+.fa-github:before {
+  content: "\f09b";
+}
+.fa-unlock:before {
+  content: "\f09c";
+}
+.fa-credit-card:before {
+  content: "\f09d";
+}
+.fa-feed:before,
+.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-navicon:before,
+.fa-reorder:before,
+.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-desc:before {
+  content: "\f0dd";
+}
+.fa-sort-up:before,
+.fa-sort-asc: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-mail-reply-all:before,
+.fa-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,
+.fa-gratipay: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";
+}
+.fa-space-shuttle:before {
+  content: "\f197";
+}
+.fa-slack:before {
+  content: "\f198";
+}
+.fa-envelope-square:before {
+  content: "\f199";
+}
+.fa-wordpress:before {
+  content: "\f19a";
+}
+.fa-openid:before {
+  content: "\f19b";
+}
+.fa-institution:before,
+.fa-bank:before,
+.fa-university:before {
+  content: "\f19c";
+}
+.fa-mortar-board:before,
+.fa-graduation-cap:before {
+  content: "\f19d";
+}
+.fa-yahoo:before {
+  content: "\f19e";
+}
+.fa-google:before {
+  content: "\f1a0";
+}
+.fa-reddit:before {
+  content: "\f1a1";
+}
+.fa-reddit-square:before {
+  content: "\f1a2";
+}
+.fa-stumbleupon-circle:before {
+  content: "\f1a3";
+}
+.fa-stumbleupon:before {
+  content: "\f1a4";
+}
+.fa-delicious:before {
+  content: "\f1a5";
+}
+.fa-digg:before {
+  content: "\f1a6";
+}
+.fa-pied-piper:before {
+  content: "\f1a7";
+}
+.fa-pied-piper-alt:before {
+  content: "\f1a8";
+}
+.fa-drupal:before {
+  content: "\f1a9";
+}
+.fa-joomla:before {
+  content: "\f1aa";
+}
+.fa-language:before {
+  content: "\f1ab";
+}
+.fa-fax:before {
+  content: "\f1ac";
+}
+.fa-building:before {
+  content: "\f1ad";
+}
+.fa-child:before {
+  content: "\f1ae";
+}
+.fa-paw:before {
+  content: "\f1b0";
+}
+.fa-spoon:before {
+  content: "\f1b1";
+}
+.fa-cube:before {
+  content: "\f1b2";
+}
+.fa-cubes:before {
+  content: "\f1b3";
+}
+.fa-behance:before {
+  content: "\f1b4";
+}
+.fa-behance-square:before {
+  content: "\f1b5";
+}
+.fa-steam:before {
+  content: "\f1b6";
+}
+.fa-steam-square:before {
+  content: "\f1b7";
+}
+.fa-recycle:before {
+  content: "\f1b8";
+}
+.fa-automobile:before,
+.fa-car:before {
+  content: "\f1b9";
+}
+.fa-cab:before,
+.fa-taxi:before {
+  content: "\f1ba";
+}
+.fa-tree:before {
+  content: "\f1bb";
+}
+.fa-spotify:before {
+  content: "\f1bc";
+}
+.fa-deviantart:before {
+  content: "\f1bd";
+}
+.fa-soundcloud:before {
+  content: "\f1be";
+}
+.fa-database:before {
+  content: "\f1c0";
+}
+.fa-file-pdf-o:before {
+  content: "\f1c1";
+}
+.fa-file-word-o:before {
+  content: "\f1c2";
+}
+.fa-file-excel-o:before {
+  content: "\f1c3";
+}
+.fa-file-powerpoint-o:before {
+  content: "\f1c4";
+}
+.fa-file-photo-o:before,
+.fa-file-picture-o:before,
+.fa-file-image-o:before {
+  content: "\f1c5";
+}
+.fa-file-zip-o:before,
+.fa-file-archive-o:before {
+  content: "\f1c6";
+}
+.fa-file-sound-o:before,
+.fa-file-audio-o:before {
+  content: "\f1c7";
+}
+.fa-file-movie-o:before,
+.fa-file-video-o:before {
+  content: "\f1c8";
+}
+.fa-file-code-o:before {
+  content: "\f1c9";
+}
+.fa-vine:before {
+  content: "\f1ca";
+}
+.fa-codepen:before {
+  content: "\f1cb";
+}
+.fa-jsfiddle:before {
+  content: "\f1cc";
+}
+.fa-life-bouy:before,
+.fa-life-buoy:before,
+.fa-life-saver:before,
+.fa-support:before,
+.fa-life-ring:before {
+  content: "\f1cd";
+}
+.fa-circle-o-notch:before {
+  content: "\f1ce";
+}
+.fa-ra:before,
+.fa-rebel:before {
+  content: "\f1d0";
+}
+.fa-ge:before,
+.fa-empire:before {
+  content: "\f1d1";
+}
+.fa-git-square:before {
+  content: "\f1d2";
+}
+.fa-git:before {
+  content: "\f1d3";
+}
+.fa-y-combinator-square:before,
+.fa-yc-square:before,
+.fa-hacker-news:before {
+  content: "\f1d4";
+}
+.fa-tencent-weibo:before {
+  content: "\f1d5";
+}
+.fa-qq:before {
+  content: "\f1d6";
+}
+.fa-wechat:before,
+.fa-weixin:before {
+  content: "\f1d7";
+}
+.fa-send:before,
+.fa-paper-plane:before {
+  content: "\f1d8";
+}
+.fa-send-o:before,
+.fa-paper-plane-o:before {
+  content: "\f1d9";
+}
+.fa-history:before {
+  content: "\f1da";
+}
+.fa-circle-thin:before {
+  content: "\f1db";
+}
+.fa-header:before {
+  content: "\f1dc";
+}
+.fa-paragraph:before {
+  content: "\f1dd";
+}
+.fa-sliders:before {
+  content: "\f1de";
+}
+.fa-share-alt:before {
+  content: "\f1e0";
+}
+.fa-share-alt-square:before {
+  content: "\f1e1";
+}
+.fa-bomb:before {
+  content: "\f1e2";
+}
+.fa-soccer-ball-o:before,
+.fa-futbol-o:before {
+  content: "\f1e3";
+}
+.fa-tty:before {
+  content: "\f1e4";
+}
+.fa-binoculars:before {
+  content: "\f1e5";
+}
+.fa-plug:before {
+  content: "\f1e6";
+}
+.fa-slideshare:before {
+  content: "\f1e7";
+}
+.fa-twitch:before {
+  content: "\f1e8";
+}
+.fa-yelp:before {
+  content: "\f1e9";
+}
+.fa-newspaper-o:before {
+  content: "\f1ea";
+}
+.fa-wifi:before {
+  content: "\f1eb";
+}
+.fa-calculator:before {
+  content: "\f1ec";
+}
+.fa-paypal:before {
+  content: "\f1ed";
+}
+.fa-google-wallet:before {
+  content: "\f1ee";
+}
+.fa-cc-visa:before {
+  content: "\f1f0";
+}
+.fa-cc-mastercard:before {
+  content: "\f1f1";
+}
+.fa-cc-discover:before {
+  content: "\f1f2";
+}
+.fa-cc-amex:before {
+  content: "\f1f3";
+}
+.fa-cc-paypal:before {
+  content: "\f1f4";
+}
+.fa-cc-stripe:before {
+  content: "\f1f5";
+}
+.fa-bell-slash:before {
+  content: "\f1f6";
+}
+.fa-bell-slash-o:before {
+  content: "\f1f7";
+}
+.fa-trash:before {
+  content: "\f1f8";
+}
+.fa-copyright:before {
+  content: "\f1f9";
+}
+.fa-at:before {
+  content: "\f1fa";
+}
+.fa-eyedropper:before {
+  content: "\f1fb";
+}
+.fa-paint-brush:before {
+  content: "\f1fc";
+}
+.fa-birthday-cake:before {
+  content: "\f1fd";
+}
+.fa-area-chart:before {
+  content: "\f1fe";
+}
+.fa-pie-chart:before {
+  content: "\f200";
+}
+.fa-line-chart:before {
+  content: "\f201";
+}
+.fa-lastfm:before {
+  content: "\f202";
+}
+.fa-lastfm-square:before {
+  content: "\f203";
+}
+.fa-toggle-off:before {
+  content: "\f204";
+}
+.fa-toggle-on:before {
+  content: "\f205";
+}
+.fa-bicycle:before {
+  content: "\f206";
+}
+.fa-bus:before {
+  content: "\f207";
+}
+.fa-ioxhost:before {
+  content: "\f208";
+}
+.fa-angellist:before {
+  content: "\f209";
+}
+.fa-cc:before {
+  content: "\f20a";
+}
+.fa-shekel:before,
+.fa-sheqel:before,
+.fa-ils:before {
+  content: "\f20b";
+}
+.fa-meanpath:before {
+  content: "\f20c";
+}
+.fa-buysellads:before {
+  content: "\f20d";
+}
+.fa-connectdevelop:before {
+  content: "\f20e";
+}
+.fa-dashcube:before {
+  content: "\f210";
+}
+.fa-forumbee:before {
+  content: "\f211";
+}
+.fa-leanpub:before {
+  content: "\f212";
+}
+.fa-sellsy:before {
+  content: "\f213";
+}
+.fa-shirtsinbulk:before {
+  content: "\f214";
+}
+.fa-simplybuilt:before {
+  content: "\f215";
+}
+.fa-skyatlas:before {
+  content: "\f216";
+}
+.fa-cart-plus:before {
+  content: "\f217";
+}
+.fa-cart-arrow-down:before {
+  content: "\f218";
+}
+.fa-diamond:before {
+  content: "\f219";
+}
+.fa-ship:before {
+  content: "\f21a";
+}
+.fa-user-secret:before {
+  content: "\f21b";
+}
+.fa-motorcycle:before {
+  content: "\f21c";
+}
+.fa-street-view:before {
+  content: "\f21d";
+}
+.fa-heartbeat:before {
+  content: "\f21e";
+}
+.fa-venus:before {
+  content: "\f221";
+}
+.fa-mars:before {
+  content: "\f222";
+}
+.fa-mercury:before {
+  content: "\f223";
+}
+.fa-intersex:before,
+.fa-transgender:before {
+  content: "\f224";
+}
+.fa-transgender-alt:before {
+  content: "\f225";
+}
+.fa-venus-double:before {
+  content: "\f226";
+}
+.fa-mars-double:before {
+  content: "\f227";
+}
+.fa-venus-mars:before {
+  content: "\f228";
+}
+.fa-mars-stroke:before {
+  content: "\f229";
+}
+.fa-mars-stroke-v:before {
+  content: "\f22a";
+}
+.fa-mars-stroke-h:before {
+  content: "\f22b";
+}
+.fa-neuter:before {
+  content: "\f22c";
+}
+.fa-genderless:before {
+  content: "\f22d";
+}
+.fa-facebook-official:before {
+  content: "\f230";
+}
+.fa-pinterest-p:before {
+  content: "\f231";
+}
+.fa-whatsapp:before {
+  content: "\f232";
+}
+.fa-server:before {
+  content: "\f233";
+}
+.fa-user-plus:before {
+  content: "\f234";
+}
+.fa-user-times:before {
+  content: "\f235";
+}
+.fa-hotel:before,
+.fa-bed:before {
+  content: "\f236";
+}
+.fa-viacoin:before {
+  content: "\f237";
+}
+.fa-train:before {
+  content: "\f238";
+}
+.fa-subway:before {
+  content: "\f239";
+}
+.fa-medium:before {
+  content: "\f23a";
+}
+.fa-yc:before,
+.fa-y-combinator:before {
+  content: "\f23b";
+}
+.fa-optin-monster:before {
+  content: "\f23c";
+}
+.fa-opencart:before {
+  content: "\f23d";
+}
+.fa-expeditedssl:before {
+  content: "\f23e";
+}
+.fa-battery-4:before,
+.fa-battery-full:before {
+  content: "\f240";
+}
+.fa-battery-3:before,
+.fa-battery-three-quarters:before {
+  content: "\f241";
+}
+.fa-battery-2:before,
+.fa-battery-half:before {
+  content: "\f242";
+}
+.fa-battery-1:before,
+.fa-battery-quarter:before {
+  content: "\f243";
+}
+.fa-battery-0:before,
+.fa-battery-empty:before {
+  content: "\f244";
+}
+.fa-mouse-pointer:before {
+  content: "\f245";
+}
+.fa-i-cursor:before {
+  content: "\f246";
+}
+.fa-object-group:before {
+  content: "\f247";
+}
+.fa-object-ungroup:before {
+  content: "\f248";
+}
+.fa-sticky-note:before {
+  content: "\f249";
+}
+.fa-sticky-note-o:before {
+  content: "\f24a";
+}
+.fa-cc-jcb:before {
+  content: "\f24b";
+}
+.fa-cc-diners-club:before {
+  content: "\f24c";
+}
+.fa-clone:before {
+  content: "\f24d";
+}
+.fa-balance-scale:before {
+  content: "\f24e";
+}
+.fa-hourglass-o:before {
+  content: "\f250";
+}
+.fa-hourglass-1:before,
+.fa-hourglass-start:before {
+  content: "\f251";
+}
+.fa-hourglass-2:before,
+.fa-hourglass-half:before {
+  content: "\f252";
+}
+.fa-hourglass-3:before,
+.fa-hourglass-end:before {
+  content: "\f253";
+}
+.fa-hourglass:before {
+  content: "\f254";
+}
+.fa-hand-grab-o:before,
+.fa-hand-rock-o:before {
+  content: "\f255";
+}
+.fa-hand-stop-o:before,
+.fa-hand-paper-o:before {
+  content: "\f256";
+}
+.fa-hand-scissors-o:before {
+  content: "\f257";
+}
+.fa-hand-lizard-o:before {
+  content: "\f258";
+}
+.fa-hand-spock-o:before {
+  content: "\f259";
+}
+.fa-hand-pointer-o:before {
+  content: "\f25a";
+}
+.fa-hand-peace-o:before {
+  content: "\f25b";
+}
+.fa-trademark:before {
+  content: "\f25c";
+}
+.fa-registered:before {
+  content: "\f25d";
+}
+.fa-creative-commons:before {
+  content: "\f25e";
+}
+.fa-gg:before {
+  content: "\f260";
+}
+.fa-gg-circle:before {
+  content: "\f261";
+}
+.fa-tripadvisor:before {
+  content: "\f262";
+}
+.fa-odnoklassniki:before {
+  content: "\f263";
+}
+.fa-odnoklassniki-square:before {
+  content: "\f264";
+}
+.fa-get-pocket:before {
+  content: "\f265";
+}
+.fa-wikipedia-w:before {
+  content: "\f266";
+}
+.fa-safari:before {
+  content: "\f267";
+}
+.fa-chrome:before {
+  content: "\f268";
+}
+.fa-firefox:before {
+  content: "\f269";
+}
+.fa-opera:before {
+  content: "\f26a";
+}
+.fa-internet-explorer:before {
+  content: "\f26b";
+}
+.fa-tv:before,
+.fa-television:before {
+  content: "\f26c";
+}
+.fa-contao:before {
+  content: "\f26d";
+}
+.fa-500px:before {
+  content: "\f26e";
+}
+.fa-amazon:before {
+  content: "\f270";
+}
+.fa-calendar-plus-o:before {
+  content: "\f271";
+}
+.fa-calendar-minus-o:before {
+  content: "\f272";
+}
+.fa-calendar-times-o:before {
+  content: "\f273";
+}
+.fa-calendar-check-o:before {
+  content: "\f274";
+}
+.fa-industry:before {
+  content: "\f275";
+}
+.fa-map-pin:before {
+  content: "\f276";
+}
+.fa-map-signs:before {
+  content: "\f277";
+}
+.fa-map-o:before {
+  content: "\f278";
+}
+.fa-map:before {
+  content: "\f279";
+}
+.fa-commenting:before {
+  content: "\f27a";
+}
+.fa-commenting-o:before {
+  content: "\f27b";
+}
+.fa-houzz:before {
+  content: "\f27c";
+}
+.fa-vimeo:before {
+  content: "\f27d";
+}
+.fa-black-tie:before {
+  content: "\f27e";
+}
+.fa-fonticons:before {
+  content: "\f280";
+}
+.fa-reddit-alien:before {
+  content: "\f281";
+}
+.fa-edge:before {
+  content: "\f282";
+}
+.fa-credit-card-alt:before {
+  content: "\f283";
+}
+.fa-codiepie:before {
+  content: "\f284";
+}
+.fa-modx:before {
+  content: "\f285";
+}
+.fa-fort-awesome:before {
+  content: "\f286";
+}
+.fa-usb:before {
+  content: "\f287";
+}
+.fa-product-hunt:before {
+  content: "\f288";
+}
+.fa-mixcloud:before {
+  content: "\f289";
+}
+.fa-scribd:before {
+  content: "\f28a";
+}
+.fa-pause-circle:before {
+  content: "\f28b";
+}
+.fa-pause-circle-o:before {
+  content: "\f28c";
+}
+.fa-stop-circle:before {
+  content: "\f28d";
+}
+.fa-stop-circle-o:before {
+  content: "\f28e";
+}
+.fa-shopping-bag:before {
+  content: "\f290";
+}
+.fa-shopping-basket:before {
+  content: "\f291";
+}
+.fa-hashtag:before {
+  content: "\f292";
+}
+.fa-bluetooth:before {
+  content: "\f293";
+}
+.fa-bluetooth-b:before {
+  content: "\f294";
+}
+.fa-percent:before {
+  content: "\f295";
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/css/font-awesome.min.css
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/css/font-awesome.min.css b/src/main/webapp/assets/js/libs/font-awesome/css/font-awesome.min.css
new file mode 100644
index 0000000..d0603cb
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/css/font-awesome.min.css
@@ -0,0 +1,4 @@
+/*!
+ *  Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.5.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.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.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1
 4285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-tr
 ansform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-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);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:abso
 lute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.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-remove:before,.fa-close:before,.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-d
 ownload: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-lef
 t: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-photo:before,.fa-image:before,.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,.fa-bar-chart: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:"\f0
 87"}.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-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.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-navicon:before,.fa-reorder:before,.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-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc: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-t
 achometer: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-dou
 ble-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-mail-reply-all:before,.fa-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:"\f1
 36"}.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:be
 fore,.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:be
 fore{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:befor
 e,.fa-gratipay: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"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mo
 rtar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{conten
 t:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before
 ,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content
 :"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{conte
 nt:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:be
 fore{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:bef
 ore{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254
 "}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-50
 0px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pau
 se-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/fonts/FontAwesome.otf
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/fonts/FontAwesome.otf b/src/main/webapp/assets/js/libs/font-awesome/fonts/FontAwesome.otf
new file mode 100644
index 0000000..3ed7f8b
Binary files /dev/null and b/src/main/webapp/assets/js/libs/font-awesome/fonts/FontAwesome.otf differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.eot
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.eot b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.eot
new file mode 100644
index 0000000..9b6afae
Binary files /dev/null and b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.eot differ


[24/27] brooklyn-ui git commit: use apache brooklyn logo w feather

Posted by he...@apache.org.
use apache brooklyn logo w feather

and add various brooklyn logo files


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/dfc2d21b
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/dfc2d21b
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/dfc2d21b

Branch: refs/heads/master
Commit: dfc2d21b8da4df8524b7d2a0a3c5f6345352b7db
Parents: 2414c14
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Feb 16 23:21:26 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Feb 16 23:27:47 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/css/brooklyn.css            |  11 ++++++-----
 .../assets/img/Apache-Brooklyn-Logo-200px-wide.png | Bin 0 -> 4256 bytes
 .../assets/img/Apache-Brooklyn-Logo-300px-wide.png | Bin 0 -> 6068 bytes
 .../assets/img/Apache-Brooklyn-Logo_highres.png    | Bin 0 -> 42890 bytes
 .../img/apache-brooklyn-feather-atop-720px.png     | Bin 0 -> 72926 bytes
 5 files changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/dfc2d21b/src/main/webapp/assets/css/brooklyn.css
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/css/brooklyn.css b/src/main/webapp/assets/css/brooklyn.css
index ec4aa90..2121837 100644
--- a/src/main/webapp/assets/css/brooklyn.css
+++ b/src/main/webapp/assets/css/brooklyn.css
@@ -29,11 +29,12 @@ textarea {
 
 /* HEADER  */
 .logo {
-    height: 44px !important;
-    width: 195px !important;
-    background: url(../images/brooklyn-logo.png) no-repeat;
-    margin-top: 50px;
-    margin-left: 40px;
+    height: 86px !important;
+    width: 240px !important;
+    margin-top: 16px;
+    background: url(../img/apache-brooklyn-feather-atop-720px.png) no-repeat;
+    background-size: contain;
+    margin-left: 15px;
 }
 
 .navbar-inner {

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/dfc2d21b/src/main/webapp/assets/img/Apache-Brooklyn-Logo-200px-wide.png
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/img/Apache-Brooklyn-Logo-200px-wide.png b/src/main/webapp/assets/img/Apache-Brooklyn-Logo-200px-wide.png
new file mode 100755
index 0000000..f8447a2
Binary files /dev/null and b/src/main/webapp/assets/img/Apache-Brooklyn-Logo-200px-wide.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/dfc2d21b/src/main/webapp/assets/img/Apache-Brooklyn-Logo-300px-wide.png
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/img/Apache-Brooklyn-Logo-300px-wide.png b/src/main/webapp/assets/img/Apache-Brooklyn-Logo-300px-wide.png
new file mode 100755
index 0000000..936c129
Binary files /dev/null and b/src/main/webapp/assets/img/Apache-Brooklyn-Logo-300px-wide.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/dfc2d21b/src/main/webapp/assets/img/Apache-Brooklyn-Logo_highres.png
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/img/Apache-Brooklyn-Logo_highres.png b/src/main/webapp/assets/img/Apache-Brooklyn-Logo_highres.png
new file mode 100755
index 0000000..3fa68b4
Binary files /dev/null and b/src/main/webapp/assets/img/Apache-Brooklyn-Logo_highres.png differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/dfc2d21b/src/main/webapp/assets/img/apache-brooklyn-feather-atop-720px.png
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/img/apache-brooklyn-feather-atop-720px.png b/src/main/webapp/assets/img/apache-brooklyn-feather-atop-720px.png
new file mode 100644
index 0000000..b097aa4
Binary files /dev/null and b/src/main/webapp/assets/img/apache-brooklyn-feather-atop-720px.png differ


[19/27] brooklyn-ui git commit: add font awesome

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.svg
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.svg b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.svg
new file mode 100644
index 0000000..d05688e
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.svg
@@ -0,0 +1,655 @@
+<?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="&#xd8;" horiz-adv-x="1792" />
+<glyph unicode="&#x2000;" horiz-adv-x="768" />
+<glyph unicode="&#x2001;" horiz-adv-x="1537" />
+<glyph unicode="&#x2002;" horiz-adv-x="768" />
+<glyph unicode="&#x2003;" horiz-adv-x="1537" />
+<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="&#x25fc;" 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;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z " />
+<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 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57 q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5 q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
+<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5 t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5 t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
+<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
+<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M1744 128q33 0 42 -18.5t-11 -44.5l-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-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
+<glyph unicode="&#xf035;" d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1 t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41
 .5t-59.5 49t-36 30q-26 21 -26 49 t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
+<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="1280" d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
+<glyph unicode="&#xf054;" horiz-adv-x="1280" d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
+<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="1792" d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
+<glyph unicode="&#xf078;" horiz-adv-x="1792" d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
+<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 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45 t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 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="2048" d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
+<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="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960z" />
+<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="1024" d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
+<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="1792" d="M912 -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 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
+<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 

<TRUNCATED>

[23/27] brooklyn-ui git commit: make span12 (composer) line up with other pages

Posted by he...@apache.org.
make span12 (composer) line up with other pages

and remove debug js logging just introduced


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/2414c144
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/2414c144
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/2414c144

Branch: refs/heads/master
Commit: 2414c1443bd5433e0ff5598ba79604f82cd43f7e
Parents: 500b5fa
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Feb 16 20:51:38 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Feb 16 20:51:38 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/css/brooklyn.css                   | 10 +++++++++-
 .../code-complete/brooklyn-yaml-completion-proposals.js   |  4 +---
 2 files changed, 10 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/2414c144/src/main/webapp/assets/css/brooklyn.css
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/css/brooklyn.css b/src/main/webapp/assets/css/brooklyn.css
index c2ad673..ec4aa90 100644
--- a/src/main/webapp/assets/css/brooklyn.css
+++ b/src/main/webapp/assets/css/brooklyn.css
@@ -136,6 +136,13 @@ textarea {
     margin-top: 10px !important
 }
 
+.row-fluid .span12 {
+    margin-left: 34px !important;
+    margin-right: -26px !important;
+    margin-top: 10px !important;
+    width: 927px !important;
+}
+
 .navbar_top {
     background-color: #f0f0f0 !important;
     -webkit-border-radius: 13px 13px 0 0 !important;
@@ -145,8 +152,9 @@ textarea {
     border-bottom: none;
 }
 
-.navbar_top  h3 {
+.navbar_top h3 {
     line-height: 24px !important;
+    margin-top: 6px;
 }
 
 .navbar_main_wrapper {

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/2414c144/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js b/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
index 032f0d6..3dfecd7 100644
--- a/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
+++ b/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
@@ -27,6 +27,7 @@ define([
     var catalogE = new Catalog(undefined, { name: "catalog/entities" });
     var catalogA = new Catalog(undefined, { name: "catalog/applications" });
     var catalogL = new Catalog(undefined, { name: "locations" });
+    // if browser opened while server is starting this will fail on first completion
     catalogA.fetch();
     catalogE.fetch();
     catalogL.fetch();
@@ -178,7 +179,6 @@ define([
         
         getServiceTypes: function(n) {
             var result = [];
-            console.log(catalogE);
             catalogE.fetch();
             catalogA.fetch();
             result = result.concat(_.map(catalogE.models, function(m) { return m.get('symbolicName'); })); 
@@ -284,7 +284,6 @@ define([
         try {
             parse = JsYamlParser.parse(text);
             if (typeof parse.result == 'string') {
-                console.log("prim");
                 throw "primitive not supported, parse as empty and let completion apply";
             }
         } catch (e) {
@@ -332,7 +331,6 @@ define([
             }
             result = _.compact(_.map(result, function(proposal) {
                 var proposalObj;
-                console.log("considering",proposal,"wrt",wordSoFar,"/",lineSoFar);
                 if (typeof proposal === 'object') {
                     proposalObj = proposal;
                     proposal = proposalObj.text;


[21/27] brooklyn-ui git commit: use icons for example and docs link

Posted by he...@apache.org.
use icons for example and docs link


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/d4d88aab
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/d4d88aab
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/d4d88aab

Branch: refs/heads/master
Commit: d4d88aab92794cf4b2e16cc429ae4dfaac518a94
Parents: 631292f
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Feb 16 16:57:57 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Feb 16 16:57:57 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/js/view/editor.js    | 4 ++++
 src/main/webapp/assets/tpl/editor/page.html | 6 +++++-
 2 files changed, 9 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d4d88aab/src/main/webapp/assets/js/view/editor.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/editor.js b/src/main/webapp/assets/js/view/editor.js
index 19e4378..07f68c0 100644
--- a/src/main/webapp/assets/js/view/editor.js
+++ b/src/main/webapp/assets/js/view/editor.js
@@ -63,6 +63,7 @@ define([
             'click #button-switch-app':'switchModeApp',
             'click #button-switch-catalog':'switchModeCatalog',
             'click #button-example':'populateExampleBlueprint',
+            'click #button-docs':'openDocumentation',
         },
         editorTemplate:_.template(EditorHtml),
 
@@ -286,6 +287,9 @@ define([
         populateExampleBlueprint: function() {
             this.editor.setValue(this.mode==MODE_CATALOG ? _DEFAULT_CATALOG : _DEFAULT_BLUEPRINT);
         },
+        openDocumentation: function() {
+            window.open(this.mode==MODE_CATALOG ? "https://brooklyn.apache.org/v/latest/ops/catalog/" : "https://brooklyn.apache.org/v/latest/yaml/yaml-reference.html", "_blank");
+        },
         
         onSubmissionComplete: function(succeeded, data, type) {
             var that = this;

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d4d88aab/src/main/webapp/assets/tpl/editor/page.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/editor/page.html b/src/main/webapp/assets/tpl/editor/page.html
index 67bb09c..05b62db 100644
--- a/src/main/webapp/assets/tpl/editor/page.html
+++ b/src/main/webapp/assets/tpl/editor/page.html
@@ -23,7 +23,11 @@ under the License.
                 <h3 style="margin-top: 6px;">Blueprint Composer</h3>
                 <div class="apps-tree-toolbar btn-toolbar" style="margin-top: -24px !important;">
                     <span class="btn-group">
-                    <button id="button-example" class="btn btn-sm" style="margin-right: 12px;">Insert Example</button>
+                    <button id="button-example" class="btn btn-sm fa fa-file-text-o" title="Insert Example"></button>
+                    </span>
+                    
+                    <span class="btn-group">
+                    <button id="button-docs" class="btn btn-sm fa fa-book" title="Open Brooklyn Website Documentation"></button>
                     </span>
                     
                     <!-- no need for this


[10/27] brooklyn-ui git commit: call buttons "Open in Composer" and "Deploy" rather than "Preview" / "Finish"

Posted by he...@apache.org.
call buttons "Open in Composer" and "Deploy" rather than "Preview" / "Finish"

and the "Open in Composer" button is highlighted if you pick a template


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/9d3d9bb3
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/9d3d9bb3
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/9d3d9bb3

Branch: refs/heads/master
Commit: 9d3d9bb3f8346f62028fdad1df43ec60d94e73d8
Parents: 2d75ed5
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 01:50:58 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 .../assets/js/view/application-add-wizard.js    | 91 +++++++++++---------
 .../assets/tpl/app-add-wizard/modal-wizard.html |  4 +-
 2 files changed, 50 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/9d3d9bb3/src/main/webapp/assets/js/view/application-add-wizard.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/application-add-wizard.js b/src/main/webapp/assets/js/view/application-add-wizard.js
index ffdee6d..62d4db2 100644
--- a/src/main/webapp/assets/js/view/application-add-wizard.js
+++ b/src/main/webapp/assets/js/view/application-add-wizard.js
@@ -166,12 +166,39 @@ define([
             
             setVisibility(this.$("#prev_step"), (this.currentStep > 0))
 
+            this.isTemplate = false;
+            {
+                var yaml = (this.currentView && this.currentView.selectedTemplate && this.currentView.selectedTemplate.yaml);
+                if (yaml) {
+                    try {
+                        yaml = JsYaml.safeLoad(yaml);
+                        hasLocation = yaml.location || yaml.locations;
+                        if (!hasLocation) {
+                          // look for locations defined in locations
+                          svcs = yaml.services;
+                          if (svcs) {
+                            for (svcI in svcs) {
+                              if (svcs[svcI].location || svcs[svcI].locations) {
+                                hasLocation = true;
+                                break;
+                              }
+                            }
+                          }
+                        }
+                        this.isTemplate = (hasLocation ? true : false);
+                    } catch (e) {
+                        log("Warning: could not parse yaml template of selected item")
+                        log(yaml);
+                    }
+                }
+            }
+            
             // next shown for first step, but not for yaml
-            var nextVisible = (this.currentStep < 1) && (this.model.mode != "yaml")
+            var nextVisible = (this.currentStep < 1) && (this.model.mode != "yaml") && (!this.isTemplate);
             setVisibility(this.$("#next_step"), nextVisible)
             
-            // previous shown for step 2 (but again, not yaml)
-            var previewVisible = (this.currentStep == 1) && (this.model.mode != "yaml")
+            // preview (aka "Open in Composer") shown for step 2 or for template (but again, not yaml)
+            var previewVisible = (((this.currentStep < 1) && this.isTemplate) || (this.currentStep == 1)) && (this.model.mode != "yaml")
             setVisibility(this.$("#preview_step"), previewVisible)
             
             // now set next/preview enablement
@@ -266,38 +293,9 @@ define([
         nextStep:function () {
             if (this.currentStep == 0) {
                 if (this.currentView.validate()) {
-                    this.isTemplate = false;
-                    var yaml = (this.currentView && this.currentView.selectedTemplate && this.currentView.selectedTemplate.yaml);
-                    if (yaml) {
-                        try {
-                            yaml = JsYaml.safeLoad(yaml);
-                            hasLocation = yaml.location || yaml.locations;
-                            if (!hasLocation) {
-                              // look for locations defined in locations
-                              svcs = yaml.services;
-                              if (svcs) {
-                                for (svcI in svcs) {
-                                  if (svcs[svcI].location || svcs[svcI].locations) {
-                                    hasLocation = true;
-                                    break;
-                                  }
-                                }
-                              }
-                            }
-                            this.isTemplate = (hasLocation ? true : false);
-                        } catch (e) {
-                            log("Warning: could not parse yaml template")
-                            log(yaml);
-                        }
-                    }
-                    if (this.isTemplate) {
-                        // it's a yaml catalog *template* (because it includes a location); go to composer
-                        this.redirectToEditorTabToDeployId(this.currentView.selectedTemplate.id);
-                    } else {
-                        // it's a java catalog template or yaml template without a location, go to wizard
-                        this.currentStep += 1;
-                        this.renderCurrentStep();
-                    }
+                    // next not visible if it's a template, so go to create (configure) step
+                    this.currentStep += 1;
+                    this.renderCurrentStep();
                 } else {
                     // the call to validate will have done the showFailure
                 }
@@ -307,16 +305,21 @@ define([
         },
         previewStep:function () {
             if (this.currentView.validate()) {
-                var yaml;
-                if (this.model.mode == "yaml") {
-                    yaml = this.model.yaml;
+                if (this.isTemplate) {
+                    // it's a yaml catalog *template* (because it includes a location); go to composer
+                    this.redirectToEditorTabToDeployId(this.currentView.selectedTemplate.id);
                 } else {
-                    // Drop any "None" locations.
-                    this.model.spec.pruneLocations();
-                    yaml = JsYaml.safeDump(oldSpecToCamp(this.model.spec.toJSON()));
+                    var yaml;
+                    if (this.model.mode == "yaml") {
+                        yaml = this.model.yaml;
+                    } else {
+                        // Drop any "None" locations.
+                        this.model.spec.pruneLocations();
+                        yaml = JsYaml.safeDump(oldSpecToCamp(this.model.spec.toJSON()));
+                    }
+    
+                    this.redirectToEditorTabToDeployYaml(yaml);
                 }
-
-                this.redirectToEditorTabToDeployYaml(yaml);
             } else {
                 // call to validate should showFailure
             }
@@ -417,6 +420,7 @@ define([
             this.delegateEvents();
             return this;
         },
+        // TODO tabs no longer relevant
         onTabChange: function(e) {
             var tabText = $(e.target).text();
             if (tabText=="Catalog") {
@@ -426,6 +430,7 @@ define([
             }
 
             if (tabText=="YAML") {
+                // TODO this mode no longer used
                 this.model.mode = "yaml";
             } else if (tabText=="Template") {
                 this.model.mode = "template";

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/9d3d9bb3/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html b/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html
index 183a4ab..427e100 100644
--- a/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html
+++ b/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html
@@ -30,6 +30,6 @@ under the License.
 <div class="modal-footer">
     <button id="prev_step" type="button button-previous" class="btn btn-mini btn-info">Back</button>
     <button id="next_step" type="button button-next" class="btn btn-mini btn-info">Next</button>
-    <button id="preview_step" type="button button-preview" class="btn btn-mini btn-info">Preview</button>
-    <button id="finish_step" type="button button-finish" class="btn btn-mini btn-info">Finish</button>
+    <button id="preview_step" type="button button-preview" class="btn btn-mini btn-info">Open in Composer</button>
+    <button id="finish_step" type="button button-finish" class="btn btn-mini btn-info">Deploy</button>
 </div>


[06/27] brooklyn-ui git commit: use location identifier spec/name, not a random id, in app-add-wizard

Posted by he...@apache.org.
use location identifier spec/name, not a random id, in app-add-wizard


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/f49de1ca
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/f49de1ca
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/f49de1ca

Branch: refs/heads/master
Commit: f49de1ca782ea158f511d80ba450e5e990e578da
Parents: 9c6c06c
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 02:57:32 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/js/view/application-add-wizard.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/f49de1ca/src/main/webapp/assets/js/view/application-add-wizard.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/application-add-wizard.js b/src/main/webapp/assets/js/view/application-add-wizard.js
index 1174c5e..1436eea 100644
--- a/src/main/webapp/assets/js/view/application-add-wizard.js
+++ b/src/main/webapp/assets/js/view/application-add-wizard.js
@@ -595,7 +595,7 @@ define([
             var $locationOptions = container.find('.select-location');
             var templated = this.locations.map(function(aLocation) {
                 return optionTemplate({
-                    id: aLocation.id || "",
+                    id: aLocation.getIdentifierName() || aLocation.id || "",
                     name: aLocation.getPrettyName()
                 });
             });
@@ -647,7 +647,7 @@ define([
         },
         addLocation:function () {
             if (this.locations.models.length>0) {
-                this.model.spec.addLocation(this.locations.models[0].get("id"))
+                this.model.spec.addLocation(this.locations.models[0].getIdentifierName())
             } else {
                 // i.e. No location
                 this.model.spec.addLocation(undefined);
@@ -702,7 +702,7 @@ define([
             var loc_id = $(event.currentTarget).val(),
                 isNoneLocation = loc_id === NO_LOCATION_INDICATOR;
             var locationValid = isNoneLocation || this.locations.find(function (candidate) {
-                return candidate.get("id")==loc_id;
+                return candidate.getIdentifierName()==loc_id;
             });
             if (!locationValid) {
                 log("invalid location "+loc_id);


[17/27] brooklyn-ui git commit: add font awesome

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_icons.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_icons.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_icons.scss
new file mode 100644
index 0000000..6f93759
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_icons.scss
@@ -0,0 +1,697 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+   readers do not read off random characters that represent icons */
+
+.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; }
+.#{$fa-css-prefix}-music:before { content: $fa-var-music; }
+.#{$fa-css-prefix}-search:before { content: $fa-var-search; }
+.#{$fa-css-prefix}-envelope-o:before { content: $fa-var-envelope-o; }
+.#{$fa-css-prefix}-heart:before { content: $fa-var-heart; }
+.#{$fa-css-prefix}-star:before { content: $fa-var-star; }
+.#{$fa-css-prefix}-star-o:before { content: $fa-var-star-o; }
+.#{$fa-css-prefix}-user:before { content: $fa-var-user; }
+.#{$fa-css-prefix}-film:before { content: $fa-var-film; }
+.#{$fa-css-prefix}-th-large:before { content: $fa-var-th-large; }
+.#{$fa-css-prefix}-th:before { content: $fa-var-th; }
+.#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; }
+.#{$fa-css-prefix}-check:before { content: $fa-var-check; }
+.#{$fa-css-prefix}-remove:before,
+.#{$fa-css-prefix}-close:before,
+.#{$fa-css-prefix}-times:before { content: $fa-var-times; }
+.#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; }
+.#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; }
+.#{$fa-css-prefix}-power-off:before { content: $fa-var-power-off; }
+.#{$fa-css-prefix}-signal:before { content: $fa-var-signal; }
+.#{$fa-css-prefix}-gear:before,
+.#{$fa-css-prefix}-cog:before { content: $fa-var-cog; }
+.#{$fa-css-prefix}-trash-o:before { content: $fa-var-trash-o; }
+.#{$fa-css-prefix}-home:before { content: $fa-var-home; }
+.#{$fa-css-prefix}-file-o:before { content: $fa-var-file-o; }
+.#{$fa-css-prefix}-clock-o:before { content: $fa-var-clock-o; }
+.#{$fa-css-prefix}-road:before { content: $fa-var-road; }
+.#{$fa-css-prefix}-download:before { content: $fa-var-download; }
+.#{$fa-css-prefix}-arrow-circle-o-down:before { content: $fa-var-arrow-circle-o-down; }
+.#{$fa-css-prefix}-arrow-circle-o-up:before { content: $fa-var-arrow-circle-o-up; }
+.#{$fa-css-prefix}-inbox:before { content: $fa-var-inbox; }
+.#{$fa-css-prefix}-play-circle-o:before { content: $fa-var-play-circle-o; }
+.#{$fa-css-prefix}-rotate-right:before,
+.#{$fa-css-prefix}-repeat:before { content: $fa-var-repeat; }
+.#{$fa-css-prefix}-refresh:before { content: $fa-var-refresh; }
+.#{$fa-css-prefix}-list-alt:before { content: $fa-var-list-alt; }
+.#{$fa-css-prefix}-lock:before { content: $fa-var-lock; }
+.#{$fa-css-prefix}-flag:before { content: $fa-var-flag; }
+.#{$fa-css-prefix}-headphones:before { content: $fa-var-headphones; }
+.#{$fa-css-prefix}-volume-off:before { content: $fa-var-volume-off; }
+.#{$fa-css-prefix}-volume-down:before { content: $fa-var-volume-down; }
+.#{$fa-css-prefix}-volume-up:before { content: $fa-var-volume-up; }
+.#{$fa-css-prefix}-qrcode:before { content: $fa-var-qrcode; }
+.#{$fa-css-prefix}-barcode:before { content: $fa-var-barcode; }
+.#{$fa-css-prefix}-tag:before { content: $fa-var-tag; }
+.#{$fa-css-prefix}-tags:before { content: $fa-var-tags; }
+.#{$fa-css-prefix}-book:before { content: $fa-var-book; }
+.#{$fa-css-prefix}-bookmark:before { content: $fa-var-bookmark; }
+.#{$fa-css-prefix}-print:before { content: $fa-var-print; }
+.#{$fa-css-prefix}-camera:before { content: $fa-var-camera; }
+.#{$fa-css-prefix}-font:before { content: $fa-var-font; }
+.#{$fa-css-prefix}-bold:before { content: $fa-var-bold; }
+.#{$fa-css-prefix}-italic:before { content: $fa-var-italic; }
+.#{$fa-css-prefix}-text-height:before { content: $fa-var-text-height; }
+.#{$fa-css-prefix}-text-width:before { content: $fa-var-text-width; }
+.#{$fa-css-prefix}-align-left:before { content: $fa-var-align-left; }
+.#{$fa-css-prefix}-align-center:before { content: $fa-var-align-center; }
+.#{$fa-css-prefix}-align-right:before { content: $fa-var-align-right; }
+.#{$fa-css-prefix}-align-justify:before { content: $fa-var-align-justify; }
+.#{$fa-css-prefix}-list:before { content: $fa-var-list; }
+.#{$fa-css-prefix}-dedent:before,
+.#{$fa-css-prefix}-outdent:before { content: $fa-var-outdent; }
+.#{$fa-css-prefix}-indent:before { content: $fa-var-indent; }
+.#{$fa-css-prefix}-video-camera:before { content: $fa-var-video-camera; }
+.#{$fa-css-prefix}-photo:before,
+.#{$fa-css-prefix}-image:before,
+.#{$fa-css-prefix}-picture-o:before { content: $fa-var-picture-o; }
+.#{$fa-css-prefix}-pencil:before { content: $fa-var-pencil; }
+.#{$fa-css-prefix}-map-marker:before { content: $fa-var-map-marker; }
+.#{$fa-css-prefix}-adjust:before { content: $fa-var-adjust; }
+.#{$fa-css-prefix}-tint:before { content: $fa-var-tint; }
+.#{$fa-css-prefix}-edit:before,
+.#{$fa-css-prefix}-pencil-square-o:before { content: $fa-var-pencil-square-o; }
+.#{$fa-css-prefix}-share-square-o:before { content: $fa-var-share-square-o; }
+.#{$fa-css-prefix}-check-square-o:before { content: $fa-var-check-square-o; }
+.#{$fa-css-prefix}-arrows:before { content: $fa-var-arrows; }
+.#{$fa-css-prefix}-step-backward:before { content: $fa-var-step-backward; }
+.#{$fa-css-prefix}-fast-backward:before { content: $fa-var-fast-backward; }
+.#{$fa-css-prefix}-backward:before { content: $fa-var-backward; }
+.#{$fa-css-prefix}-play:before { content: $fa-var-play; }
+.#{$fa-css-prefix}-pause:before { content: $fa-var-pause; }
+.#{$fa-css-prefix}-stop:before { content: $fa-var-stop; }
+.#{$fa-css-prefix}-forward:before { content: $fa-var-forward; }
+.#{$fa-css-prefix}-fast-forward:before { content: $fa-var-fast-forward; }
+.#{$fa-css-prefix}-step-forward:before { content: $fa-var-step-forward; }
+.#{$fa-css-prefix}-eject:before { content: $fa-var-eject; }
+.#{$fa-css-prefix}-chevron-left:before { content: $fa-var-chevron-left; }
+.#{$fa-css-prefix}-chevron-right:before { content: $fa-var-chevron-right; }
+.#{$fa-css-prefix}-plus-circle:before { content: $fa-var-plus-circle; }
+.#{$fa-css-prefix}-minus-circle:before { content: $fa-var-minus-circle; }
+.#{$fa-css-prefix}-times-circle:before { content: $fa-var-times-circle; }
+.#{$fa-css-prefix}-check-circle:before { content: $fa-var-check-circle; }
+.#{$fa-css-prefix}-question-circle:before { content: $fa-var-question-circle; }
+.#{$fa-css-prefix}-info-circle:before { content: $fa-var-info-circle; }
+.#{$fa-css-prefix}-crosshairs:before { content: $fa-var-crosshairs; }
+.#{$fa-css-prefix}-times-circle-o:before { content: $fa-var-times-circle-o; }
+.#{$fa-css-prefix}-check-circle-o:before { content: $fa-var-check-circle-o; }
+.#{$fa-css-prefix}-ban:before { content: $fa-var-ban; }
+.#{$fa-css-prefix}-arrow-left:before { content: $fa-var-arrow-left; }
+.#{$fa-css-prefix}-arrow-right:before { content: $fa-var-arrow-right; }
+.#{$fa-css-prefix}-arrow-up:before { content: $fa-var-arrow-up; }
+.#{$fa-css-prefix}-arrow-down:before { content: $fa-var-arrow-down; }
+.#{$fa-css-prefix}-mail-forward:before,
+.#{$fa-css-prefix}-share:before { content: $fa-var-share; }
+.#{$fa-css-prefix}-expand:before { content: $fa-var-expand; }
+.#{$fa-css-prefix}-compress:before { content: $fa-var-compress; }
+.#{$fa-css-prefix}-plus:before { content: $fa-var-plus; }
+.#{$fa-css-prefix}-minus:before { content: $fa-var-minus; }
+.#{$fa-css-prefix}-asterisk:before { content: $fa-var-asterisk; }
+.#{$fa-css-prefix}-exclamation-circle:before { content: $fa-var-exclamation-circle; }
+.#{$fa-css-prefix}-gift:before { content: $fa-var-gift; }
+.#{$fa-css-prefix}-leaf:before { content: $fa-var-leaf; }
+.#{$fa-css-prefix}-fire:before { content: $fa-var-fire; }
+.#{$fa-css-prefix}-eye:before { content: $fa-var-eye; }
+.#{$fa-css-prefix}-eye-slash:before { content: $fa-var-eye-slash; }
+.#{$fa-css-prefix}-warning:before,
+.#{$fa-css-prefix}-exclamation-triangle:before { content: $fa-var-exclamation-triangle; }
+.#{$fa-css-prefix}-plane:before { content: $fa-var-plane; }
+.#{$fa-css-prefix}-calendar:before { content: $fa-var-calendar; }
+.#{$fa-css-prefix}-random:before { content: $fa-var-random; }
+.#{$fa-css-prefix}-comment:before { content: $fa-var-comment; }
+.#{$fa-css-prefix}-magnet:before { content: $fa-var-magnet; }
+.#{$fa-css-prefix}-chevron-up:before { content: $fa-var-chevron-up; }
+.#{$fa-css-prefix}-chevron-down:before { content: $fa-var-chevron-down; }
+.#{$fa-css-prefix}-retweet:before { content: $fa-var-retweet; }
+.#{$fa-css-prefix}-shopping-cart:before { content: $fa-var-shopping-cart; }
+.#{$fa-css-prefix}-folder:before { content: $fa-var-folder; }
+.#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; }
+.#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; }
+.#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; }
+.#{$fa-css-prefix}-bar-chart-o:before,
+.#{$fa-css-prefix}-bar-chart:before { content: $fa-var-bar-chart; }
+.#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; }
+.#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; }
+.#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; }
+.#{$fa-css-prefix}-key:before { content: $fa-var-key; }
+.#{$fa-css-prefix}-gears:before,
+.#{$fa-css-prefix}-cogs:before { content: $fa-var-cogs; }
+.#{$fa-css-prefix}-comments:before { content: $fa-var-comments; }
+.#{$fa-css-prefix}-thumbs-o-up:before { content: $fa-var-thumbs-o-up; }
+.#{$fa-css-prefix}-thumbs-o-down:before { content: $fa-var-thumbs-o-down; }
+.#{$fa-css-prefix}-star-half:before { content: $fa-var-star-half; }
+.#{$fa-css-prefix}-heart-o:before { content: $fa-var-heart-o; }
+.#{$fa-css-prefix}-sign-out:before { content: $fa-var-sign-out; }
+.#{$fa-css-prefix}-linkedin-square:before { content: $fa-var-linkedin-square; }
+.#{$fa-css-prefix}-thumb-tack:before { content: $fa-var-thumb-tack; }
+.#{$fa-css-prefix}-external-link:before { content: $fa-var-external-link; }
+.#{$fa-css-prefix}-sign-in:before { content: $fa-var-sign-in; }
+.#{$fa-css-prefix}-trophy:before { content: $fa-var-trophy; }
+.#{$fa-css-prefix}-github-square:before { content: $fa-var-github-square; }
+.#{$fa-css-prefix}-upload:before { content: $fa-var-upload; }
+.#{$fa-css-prefix}-lemon-o:before { content: $fa-var-lemon-o; }
+.#{$fa-css-prefix}-phone:before { content: $fa-var-phone; }
+.#{$fa-css-prefix}-square-o:before { content: $fa-var-square-o; }
+.#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; }
+.#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; }
+.#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; }
+.#{$fa-css-prefix}-facebook-f:before,
+.#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; }
+.#{$fa-css-prefix}-github:before { content: $fa-var-github; }
+.#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; }
+.#{$fa-css-prefix}-credit-card:before { content: $fa-var-credit-card; }
+.#{$fa-css-prefix}-feed:before,
+.#{$fa-css-prefix}-rss:before { content: $fa-var-rss; }
+.#{$fa-css-prefix}-hdd-o:before { content: $fa-var-hdd-o; }
+.#{$fa-css-prefix}-bullhorn:before { content: $fa-var-bullhorn; }
+.#{$fa-css-prefix}-bell:before { content: $fa-var-bell; }
+.#{$fa-css-prefix}-certificate:before { content: $fa-var-certificate; }
+.#{$fa-css-prefix}-hand-o-right:before { content: $fa-var-hand-o-right; }
+.#{$fa-css-prefix}-hand-o-left:before { content: $fa-var-hand-o-left; }
+.#{$fa-css-prefix}-hand-o-up:before { content: $fa-var-hand-o-up; }
+.#{$fa-css-prefix}-hand-o-down:before { content: $fa-var-hand-o-down; }
+.#{$fa-css-prefix}-arrow-circle-left:before { content: $fa-var-arrow-circle-left; }
+.#{$fa-css-prefix}-arrow-circle-right:before { content: $fa-var-arrow-circle-right; }
+.#{$fa-css-prefix}-arrow-circle-up:before { content: $fa-var-arrow-circle-up; }
+.#{$fa-css-prefix}-arrow-circle-down:before { content: $fa-var-arrow-circle-down; }
+.#{$fa-css-prefix}-globe:before { content: $fa-var-globe; }
+.#{$fa-css-prefix}-wrench:before { content: $fa-var-wrench; }
+.#{$fa-css-prefix}-tasks:before { content: $fa-var-tasks; }
+.#{$fa-css-prefix}-filter:before { content: $fa-var-filter; }
+.#{$fa-css-prefix}-briefcase:before { content: $fa-var-briefcase; }
+.#{$fa-css-prefix}-arrows-alt:before { content: $fa-var-arrows-alt; }
+.#{$fa-css-prefix}-group:before,
+.#{$fa-css-prefix}-users:before { content: $fa-var-users; }
+.#{$fa-css-prefix}-chain:before,
+.#{$fa-css-prefix}-link:before { content: $fa-var-link; }
+.#{$fa-css-prefix}-cloud:before { content: $fa-var-cloud; }
+.#{$fa-css-prefix}-flask:before { content: $fa-var-flask; }
+.#{$fa-css-prefix}-cut:before,
+.#{$fa-css-prefix}-scissors:before { content: $fa-var-scissors; }
+.#{$fa-css-prefix}-copy:before,
+.#{$fa-css-prefix}-files-o:before { content: $fa-var-files-o; }
+.#{$fa-css-prefix}-paperclip:before { content: $fa-var-paperclip; }
+.#{$fa-css-prefix}-save:before,
+.#{$fa-css-prefix}-floppy-o:before { content: $fa-var-floppy-o; }
+.#{$fa-css-prefix}-square:before { content: $fa-var-square; }
+.#{$fa-css-prefix}-navicon:before,
+.#{$fa-css-prefix}-reorder:before,
+.#{$fa-css-prefix}-bars:before { content: $fa-var-bars; }
+.#{$fa-css-prefix}-list-ul:before { content: $fa-var-list-ul; }
+.#{$fa-css-prefix}-list-ol:before { content: $fa-var-list-ol; }
+.#{$fa-css-prefix}-strikethrough:before { content: $fa-var-strikethrough; }
+.#{$fa-css-prefix}-underline:before { content: $fa-var-underline; }
+.#{$fa-css-prefix}-table:before { content: $fa-var-table; }
+.#{$fa-css-prefix}-magic:before { content: $fa-var-magic; }
+.#{$fa-css-prefix}-truck:before { content: $fa-var-truck; }
+.#{$fa-css-prefix}-pinterest:before { content: $fa-var-pinterest; }
+.#{$fa-css-prefix}-pinterest-square:before { content: $fa-var-pinterest-square; }
+.#{$fa-css-prefix}-google-plus-square:before { content: $fa-var-google-plus-square; }
+.#{$fa-css-prefix}-google-plus:before { content: $fa-var-google-plus; }
+.#{$fa-css-prefix}-money:before { content: $fa-var-money; }
+.#{$fa-css-prefix}-caret-down:before { content: $fa-var-caret-down; }
+.#{$fa-css-prefix}-caret-up:before { content: $fa-var-caret-up; }
+.#{$fa-css-prefix}-caret-left:before { content: $fa-var-caret-left; }
+.#{$fa-css-prefix}-caret-right:before { content: $fa-var-caret-right; }
+.#{$fa-css-prefix}-columns:before { content: $fa-var-columns; }
+.#{$fa-css-prefix}-unsorted:before,
+.#{$fa-css-prefix}-sort:before { content: $fa-var-sort; }
+.#{$fa-css-prefix}-sort-down:before,
+.#{$fa-css-prefix}-sort-desc:before { content: $fa-var-sort-desc; }
+.#{$fa-css-prefix}-sort-up:before,
+.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; }
+.#{$fa-css-prefix}-envelope:before { content: $fa-var-envelope; }
+.#{$fa-css-prefix}-linkedin:before { content: $fa-var-linkedin; }
+.#{$fa-css-prefix}-rotate-left:before,
+.#{$fa-css-prefix}-undo:before { content: $fa-var-undo; }
+.#{$fa-css-prefix}-legal:before,
+.#{$fa-css-prefix}-gavel:before { content: $fa-var-gavel; }
+.#{$fa-css-prefix}-dashboard:before,
+.#{$fa-css-prefix}-tachometer:before { content: $fa-var-tachometer; }
+.#{$fa-css-prefix}-comment-o:before { content: $fa-var-comment-o; }
+.#{$fa-css-prefix}-comments-o:before { content: $fa-var-comments-o; }
+.#{$fa-css-prefix}-flash:before,
+.#{$fa-css-prefix}-bolt:before { content: $fa-var-bolt; }
+.#{$fa-css-prefix}-sitemap:before { content: $fa-var-sitemap; }
+.#{$fa-css-prefix}-umbrella:before { content: $fa-var-umbrella; }
+.#{$fa-css-prefix}-paste:before,
+.#{$fa-css-prefix}-clipboard:before { content: $fa-var-clipboard; }
+.#{$fa-css-prefix}-lightbulb-o:before { content: $fa-var-lightbulb-o; }
+.#{$fa-css-prefix}-exchange:before { content: $fa-var-exchange; }
+.#{$fa-css-prefix}-cloud-download:before { content: $fa-var-cloud-download; }
+.#{$fa-css-prefix}-cloud-upload:before { content: $fa-var-cloud-upload; }
+.#{$fa-css-prefix}-user-md:before { content: $fa-var-user-md; }
+.#{$fa-css-prefix}-stethoscope:before { content: $fa-var-stethoscope; }
+.#{$fa-css-prefix}-suitcase:before { content: $fa-var-suitcase; }
+.#{$fa-css-prefix}-bell-o:before { content: $fa-var-bell-o; }
+.#{$fa-css-prefix}-coffee:before { content: $fa-var-coffee; }
+.#{$fa-css-prefix}-cutlery:before { content: $fa-var-cutlery; }
+.#{$fa-css-prefix}-file-text-o:before { content: $fa-var-file-text-o; }
+.#{$fa-css-prefix}-building-o:before { content: $fa-var-building-o; }
+.#{$fa-css-prefix}-hospital-o:before { content: $fa-var-hospital-o; }
+.#{$fa-css-prefix}-ambulance:before { content: $fa-var-ambulance; }
+.#{$fa-css-prefix}-medkit:before { content: $fa-var-medkit; }
+.#{$fa-css-prefix}-fighter-jet:before { content: $fa-var-fighter-jet; }
+.#{$fa-css-prefix}-beer:before { content: $fa-var-beer; }
+.#{$fa-css-prefix}-h-square:before { content: $fa-var-h-square; }
+.#{$fa-css-prefix}-plus-square:before { content: $fa-var-plus-square; }
+.#{$fa-css-prefix}-angle-double-left:before { content: $fa-var-angle-double-left; }
+.#{$fa-css-prefix}-angle-double-right:before { content: $fa-var-angle-double-right; }
+.#{$fa-css-prefix}-angle-double-up:before { content: $fa-var-angle-double-up; }
+.#{$fa-css-prefix}-angle-double-down:before { content: $fa-var-angle-double-down; }
+.#{$fa-css-prefix}-angle-left:before { content: $fa-var-angle-left; }
+.#{$fa-css-prefix}-angle-right:before { content: $fa-var-angle-right; }
+.#{$fa-css-prefix}-angle-up:before { content: $fa-var-angle-up; }
+.#{$fa-css-prefix}-angle-down:before { content: $fa-var-angle-down; }
+.#{$fa-css-prefix}-desktop:before { content: $fa-var-desktop; }
+.#{$fa-css-prefix}-laptop:before { content: $fa-var-laptop; }
+.#{$fa-css-prefix}-tablet:before { content: $fa-var-tablet; }
+.#{$fa-css-prefix}-mobile-phone:before,
+.#{$fa-css-prefix}-mobile:before { content: $fa-var-mobile; }
+.#{$fa-css-prefix}-circle-o:before { content: $fa-var-circle-o; }
+.#{$fa-css-prefix}-quote-left:before { content: $fa-var-quote-left; }
+.#{$fa-css-prefix}-quote-right:before { content: $fa-var-quote-right; }
+.#{$fa-css-prefix}-spinner:before { content: $fa-var-spinner; }
+.#{$fa-css-prefix}-circle:before { content: $fa-var-circle; }
+.#{$fa-css-prefix}-mail-reply:before,
+.#{$fa-css-prefix}-reply:before { content: $fa-var-reply; }
+.#{$fa-css-prefix}-github-alt:before { content: $fa-var-github-alt; }
+.#{$fa-css-prefix}-folder-o:before { content: $fa-var-folder-o; }
+.#{$fa-css-prefix}-folder-open-o:before { content: $fa-var-folder-open-o; }
+.#{$fa-css-prefix}-smile-o:before { content: $fa-var-smile-o; }
+.#{$fa-css-prefix}-frown-o:before { content: $fa-var-frown-o; }
+.#{$fa-css-prefix}-meh-o:before { content: $fa-var-meh-o; }
+.#{$fa-css-prefix}-gamepad:before { content: $fa-var-gamepad; }
+.#{$fa-css-prefix}-keyboard-o:before { content: $fa-var-keyboard-o; }
+.#{$fa-css-prefix}-flag-o:before { content: $fa-var-flag-o; }
+.#{$fa-css-prefix}-flag-checkered:before { content: $fa-var-flag-checkered; }
+.#{$fa-css-prefix}-terminal:before { content: $fa-var-terminal; }
+.#{$fa-css-prefix}-code:before { content: $fa-var-code; }
+.#{$fa-css-prefix}-mail-reply-all:before,
+.#{$fa-css-prefix}-reply-all:before { content: $fa-var-reply-all; }
+.#{$fa-css-prefix}-star-half-empty:before,
+.#{$fa-css-prefix}-star-half-full:before,
+.#{$fa-css-prefix}-star-half-o:before { content: $fa-var-star-half-o; }
+.#{$fa-css-prefix}-location-arrow:before { content: $fa-var-location-arrow; }
+.#{$fa-css-prefix}-crop:before { content: $fa-var-crop; }
+.#{$fa-css-prefix}-code-fork:before { content: $fa-var-code-fork; }
+.#{$fa-css-prefix}-unlink:before,
+.#{$fa-css-prefix}-chain-broken:before { content: $fa-var-chain-broken; }
+.#{$fa-css-prefix}-question:before { content: $fa-var-question; }
+.#{$fa-css-prefix}-info:before { content: $fa-var-info; }
+.#{$fa-css-prefix}-exclamation:before { content: $fa-var-exclamation; }
+.#{$fa-css-prefix}-superscript:before { content: $fa-var-superscript; }
+.#{$fa-css-prefix}-subscript:before { content: $fa-var-subscript; }
+.#{$fa-css-prefix}-eraser:before { content: $fa-var-eraser; }
+.#{$fa-css-prefix}-puzzle-piece:before { content: $fa-var-puzzle-piece; }
+.#{$fa-css-prefix}-microphone:before { content: $fa-var-microphone; }
+.#{$fa-css-prefix}-microphone-slash:before { content: $fa-var-microphone-slash; }
+.#{$fa-css-prefix}-shield:before { content: $fa-var-shield; }
+.#{$fa-css-prefix}-calendar-o:before { content: $fa-var-calendar-o; }
+.#{$fa-css-prefix}-fire-extinguisher:before { content: $fa-var-fire-extinguisher; }
+.#{$fa-css-prefix}-rocket:before { content: $fa-var-rocket; }
+.#{$fa-css-prefix}-maxcdn:before { content: $fa-var-maxcdn; }
+.#{$fa-css-prefix}-chevron-circle-left:before { content: $fa-var-chevron-circle-left; }
+.#{$fa-css-prefix}-chevron-circle-right:before { content: $fa-var-chevron-circle-right; }
+.#{$fa-css-prefix}-chevron-circle-up:before { content: $fa-var-chevron-circle-up; }
+.#{$fa-css-prefix}-chevron-circle-down:before { content: $fa-var-chevron-circle-down; }
+.#{$fa-css-prefix}-html5:before { content: $fa-var-html5; }
+.#{$fa-css-prefix}-css3:before { content: $fa-var-css3; }
+.#{$fa-css-prefix}-anchor:before { content: $fa-var-anchor; }
+.#{$fa-css-prefix}-unlock-alt:before { content: $fa-var-unlock-alt; }
+.#{$fa-css-prefix}-bullseye:before { content: $fa-var-bullseye; }
+.#{$fa-css-prefix}-ellipsis-h:before { content: $fa-var-ellipsis-h; }
+.#{$fa-css-prefix}-ellipsis-v:before { content: $fa-var-ellipsis-v; }
+.#{$fa-css-prefix}-rss-square:before { content: $fa-var-rss-square; }
+.#{$fa-css-prefix}-play-circle:before { content: $fa-var-play-circle; }
+.#{$fa-css-prefix}-ticket:before { content: $fa-var-ticket; }
+.#{$fa-css-prefix}-minus-square:before { content: $fa-var-minus-square; }
+.#{$fa-css-prefix}-minus-square-o:before { content: $fa-var-minus-square-o; }
+.#{$fa-css-prefix}-level-up:before { content: $fa-var-level-up; }
+.#{$fa-css-prefix}-level-down:before { content: $fa-var-level-down; }
+.#{$fa-css-prefix}-check-square:before { content: $fa-var-check-square; }
+.#{$fa-css-prefix}-pencil-square:before { content: $fa-var-pencil-square; }
+.#{$fa-css-prefix}-external-link-square:before { content: $fa-var-external-link-square; }
+.#{$fa-css-prefix}-share-square:before { content: $fa-var-share-square; }
+.#{$fa-css-prefix}-compass:before { content: $fa-var-compass; }
+.#{$fa-css-prefix}-toggle-down:before,
+.#{$fa-css-prefix}-caret-square-o-down:before { content: $fa-var-caret-square-o-down; }
+.#{$fa-css-prefix}-toggle-up:before,
+.#{$fa-css-prefix}-caret-square-o-up:before { content: $fa-var-caret-square-o-up; }
+.#{$fa-css-prefix}-toggle-right:before,
+.#{$fa-css-prefix}-caret-square-o-right:before { content: $fa-var-caret-square-o-right; }
+.#{$fa-css-prefix}-euro:before,
+.#{$fa-css-prefix}-eur:before { content: $fa-var-eur; }
+.#{$fa-css-prefix}-gbp:before { content: $fa-var-gbp; }
+.#{$fa-css-prefix}-dollar:before,
+.#{$fa-css-prefix}-usd:before { content: $fa-var-usd; }
+.#{$fa-css-prefix}-rupee:before,
+.#{$fa-css-prefix}-inr:before { content: $fa-var-inr; }
+.#{$fa-css-prefix}-cny:before,
+.#{$fa-css-prefix}-rmb:before,
+.#{$fa-css-prefix}-yen:before,
+.#{$fa-css-prefix}-jpy:before { content: $fa-var-jpy; }
+.#{$fa-css-prefix}-ruble:before,
+.#{$fa-css-prefix}-rouble:before,
+.#{$fa-css-prefix}-rub:before { content: $fa-var-rub; }
+.#{$fa-css-prefix}-won:before,
+.#{$fa-css-prefix}-krw:before { content: $fa-var-krw; }
+.#{$fa-css-prefix}-bitcoin:before,
+.#{$fa-css-prefix}-btc:before { content: $fa-var-btc; }
+.#{$fa-css-prefix}-file:before { content: $fa-var-file; }
+.#{$fa-css-prefix}-file-text:before { content: $fa-var-file-text; }
+.#{$fa-css-prefix}-sort-alpha-asc:before { content: $fa-var-sort-alpha-asc; }
+.#{$fa-css-prefix}-sort-alpha-desc:before { content: $fa-var-sort-alpha-desc; }
+.#{$fa-css-prefix}-sort-amount-asc:before { content: $fa-var-sort-amount-asc; }
+.#{$fa-css-prefix}-sort-amount-desc:before { content: $fa-var-sort-amount-desc; }
+.#{$fa-css-prefix}-sort-numeric-asc:before { content: $fa-var-sort-numeric-asc; }
+.#{$fa-css-prefix}-sort-numeric-desc:before { content: $fa-var-sort-numeric-desc; }
+.#{$fa-css-prefix}-thumbs-up:before { content: $fa-var-thumbs-up; }
+.#{$fa-css-prefix}-thumbs-down:before { content: $fa-var-thumbs-down; }
+.#{$fa-css-prefix}-youtube-square:before { content: $fa-var-youtube-square; }
+.#{$fa-css-prefix}-youtube:before { content: $fa-var-youtube; }
+.#{$fa-css-prefix}-xing:before { content: $fa-var-xing; }
+.#{$fa-css-prefix}-xing-square:before { content: $fa-var-xing-square; }
+.#{$fa-css-prefix}-youtube-play:before { content: $fa-var-youtube-play; }
+.#{$fa-css-prefix}-dropbox:before { content: $fa-var-dropbox; }
+.#{$fa-css-prefix}-stack-overflow:before { content: $fa-var-stack-overflow; }
+.#{$fa-css-prefix}-instagram:before { content: $fa-var-instagram; }
+.#{$fa-css-prefix}-flickr:before { content: $fa-var-flickr; }
+.#{$fa-css-prefix}-adn:before { content: $fa-var-adn; }
+.#{$fa-css-prefix}-bitbucket:before { content: $fa-var-bitbucket; }
+.#{$fa-css-prefix}-bitbucket-square:before { content: $fa-var-bitbucket-square; }
+.#{$fa-css-prefix}-tumblr:before { content: $fa-var-tumblr; }
+.#{$fa-css-prefix}-tumblr-square:before { content: $fa-var-tumblr-square; }
+.#{$fa-css-prefix}-long-arrow-down:before { content: $fa-var-long-arrow-down; }
+.#{$fa-css-prefix}-long-arrow-up:before { content: $fa-var-long-arrow-up; }
+.#{$fa-css-prefix}-long-arrow-left:before { content: $fa-var-long-arrow-left; }
+.#{$fa-css-prefix}-long-arrow-right:before { content: $fa-var-long-arrow-right; }
+.#{$fa-css-prefix}-apple:before { content: $fa-var-apple; }
+.#{$fa-css-prefix}-windows:before { content: $fa-var-windows; }
+.#{$fa-css-prefix}-android:before { content: $fa-var-android; }
+.#{$fa-css-prefix}-linux:before { content: $fa-var-linux; }
+.#{$fa-css-prefix}-dribbble:before { content: $fa-var-dribbble; }
+.#{$fa-css-prefix}-skype:before { content: $fa-var-skype; }
+.#{$fa-css-prefix}-foursquare:before { content: $fa-var-foursquare; }
+.#{$fa-css-prefix}-trello:before { content: $fa-var-trello; }
+.#{$fa-css-prefix}-female:before { content: $fa-var-female; }
+.#{$fa-css-prefix}-male:before { content: $fa-var-male; }
+.#{$fa-css-prefix}-gittip:before,
+.#{$fa-css-prefix}-gratipay:before { content: $fa-var-gratipay; }
+.#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; }
+.#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; }
+.#{$fa-css-prefix}-archive:before { content: $fa-var-archive; }
+.#{$fa-css-prefix}-bug:before { content: $fa-var-bug; }
+.#{$fa-css-prefix}-vk:before { content: $fa-var-vk; }
+.#{$fa-css-prefix}-weibo:before { content: $fa-var-weibo; }
+.#{$fa-css-prefix}-renren:before { content: $fa-var-renren; }
+.#{$fa-css-prefix}-pagelines:before { content: $fa-var-pagelines; }
+.#{$fa-css-prefix}-stack-exchange:before { content: $fa-var-stack-exchange; }
+.#{$fa-css-prefix}-arrow-circle-o-right:before { content: $fa-var-arrow-circle-o-right; }
+.#{$fa-css-prefix}-arrow-circle-o-left:before { content: $fa-var-arrow-circle-o-left; }
+.#{$fa-css-prefix}-toggle-left:before,
+.#{$fa-css-prefix}-caret-square-o-left:before { content: $fa-var-caret-square-o-left; }
+.#{$fa-css-prefix}-dot-circle-o:before { content: $fa-var-dot-circle-o; }
+.#{$fa-css-prefix}-wheelchair:before { content: $fa-var-wheelchair; }
+.#{$fa-css-prefix}-vimeo-square:before { content: $fa-var-vimeo-square; }
+.#{$fa-css-prefix}-turkish-lira:before,
+.#{$fa-css-prefix}-try:before { content: $fa-var-try; }
+.#{$fa-css-prefix}-plus-square-o:before { content: $fa-var-plus-square-o; }
+.#{$fa-css-prefix}-space-shuttle:before { content: $fa-var-space-shuttle; }
+.#{$fa-css-prefix}-slack:before { content: $fa-var-slack; }
+.#{$fa-css-prefix}-envelope-square:before { content: $fa-var-envelope-square; }
+.#{$fa-css-prefix}-wordpress:before { content: $fa-var-wordpress; }
+.#{$fa-css-prefix}-openid:before { content: $fa-var-openid; }
+.#{$fa-css-prefix}-institution:before,
+.#{$fa-css-prefix}-bank:before,
+.#{$fa-css-prefix}-university:before { content: $fa-var-university; }
+.#{$fa-css-prefix}-mortar-board:before,
+.#{$fa-css-prefix}-graduation-cap:before { content: $fa-var-graduation-cap; }
+.#{$fa-css-prefix}-yahoo:before { content: $fa-var-yahoo; }
+.#{$fa-css-prefix}-google:before { content: $fa-var-google; }
+.#{$fa-css-prefix}-reddit:before { content: $fa-var-reddit; }
+.#{$fa-css-prefix}-reddit-square:before { content: $fa-var-reddit-square; }
+.#{$fa-css-prefix}-stumbleupon-circle:before { content: $fa-var-stumbleupon-circle; }
+.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; }
+.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; }
+.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; }
+.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; }
+.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; }
+.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; }
+.#{$fa-css-prefix}-joomla:before { content: $fa-var-joomla; }
+.#{$fa-css-prefix}-language:before { content: $fa-var-language; }
+.#{$fa-css-prefix}-fax:before { content: $fa-var-fax; }
+.#{$fa-css-prefix}-building:before { content: $fa-var-building; }
+.#{$fa-css-prefix}-child:before { content: $fa-var-child; }
+.#{$fa-css-prefix}-paw:before { content: $fa-var-paw; }
+.#{$fa-css-prefix}-spoon:before { content: $fa-var-spoon; }
+.#{$fa-css-prefix}-cube:before { content: $fa-var-cube; }
+.#{$fa-css-prefix}-cubes:before { content: $fa-var-cubes; }
+.#{$fa-css-prefix}-behance:before { content: $fa-var-behance; }
+.#{$fa-css-prefix}-behance-square:before { content: $fa-var-behance-square; }
+.#{$fa-css-prefix}-steam:before { content: $fa-var-steam; }
+.#{$fa-css-prefix}-steam-square:before { content: $fa-var-steam-square; }
+.#{$fa-css-prefix}-recycle:before { content: $fa-var-recycle; }
+.#{$fa-css-prefix}-automobile:before,
+.#{$fa-css-prefix}-car:before { content: $fa-var-car; }
+.#{$fa-css-prefix}-cab:before,
+.#{$fa-css-prefix}-taxi:before { content: $fa-var-taxi; }
+.#{$fa-css-prefix}-tree:before { content: $fa-var-tree; }
+.#{$fa-css-prefix}-spotify:before { content: $fa-var-spotify; }
+.#{$fa-css-prefix}-deviantart:before { content: $fa-var-deviantart; }
+.#{$fa-css-prefix}-soundcloud:before { content: $fa-var-soundcloud; }
+.#{$fa-css-prefix}-database:before { content: $fa-var-database; }
+.#{$fa-css-prefix}-file-pdf-o:before { content: $fa-var-file-pdf-o; }
+.#{$fa-css-prefix}-file-word-o:before { content: $fa-var-file-word-o; }
+.#{$fa-css-prefix}-file-excel-o:before { content: $fa-var-file-excel-o; }
+.#{$fa-css-prefix}-file-powerpoint-o:before { content: $fa-var-file-powerpoint-o; }
+.#{$fa-css-prefix}-file-photo-o:before,
+.#{$fa-css-prefix}-file-picture-o:before,
+.#{$fa-css-prefix}-file-image-o:before { content: $fa-var-file-image-o; }
+.#{$fa-css-prefix}-file-zip-o:before,
+.#{$fa-css-prefix}-file-archive-o:before { content: $fa-var-file-archive-o; }
+.#{$fa-css-prefix}-file-sound-o:before,
+.#{$fa-css-prefix}-file-audio-o:before { content: $fa-var-file-audio-o; }
+.#{$fa-css-prefix}-file-movie-o:before,
+.#{$fa-css-prefix}-file-video-o:before { content: $fa-var-file-video-o; }
+.#{$fa-css-prefix}-file-code-o:before { content: $fa-var-file-code-o; }
+.#{$fa-css-prefix}-vine:before { content: $fa-var-vine; }
+.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; }
+.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; }
+.#{$fa-css-prefix}-life-bouy:before,
+.#{$fa-css-prefix}-life-buoy:before,
+.#{$fa-css-prefix}-life-saver:before,
+.#{$fa-css-prefix}-support:before,
+.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; }
+.#{$fa-css-prefix}-circle-o-notch:before { content: $fa-var-circle-o-notch; }
+.#{$fa-css-prefix}-ra:before,
+.#{$fa-css-prefix}-rebel:before { content: $fa-var-rebel; }
+.#{$fa-css-prefix}-ge:before,
+.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; }
+.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; }
+.#{$fa-css-prefix}-git:before { content: $fa-var-git; }
+.#{$fa-css-prefix}-y-combinator-square:before,
+.#{$fa-css-prefix}-yc-square:before,
+.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; }
+.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; }
+.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; }
+.#{$fa-css-prefix}-wechat:before,
+.#{$fa-css-prefix}-weixin:before { content: $fa-var-weixin; }
+.#{$fa-css-prefix}-send:before,
+.#{$fa-css-prefix}-paper-plane:before { content: $fa-var-paper-plane; }
+.#{$fa-css-prefix}-send-o:before,
+.#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; }
+.#{$fa-css-prefix}-history:before { content: $fa-var-history; }
+.#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; }
+.#{$fa-css-prefix}-header:before { content: $fa-var-header; }
+.#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; }
+.#{$fa-css-prefix}-sliders:before { content: $fa-var-sliders; }
+.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; }
+.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; }
+.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; }
+.#{$fa-css-prefix}-soccer-ball-o:before,
+.#{$fa-css-prefix}-futbol-o:before { content: $fa-var-futbol-o; }
+.#{$fa-css-prefix}-tty:before { content: $fa-var-tty; }
+.#{$fa-css-prefix}-binoculars:before { content: $fa-var-binoculars; }
+.#{$fa-css-prefix}-plug:before { content: $fa-var-plug; }
+.#{$fa-css-prefix}-slideshare:before { content: $fa-var-slideshare; }
+.#{$fa-css-prefix}-twitch:before { content: $fa-var-twitch; }
+.#{$fa-css-prefix}-yelp:before { content: $fa-var-yelp; }
+.#{$fa-css-prefix}-newspaper-o:before { content: $fa-var-newspaper-o; }
+.#{$fa-css-prefix}-wifi:before { content: $fa-var-wifi; }
+.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; }
+.#{$fa-css-prefix}-paypal:before { content: $fa-var-paypal; }
+.#{$fa-css-prefix}-google-wallet:before { content: $fa-var-google-wallet; }
+.#{$fa-css-prefix}-cc-visa:before { content: $fa-var-cc-visa; }
+.#{$fa-css-prefix}-cc-mastercard:before { content: $fa-var-cc-mastercard; }
+.#{$fa-css-prefix}-cc-discover:before { content: $fa-var-cc-discover; }
+.#{$fa-css-prefix}-cc-amex:before { content: $fa-var-cc-amex; }
+.#{$fa-css-prefix}-cc-paypal:before { content: $fa-var-cc-paypal; }
+.#{$fa-css-prefix}-cc-stripe:before { content: $fa-var-cc-stripe; }
+.#{$fa-css-prefix}-bell-slash:before { content: $fa-var-bell-slash; }
+.#{$fa-css-prefix}-bell-slash-o:before { content: $fa-var-bell-slash-o; }
+.#{$fa-css-prefix}-trash:before { content: $fa-var-trash; }
+.#{$fa-css-prefix}-copyright:before { content: $fa-var-copyright; }
+.#{$fa-css-prefix}-at:before { content: $fa-var-at; }
+.#{$fa-css-prefix}-eyedropper:before { content: $fa-var-eyedropper; }
+.#{$fa-css-prefix}-paint-brush:before { content: $fa-var-paint-brush; }
+.#{$fa-css-prefix}-birthday-cake:before { content: $fa-var-birthday-cake; }
+.#{$fa-css-prefix}-area-chart:before { content: $fa-var-area-chart; }
+.#{$fa-css-prefix}-pie-chart:before { content: $fa-var-pie-chart; }
+.#{$fa-css-prefix}-line-chart:before { content: $fa-var-line-chart; }
+.#{$fa-css-prefix}-lastfm:before { content: $fa-var-lastfm; }
+.#{$fa-css-prefix}-lastfm-square:before { content: $fa-var-lastfm-square; }
+.#{$fa-css-prefix}-toggle-off:before { content: $fa-var-toggle-off; }
+.#{$fa-css-prefix}-toggle-on:before { content: $fa-var-toggle-on; }
+.#{$fa-css-prefix}-bicycle:before { content: $fa-var-bicycle; }
+.#{$fa-css-prefix}-bus:before { content: $fa-var-bus; }
+.#{$fa-css-prefix}-ioxhost:before { content: $fa-var-ioxhost; }
+.#{$fa-css-prefix}-angellist:before { content: $fa-var-angellist; }
+.#{$fa-css-prefix}-cc:before { content: $fa-var-cc; }
+.#{$fa-css-prefix}-shekel:before,
+.#{$fa-css-prefix}-sheqel:before,
+.#{$fa-css-prefix}-ils:before { content: $fa-var-ils; }
+.#{$fa-css-prefix}-meanpath:before { content: $fa-var-meanpath; }
+.#{$fa-css-prefix}-buysellads:before { content: $fa-var-buysellads; }
+.#{$fa-css-prefix}-connectdevelop:before { content: $fa-var-connectdevelop; }
+.#{$fa-css-prefix}-dashcube:before { content: $fa-var-dashcube; }
+.#{$fa-css-prefix}-forumbee:before { content: $fa-var-forumbee; }
+.#{$fa-css-prefix}-leanpub:before { content: $fa-var-leanpub; }
+.#{$fa-css-prefix}-sellsy:before { content: $fa-var-sellsy; }
+.#{$fa-css-prefix}-shirtsinbulk:before { content: $fa-var-shirtsinbulk; }
+.#{$fa-css-prefix}-simplybuilt:before { content: $fa-var-simplybuilt; }
+.#{$fa-css-prefix}-skyatlas:before { content: $fa-var-skyatlas; }
+.#{$fa-css-prefix}-cart-plus:before { content: $fa-var-cart-plus; }
+.#{$fa-css-prefix}-cart-arrow-down:before { content: $fa-var-cart-arrow-down; }
+.#{$fa-css-prefix}-diamond:before { content: $fa-var-diamond; }
+.#{$fa-css-prefix}-ship:before { content: $fa-var-ship; }
+.#{$fa-css-prefix}-user-secret:before { content: $fa-var-user-secret; }
+.#{$fa-css-prefix}-motorcycle:before { content: $fa-var-motorcycle; }
+.#{$fa-css-prefix}-street-view:before { content: $fa-var-street-view; }
+.#{$fa-css-prefix}-heartbeat:before { content: $fa-var-heartbeat; }
+.#{$fa-css-prefix}-venus:before { content: $fa-var-venus; }
+.#{$fa-css-prefix}-mars:before { content: $fa-var-mars; }
+.#{$fa-css-prefix}-mercury:before { content: $fa-var-mercury; }
+.#{$fa-css-prefix}-intersex:before,
+.#{$fa-css-prefix}-transgender:before { content: $fa-var-transgender; }
+.#{$fa-css-prefix}-transgender-alt:before { content: $fa-var-transgender-alt; }
+.#{$fa-css-prefix}-venus-double:before { content: $fa-var-venus-double; }
+.#{$fa-css-prefix}-mars-double:before { content: $fa-var-mars-double; }
+.#{$fa-css-prefix}-venus-mars:before { content: $fa-var-venus-mars; }
+.#{$fa-css-prefix}-mars-stroke:before { content: $fa-var-mars-stroke; }
+.#{$fa-css-prefix}-mars-stroke-v:before { content: $fa-var-mars-stroke-v; }
+.#{$fa-css-prefix}-mars-stroke-h:before { content: $fa-var-mars-stroke-h; }
+.#{$fa-css-prefix}-neuter:before { content: $fa-var-neuter; }
+.#{$fa-css-prefix}-genderless:before { content: $fa-var-genderless; }
+.#{$fa-css-prefix}-facebook-official:before { content: $fa-var-facebook-official; }
+.#{$fa-css-prefix}-pinterest-p:before { content: $fa-var-pinterest-p; }
+.#{$fa-css-prefix}-whatsapp:before { content: $fa-var-whatsapp; }
+.#{$fa-css-prefix}-server:before { content: $fa-var-server; }
+.#{$fa-css-prefix}-user-plus:before { content: $fa-var-user-plus; }
+.#{$fa-css-prefix}-user-times:before { content: $fa-var-user-times; }
+.#{$fa-css-prefix}-hotel:before,
+.#{$fa-css-prefix}-bed:before { content: $fa-var-bed; }
+.#{$fa-css-prefix}-viacoin:before { content: $fa-var-viacoin; }
+.#{$fa-css-prefix}-train:before { content: $fa-var-train; }
+.#{$fa-css-prefix}-subway:before { content: $fa-var-subway; }
+.#{$fa-css-prefix}-medium:before { content: $fa-var-medium; }
+.#{$fa-css-prefix}-yc:before,
+.#{$fa-css-prefix}-y-combinator:before { content: $fa-var-y-combinator; }
+.#{$fa-css-prefix}-optin-monster:before { content: $fa-var-optin-monster; }
+.#{$fa-css-prefix}-opencart:before { content: $fa-var-opencart; }
+.#{$fa-css-prefix}-expeditedssl:before { content: $fa-var-expeditedssl; }
+.#{$fa-css-prefix}-battery-4:before,
+.#{$fa-css-prefix}-battery-full:before { content: $fa-var-battery-full; }
+.#{$fa-css-prefix}-battery-3:before,
+.#{$fa-css-prefix}-battery-three-quarters:before { content: $fa-var-battery-three-quarters; }
+.#{$fa-css-prefix}-battery-2:before,
+.#{$fa-css-prefix}-battery-half:before { content: $fa-var-battery-half; }
+.#{$fa-css-prefix}-battery-1:before,
+.#{$fa-css-prefix}-battery-quarter:before { content: $fa-var-battery-quarter; }
+.#{$fa-css-prefix}-battery-0:before,
+.#{$fa-css-prefix}-battery-empty:before { content: $fa-var-battery-empty; }
+.#{$fa-css-prefix}-mouse-pointer:before { content: $fa-var-mouse-pointer; }
+.#{$fa-css-prefix}-i-cursor:before { content: $fa-var-i-cursor; }
+.#{$fa-css-prefix}-object-group:before { content: $fa-var-object-group; }
+.#{$fa-css-prefix}-object-ungroup:before { content: $fa-var-object-ungroup; }
+.#{$fa-css-prefix}-sticky-note:before { content: $fa-var-sticky-note; }
+.#{$fa-css-prefix}-sticky-note-o:before { content: $fa-var-sticky-note-o; }
+.#{$fa-css-prefix}-cc-jcb:before { content: $fa-var-cc-jcb; }
+.#{$fa-css-prefix}-cc-diners-club:before { content: $fa-var-cc-diners-club; }
+.#{$fa-css-prefix}-clone:before { content: $fa-var-clone; }
+.#{$fa-css-prefix}-balance-scale:before { content: $fa-var-balance-scale; }
+.#{$fa-css-prefix}-hourglass-o:before { content: $fa-var-hourglass-o; }
+.#{$fa-css-prefix}-hourglass-1:before,
+.#{$fa-css-prefix}-hourglass-start:before { content: $fa-var-hourglass-start; }
+.#{$fa-css-prefix}-hourglass-2:before,
+.#{$fa-css-prefix}-hourglass-half:before { content: $fa-var-hourglass-half; }
+.#{$fa-css-prefix}-hourglass-3:before,
+.#{$fa-css-prefix}-hourglass-end:before { content: $fa-var-hourglass-end; }
+.#{$fa-css-prefix}-hourglass:before { content: $fa-var-hourglass; }
+.#{$fa-css-prefix}-hand-grab-o:before,
+.#{$fa-css-prefix}-hand-rock-o:before { content: $fa-var-hand-rock-o; }
+.#{$fa-css-prefix}-hand-stop-o:before,
+.#{$fa-css-prefix}-hand-paper-o:before { content: $fa-var-hand-paper-o; }
+.#{$fa-css-prefix}-hand-scissors-o:before { content: $fa-var-hand-scissors-o; }
+.#{$fa-css-prefix}-hand-lizard-o:before { content: $fa-var-hand-lizard-o; }
+.#{$fa-css-prefix}-hand-spock-o:before { content: $fa-var-hand-spock-o; }
+.#{$fa-css-prefix}-hand-pointer-o:before { content: $fa-var-hand-pointer-o; }
+.#{$fa-css-prefix}-hand-peace-o:before { content: $fa-var-hand-peace-o; }
+.#{$fa-css-prefix}-trademark:before { content: $fa-var-trademark; }
+.#{$fa-css-prefix}-registered:before { content: $fa-var-registered; }
+.#{$fa-css-prefix}-creative-commons:before { content: $fa-var-creative-commons; }
+.#{$fa-css-prefix}-gg:before { content: $fa-var-gg; }
+.#{$fa-css-prefix}-gg-circle:before { content: $fa-var-gg-circle; }
+.#{$fa-css-prefix}-tripadvisor:before { content: $fa-var-tripadvisor; }
+.#{$fa-css-prefix}-odnoklassniki:before { content: $fa-var-odnoklassniki; }
+.#{$fa-css-prefix}-odnoklassniki-square:before { content: $fa-var-odnoklassniki-square; }
+.#{$fa-css-prefix}-get-pocket:before { content: $fa-var-get-pocket; }
+.#{$fa-css-prefix}-wikipedia-w:before { content: $fa-var-wikipedia-w; }
+.#{$fa-css-prefix}-safari:before { content: $fa-var-safari; }
+.#{$fa-css-prefix}-chrome:before { content: $fa-var-chrome; }
+.#{$fa-css-prefix}-firefox:before { content: $fa-var-firefox; }
+.#{$fa-css-prefix}-opera:before { content: $fa-var-opera; }
+.#{$fa-css-prefix}-internet-explorer:before { content: $fa-var-internet-explorer; }
+.#{$fa-css-prefix}-tv:before,
+.#{$fa-css-prefix}-television:before { content: $fa-var-television; }
+.#{$fa-css-prefix}-contao:before { content: $fa-var-contao; }
+.#{$fa-css-prefix}-500px:before { content: $fa-var-500px; }
+.#{$fa-css-prefix}-amazon:before { content: $fa-var-amazon; }
+.#{$fa-css-prefix}-calendar-plus-o:before { content: $fa-var-calendar-plus-o; }
+.#{$fa-css-prefix}-calendar-minus-o:before { content: $fa-var-calendar-minus-o; }
+.#{$fa-css-prefix}-calendar-times-o:before { content: $fa-var-calendar-times-o; }
+.#{$fa-css-prefix}-calendar-check-o:before { content: $fa-var-calendar-check-o; }
+.#{$fa-css-prefix}-industry:before { content: $fa-var-industry; }
+.#{$fa-css-prefix}-map-pin:before { content: $fa-var-map-pin; }
+.#{$fa-css-prefix}-map-signs:before { content: $fa-var-map-signs; }
+.#{$fa-css-prefix}-map-o:before { content: $fa-var-map-o; }
+.#{$fa-css-prefix}-map:before { content: $fa-var-map; }
+.#{$fa-css-prefix}-commenting:before { content: $fa-var-commenting; }
+.#{$fa-css-prefix}-commenting-o:before { content: $fa-var-commenting-o; }
+.#{$fa-css-prefix}-houzz:before { content: $fa-var-houzz; }
+.#{$fa-css-prefix}-vimeo:before { content: $fa-var-vimeo; }
+.#{$fa-css-prefix}-black-tie:before { content: $fa-var-black-tie; }
+.#{$fa-css-prefix}-fonticons:before { content: $fa-var-fonticons; }
+.#{$fa-css-prefix}-reddit-alien:before { content: $fa-var-reddit-alien; }
+.#{$fa-css-prefix}-edge:before { content: $fa-var-edge; }
+.#{$fa-css-prefix}-credit-card-alt:before { content: $fa-var-credit-card-alt; }
+.#{$fa-css-prefix}-codiepie:before { content: $fa-var-codiepie; }
+.#{$fa-css-prefix}-modx:before { content: $fa-var-modx; }
+.#{$fa-css-prefix}-fort-awesome:before { content: $fa-var-fort-awesome; }
+.#{$fa-css-prefix}-usb:before { content: $fa-var-usb; }
+.#{$fa-css-prefix}-product-hunt:before { content: $fa-var-product-hunt; }
+.#{$fa-css-prefix}-mixcloud:before { content: $fa-var-mixcloud; }
+.#{$fa-css-prefix}-scribd:before { content: $fa-var-scribd; }
+.#{$fa-css-prefix}-pause-circle:before { content: $fa-var-pause-circle; }
+.#{$fa-css-prefix}-pause-circle-o:before { content: $fa-var-pause-circle-o; }
+.#{$fa-css-prefix}-stop-circle:before { content: $fa-var-stop-circle; }
+.#{$fa-css-prefix}-stop-circle-o:before { content: $fa-var-stop-circle-o; }
+.#{$fa-css-prefix}-shopping-bag:before { content: $fa-var-shopping-bag; }
+.#{$fa-css-prefix}-shopping-basket:before { content: $fa-var-shopping-basket; }
+.#{$fa-css-prefix}-hashtag:before { content: $fa-var-hashtag; }
+.#{$fa-css-prefix}-bluetooth:before { content: $fa-var-bluetooth; }
+.#{$fa-css-prefix}-bluetooth-b:before { content: $fa-var-bluetooth-b; }
+.#{$fa-css-prefix}-percent:before { content: $fa-var-percent; }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_larger.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_larger.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_larger.scss
new file mode 100644
index 0000000..41e9a81
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_larger.scss
@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.#{$fa-css-prefix}-lg {
+  font-size: (4em / 3);
+  line-height: (3em / 4);
+  vertical-align: -15%;
+}
+.#{$fa-css-prefix}-2x { font-size: 2em; }
+.#{$fa-css-prefix}-3x { font-size: 3em; }
+.#{$fa-css-prefix}-4x { font-size: 4em; }
+.#{$fa-css-prefix}-5x { font-size: 5em; }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_list.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_list.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_list.scss
new file mode 100644
index 0000000..7d1e4d5
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_list.scss
@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.#{$fa-css-prefix}-ul {
+  padding-left: 0;
+  margin-left: $fa-li-width;
+  list-style-type: none;
+  > li { position: relative; }
+}
+.#{$fa-css-prefix}-li {
+  position: absolute;
+  left: -$fa-li-width;
+  width: $fa-li-width;
+  top: (2em / 14);
+  text-align: center;
+  &.#{$fa-css-prefix}-lg {
+    left: -$fa-li-width + (4em / 14);
+  }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_mixins.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_mixins.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_mixins.scss
new file mode 100644
index 0000000..f96719b
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_mixins.scss
@@ -0,0 +1,26 @@
+// Mixins
+// --------------------------
+
+@mixin fa-icon() {
+  display: inline-block;
+  font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
+  font-size: inherit; // can't have font-size inherit on line above, so need to override
+  text-rendering: auto; // optimizelegibility throws things off #1094
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+}
+
+@mixin fa-icon-rotate($degrees, $rotation) {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
+  -webkit-transform: rotate($degrees);
+      -ms-transform: rotate($degrees);
+          transform: rotate($degrees);
+}
+
+@mixin fa-icon-flip($horiz, $vert, $rotation) {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
+  -webkit-transform: scale($horiz, $vert);
+      -ms-transform: scale($horiz, $vert);
+          transform: scale($horiz, $vert);
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_path.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_path.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_path.scss
new file mode 100644
index 0000000..bb457c2
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_path.scss
@@ -0,0 +1,15 @@
+/* FONT PATH
+ * -------------------------- */
+
+@font-face {
+  font-family: 'FontAwesome';
+  src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
+  src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
+    url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
+    url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
+    url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
+    url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
+//  src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
+  font-weight: normal;
+  font-style: normal;
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_rotated-flipped.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_rotated-flipped.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_rotated-flipped.scss
new file mode 100644
index 0000000..a3558fd
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_rotated-flipped.scss
@@ -0,0 +1,20 @@
+// Rotated & Flipped Icons
+// -------------------------
+
+.#{$fa-css-prefix}-rotate-90  { @include fa-icon-rotate(90deg, 1);  }
+.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
+.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
+
+.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
+.#{$fa-css-prefix}-flip-vertical   { @include fa-icon-flip(1, -1, 2); }
+
+// Hook for IE8-9
+// -------------------------
+
+:root .#{$fa-css-prefix}-rotate-90,
+:root .#{$fa-css-prefix}-rotate-180,
+:root .#{$fa-css-prefix}-rotate-270,
+:root .#{$fa-css-prefix}-flip-horizontal,
+:root .#{$fa-css-prefix}-flip-vertical {
+  filter: none;
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_stacked.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_stacked.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_stacked.scss
new file mode 100644
index 0000000..aef7403
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_stacked.scss
@@ -0,0 +1,20 @@
+// Stacked Icons
+// -------------------------
+
+.#{$fa-css-prefix}-stack {
+  position: relative;
+  display: inline-block;
+  width: 2em;
+  height: 2em;
+  line-height: 2em;
+  vertical-align: middle;
+}
+.#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
+  position: absolute;
+  left: 0;
+  width: 100%;
+  text-align: center;
+}
+.#{$fa-css-prefix}-stack-1x { line-height: inherit; }
+.#{$fa-css-prefix}-stack-2x { font-size: 2em; }
+.#{$fa-css-prefix}-inverse { color: $fa-inverse; }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_variables.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_variables.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_variables.scss
new file mode 100644
index 0000000..0a47110
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_variables.scss
@@ -0,0 +1,708 @@
+// Variables
+// --------------------------
+
+$fa-font-path:        "../fonts" !default;
+$fa-font-size-base:   14px !default;
+$fa-line-height-base: 1 !default;
+//$fa-font-path:        "//netdna.bootstrapcdn.com/font-awesome/4.5.0/fonts" !default; // for referencing Bootstrap CDN font files directly
+$fa-css-prefix:       fa !default;
+$fa-version:          "4.5.0" !default;
+$fa-border-color:     #eee !default;
+$fa-inverse:          #fff !default;
+$fa-li-width:         (30em / 14) !default;
+
+$fa-var-500px: "\f26e";
+$fa-var-adjust: "\f042";
+$fa-var-adn: "\f170";
+$fa-var-align-center: "\f037";
+$fa-var-align-justify: "\f039";
+$fa-var-align-left: "\f036";
+$fa-var-align-right: "\f038";
+$fa-var-amazon: "\f270";
+$fa-var-ambulance: "\f0f9";
+$fa-var-anchor: "\f13d";
+$fa-var-android: "\f17b";
+$fa-var-angellist: "\f209";
+$fa-var-angle-double-down: "\f103";
+$fa-var-angle-double-left: "\f100";
+$fa-var-angle-double-right: "\f101";
+$fa-var-angle-double-up: "\f102";
+$fa-var-angle-down: "\f107";
+$fa-var-angle-left: "\f104";
+$fa-var-angle-right: "\f105";
+$fa-var-angle-up: "\f106";
+$fa-var-apple: "\f179";
+$fa-var-archive: "\f187";
+$fa-var-area-chart: "\f1fe";
+$fa-var-arrow-circle-down: "\f0ab";
+$fa-var-arrow-circle-left: "\f0a8";
+$fa-var-arrow-circle-o-down: "\f01a";
+$fa-var-arrow-circle-o-left: "\f190";
+$fa-var-arrow-circle-o-right: "\f18e";
+$fa-var-arrow-circle-o-up: "\f01b";
+$fa-var-arrow-circle-right: "\f0a9";
+$fa-var-arrow-circle-up: "\f0aa";
+$fa-var-arrow-down: "\f063";
+$fa-var-arrow-left: "\f060";
+$fa-var-arrow-right: "\f061";
+$fa-var-arrow-up: "\f062";
+$fa-var-arrows: "\f047";
+$fa-var-arrows-alt: "\f0b2";
+$fa-var-arrows-h: "\f07e";
+$fa-var-arrows-v: "\f07d";
+$fa-var-asterisk: "\f069";
+$fa-var-at: "\f1fa";
+$fa-var-automobile: "\f1b9";
+$fa-var-backward: "\f04a";
+$fa-var-balance-scale: "\f24e";
+$fa-var-ban: "\f05e";
+$fa-var-bank: "\f19c";
+$fa-var-bar-chart: "\f080";
+$fa-var-bar-chart-o: "\f080";
+$fa-var-barcode: "\f02a";
+$fa-var-bars: "\f0c9";
+$fa-var-battery-0: "\f244";
+$fa-var-battery-1: "\f243";
+$fa-var-battery-2: "\f242";
+$fa-var-battery-3: "\f241";
+$fa-var-battery-4: "\f240";
+$fa-var-battery-empty: "\f244";
+$fa-var-battery-full: "\f240";
+$fa-var-battery-half: "\f242";
+$fa-var-battery-quarter: "\f243";
+$fa-var-battery-three-quarters: "\f241";
+$fa-var-bed: "\f236";
+$fa-var-beer: "\f0fc";
+$fa-var-behance: "\f1b4";
+$fa-var-behance-square: "\f1b5";
+$fa-var-bell: "\f0f3";
+$fa-var-bell-o: "\f0a2";
+$fa-var-bell-slash: "\f1f6";
+$fa-var-bell-slash-o: "\f1f7";
+$fa-var-bicycle: "\f206";
+$fa-var-binoculars: "\f1e5";
+$fa-var-birthday-cake: "\f1fd";
+$fa-var-bitbucket: "\f171";
+$fa-var-bitbucket-square: "\f172";
+$fa-var-bitcoin: "\f15a";
+$fa-var-black-tie: "\f27e";
+$fa-var-bluetooth: "\f293";
+$fa-var-bluetooth-b: "\f294";
+$fa-var-bold: "\f032";
+$fa-var-bolt: "\f0e7";
+$fa-var-bomb: "\f1e2";
+$fa-var-book: "\f02d";
+$fa-var-bookmark: "\f02e";
+$fa-var-bookmark-o: "\f097";
+$fa-var-briefcase: "\f0b1";
+$fa-var-btc: "\f15a";
+$fa-var-bug: "\f188";
+$fa-var-building: "\f1ad";
+$fa-var-building-o: "\f0f7";
+$fa-var-bullhorn: "\f0a1";
+$fa-var-bullseye: "\f140";
+$fa-var-bus: "\f207";
+$fa-var-buysellads: "\f20d";
+$fa-var-cab: "\f1ba";
+$fa-var-calculator: "\f1ec";
+$fa-var-calendar: "\f073";
+$fa-var-calendar-check-o: "\f274";
+$fa-var-calendar-minus-o: "\f272";
+$fa-var-calendar-o: "\f133";
+$fa-var-calendar-plus-o: "\f271";
+$fa-var-calendar-times-o: "\f273";
+$fa-var-camera: "\f030";
+$fa-var-camera-retro: "\f083";
+$fa-var-car: "\f1b9";
+$fa-var-caret-down: "\f0d7";
+$fa-var-caret-left: "\f0d9";
+$fa-var-caret-right: "\f0da";
+$fa-var-caret-square-o-down: "\f150";
+$fa-var-caret-square-o-left: "\f191";
+$fa-var-caret-square-o-right: "\f152";
+$fa-var-caret-square-o-up: "\f151";
+$fa-var-caret-up: "\f0d8";
+$fa-var-cart-arrow-down: "\f218";
+$fa-var-cart-plus: "\f217";
+$fa-var-cc: "\f20a";
+$fa-var-cc-amex: "\f1f3";
+$fa-var-cc-diners-club: "\f24c";
+$fa-var-cc-discover: "\f1f2";
+$fa-var-cc-jcb: "\f24b";
+$fa-var-cc-mastercard: "\f1f1";
+$fa-var-cc-paypal: "\f1f4";
+$fa-var-cc-stripe: "\f1f5";
+$fa-var-cc-visa: "\f1f0";
+$fa-var-certificate: "\f0a3";
+$fa-var-chain: "\f0c1";
+$fa-var-chain-broken: "\f127";
+$fa-var-check: "\f00c";
+$fa-var-check-circle: "\f058";
+$fa-var-check-circle-o: "\f05d";
+$fa-var-check-square: "\f14a";
+$fa-var-check-square-o: "\f046";
+$fa-var-chevron-circle-down: "\f13a";
+$fa-var-chevron-circle-left: "\f137";
+$fa-var-chevron-circle-right: "\f138";
+$fa-var-chevron-circle-up: "\f139";
+$fa-var-chevron-down: "\f078";
+$fa-var-chevron-left: "\f053";
+$fa-var-chevron-right: "\f054";
+$fa-var-chevron-up: "\f077";
+$fa-var-child: "\f1ae";
+$fa-var-chrome: "\f268";
+$fa-var-circle: "\f111";
+$fa-var-circle-o: "\f10c";
+$fa-var-circle-o-notch: "\f1ce";
+$fa-var-circle-thin: "\f1db";
+$fa-var-clipboard: "\f0ea";
+$fa-var-clock-o: "\f017";
+$fa-var-clone: "\f24d";
+$fa-var-close: "\f00d";
+$fa-var-cloud: "\f0c2";
+$fa-var-cloud-download: "\f0ed";
+$fa-var-cloud-upload: "\f0ee";
+$fa-var-cny: "\f157";
+$fa-var-code: "\f121";
+$fa-var-code-fork: "\f126";
+$fa-var-codepen: "\f1cb";
+$fa-var-codiepie: "\f284";
+$fa-var-coffee: "\f0f4";
+$fa-var-cog: "\f013";
+$fa-var-cogs: "\f085";
+$fa-var-columns: "\f0db";
+$fa-var-comment: "\f075";
+$fa-var-comment-o: "\f0e5";
+$fa-var-commenting: "\f27a";
+$fa-var-commenting-o: "\f27b";
+$fa-var-comments: "\f086";
+$fa-var-comments-o: "\f0e6";
+$fa-var-compass: "\f14e";
+$fa-var-compress: "\f066";
+$fa-var-connectdevelop: "\f20e";
+$fa-var-contao: "\f26d";
+$fa-var-copy: "\f0c5";
+$fa-var-copyright: "\f1f9";
+$fa-var-creative-commons: "\f25e";
+$fa-var-credit-card: "\f09d";
+$fa-var-credit-card-alt: "\f283";
+$fa-var-crop: "\f125";
+$fa-var-crosshairs: "\f05b";
+$fa-var-css3: "\f13c";
+$fa-var-cube: "\f1b2";
+$fa-var-cubes: "\f1b3";
+$fa-var-cut: "\f0c4";
+$fa-var-cutlery: "\f0f5";
+$fa-var-dashboard: "\f0e4";
+$fa-var-dashcube: "\f210";
+$fa-var-database: "\f1c0";
+$fa-var-dedent: "\f03b";
+$fa-var-delicious: "\f1a5";
+$fa-var-desktop: "\f108";
+$fa-var-deviantart: "\f1bd";
+$fa-var-diamond: "\f219";
+$fa-var-digg: "\f1a6";
+$fa-var-dollar: "\f155";
+$fa-var-dot-circle-o: "\f192";
+$fa-var-download: "\f019";
+$fa-var-dribbble: "\f17d";
+$fa-var-dropbox: "\f16b";
+$fa-var-drupal: "\f1a9";
+$fa-var-edge: "\f282";
+$fa-var-edit: "\f044";
+$fa-var-eject: "\f052";
+$fa-var-ellipsis-h: "\f141";
+$fa-var-ellipsis-v: "\f142";
+$fa-var-empire: "\f1d1";
+$fa-var-envelope: "\f0e0";
+$fa-var-envelope-o: "\f003";
+$fa-var-envelope-square: "\f199";
+$fa-var-eraser: "\f12d";
+$fa-var-eur: "\f153";
+$fa-var-euro: "\f153";
+$fa-var-exchange: "\f0ec";
+$fa-var-exclamation: "\f12a";
+$fa-var-exclamation-circle: "\f06a";
+$fa-var-exclamation-triangle: "\f071";
+$fa-var-expand: "\f065";
+$fa-var-expeditedssl: "\f23e";
+$fa-var-external-link: "\f08e";
+$fa-var-external-link-square: "\f14c";
+$fa-var-eye: "\f06e";
+$fa-var-eye-slash: "\f070";
+$fa-var-eyedropper: "\f1fb";
+$fa-var-facebook: "\f09a";
+$fa-var-facebook-f: "\f09a";
+$fa-var-facebook-official: "\f230";
+$fa-var-facebook-square: "\f082";
+$fa-var-fast-backward: "\f049";
+$fa-var-fast-forward: "\f050";
+$fa-var-fax: "\f1ac";
+$fa-var-feed: "\f09e";
+$fa-var-female: "\f182";
+$fa-var-fighter-jet: "\f0fb";
+$fa-var-file: "\f15b";
+$fa-var-file-archive-o: "\f1c6";
+$fa-var-file-audio-o: "\f1c7";
+$fa-var-file-code-o: "\f1c9";
+$fa-var-file-excel-o: "\f1c3";
+$fa-var-file-image-o: "\f1c5";
+$fa-var-file-movie-o: "\f1c8";
+$fa-var-file-o: "\f016";
+$fa-var-file-pdf-o: "\f1c1";
+$fa-var-file-photo-o: "\f1c5";
+$fa-var-file-picture-o: "\f1c5";
+$fa-var-file-powerpoint-o: "\f1c4";
+$fa-var-file-sound-o: "\f1c7";
+$fa-var-file-text: "\f15c";
+$fa-var-file-text-o: "\f0f6";
+$fa-var-file-video-o: "\f1c8";
+$fa-var-file-word-o: "\f1c2";
+$fa-var-file-zip-o: "\f1c6";
+$fa-var-files-o: "\f0c5";
+$fa-var-film: "\f008";
+$fa-var-filter: "\f0b0";
+$fa-var-fire: "\f06d";
+$fa-var-fire-extinguisher: "\f134";
+$fa-var-firefox: "\f269";
+$fa-var-flag: "\f024";
+$fa-var-flag-checkered: "\f11e";
+$fa-var-flag-o: "\f11d";
+$fa-var-flash: "\f0e7";
+$fa-var-flask: "\f0c3";
+$fa-var-flickr: "\f16e";
+$fa-var-floppy-o: "\f0c7";
+$fa-var-folder: "\f07b";
+$fa-var-folder-o: "\f114";
+$fa-var-folder-open: "\f07c";
+$fa-var-folder-open-o: "\f115";
+$fa-var-font: "\f031";
+$fa-var-fonticons: "\f280";
+$fa-var-fort-awesome: "\f286";
+$fa-var-forumbee: "\f211";
+$fa-var-forward: "\f04e";
+$fa-var-foursquare: "\f180";
+$fa-var-frown-o: "\f119";
+$fa-var-futbol-o: "\f1e3";
+$fa-var-gamepad: "\f11b";
+$fa-var-gavel: "\f0e3";
+$fa-var-gbp: "\f154";
+$fa-var-ge: "\f1d1";
+$fa-var-gear: "\f013";
+$fa-var-gears: "\f085";
+$fa-var-genderless: "\f22d";
+$fa-var-get-pocket: "\f265";
+$fa-var-gg: "\f260";
+$fa-var-gg-circle: "\f261";
+$fa-var-gift: "\f06b";
+$fa-var-git: "\f1d3";
+$fa-var-git-square: "\f1d2";
+$fa-var-github: "\f09b";
+$fa-var-github-alt: "\f113";
+$fa-var-github-square: "\f092";
+$fa-var-gittip: "\f184";
+$fa-var-glass: "\f000";
+$fa-var-globe: "\f0ac";
+$fa-var-google: "\f1a0";
+$fa-var-google-plus: "\f0d5";
+$fa-var-google-plus-square: "\f0d4";
+$fa-var-google-wallet: "\f1ee";
+$fa-var-graduation-cap: "\f19d";
+$fa-var-gratipay: "\f184";
+$fa-var-group: "\f0c0";
+$fa-var-h-square: "\f0fd";
+$fa-var-hacker-news: "\f1d4";
+$fa-var-hand-grab-o: "\f255";
+$fa-var-hand-lizard-o: "\f258";
+$fa-var-hand-o-down: "\f0a7";
+$fa-var-hand-o-left: "\f0a5";
+$fa-var-hand-o-right: "\f0a4";
+$fa-var-hand-o-up: "\f0a6";
+$fa-var-hand-paper-o: "\f256";
+$fa-var-hand-peace-o: "\f25b";
+$fa-var-hand-pointer-o: "\f25a";
+$fa-var-hand-rock-o: "\f255";
+$fa-var-hand-scissors-o: "\f257";
+$fa-var-hand-spock-o: "\f259";
+$fa-var-hand-stop-o: "\f256";
+$fa-var-hashtag: "\f292";
+$fa-var-hdd-o: "\f0a0";
+$fa-var-header: "\f1dc";
+$fa-var-headphones: "\f025";
+$fa-var-heart: "\f004";
+$fa-var-heart-o: "\f08a";
+$fa-var-heartbeat: "\f21e";
+$fa-var-history: "\f1da";
+$fa-var-home: "\f015";
+$fa-var-hospital-o: "\f0f8";
+$fa-var-hotel: "\f236";
+$fa-var-hourglass: "\f254";
+$fa-var-hourglass-1: "\f251";
+$fa-var-hourglass-2: "\f252";
+$fa-var-hourglass-3: "\f253";
+$fa-var-hourglass-end: "\f253";
+$fa-var-hourglass-half: "\f252";
+$fa-var-hourglass-o: "\f250";
+$fa-var-hourglass-start: "\f251";
+$fa-var-houzz: "\f27c";
+$fa-var-html5: "\f13b";
+$fa-var-i-cursor: "\f246";
+$fa-var-ils: "\f20b";
+$fa-var-image: "\f03e";
+$fa-var-inbox: "\f01c";
+$fa-var-indent: "\f03c";
+$fa-var-industry: "\f275";
+$fa-var-info: "\f129";
+$fa-var-info-circle: "\f05a";
+$fa-var-inr: "\f156";
+$fa-var-instagram: "\f16d";
+$fa-var-institution: "\f19c";
+$fa-var-internet-explorer: "\f26b";
+$fa-var-intersex: "\f224";
+$fa-var-ioxhost: "\f208";
+$fa-var-italic: "\f033";
+$fa-var-joomla: "\f1aa";
+$fa-var-jpy: "\f157";
+$fa-var-jsfiddle: "\f1cc";
+$fa-var-key: "\f084";
+$fa-var-keyboard-o: "\f11c";
+$fa-var-krw: "\f159";
+$fa-var-language: "\f1ab";
+$fa-var-laptop: "\f109";
+$fa-var-lastfm: "\f202";
+$fa-var-lastfm-square: "\f203";
+$fa-var-leaf: "\f06c";
+$fa-var-leanpub: "\f212";
+$fa-var-legal: "\f0e3";
+$fa-var-lemon-o: "\f094";
+$fa-var-level-down: "\f149";
+$fa-var-level-up: "\f148";
+$fa-var-life-bouy: "\f1cd";
+$fa-var-life-buoy: "\f1cd";
+$fa-var-life-ring: "\f1cd";
+$fa-var-life-saver: "\f1cd";
+$fa-var-lightbulb-o: "\f0eb";
+$fa-var-line-chart: "\f201";
+$fa-var-link: "\f0c1";
+$fa-var-linkedin: "\f0e1";
+$fa-var-linkedin-square: "\f08c";
+$fa-var-linux: "\f17c";
+$fa-var-list: "\f03a";
+$fa-var-list-alt: "\f022";
+$fa-var-list-ol: "\f0cb";
+$fa-var-list-ul: "\f0ca";
+$fa-var-location-arrow: "\f124";
+$fa-var-lock: "\f023";
+$fa-var-long-arrow-down: "\f175";
+$fa-var-long-arrow-left: "\f177";
+$fa-var-long-arrow-right: "\f178";
+$fa-var-long-arrow-up: "\f176";
+$fa-var-magic: "\f0d0";
+$fa-var-magnet: "\f076";
+$fa-var-mail-forward: "\f064";
+$fa-var-mail-reply: "\f112";
+$fa-var-mail-reply-all: "\f122";
+$fa-var-male: "\f183";
+$fa-var-map: "\f279";
+$fa-var-map-marker: "\f041";
+$fa-var-map-o: "\f278";
+$fa-var-map-pin: "\f276";
+$fa-var-map-signs: "\f277";
+$fa-var-mars: "\f222";
+$fa-var-mars-double: "\f227";
+$fa-var-mars-stroke: "\f229";
+$fa-var-mars-stroke-h: "\f22b";
+$fa-var-mars-stroke-v: "\f22a";
+$fa-var-maxcdn: "\f136";
+$fa-var-meanpath: "\f20c";
+$fa-var-medium: "\f23a";
+$fa-var-medkit: "\f0fa";
+$fa-var-meh-o: "\f11a";
+$fa-var-mercury: "\f223";
+$fa-var-microphone: "\f130";
+$fa-var-microphone-slash: "\f131";
+$fa-var-minus: "\f068";
+$fa-var-minus-circle: "\f056";
+$fa-var-minus-square: "\f146";
+$fa-var-minus-square-o: "\f147";
+$fa-var-mixcloud: "\f289";
+$fa-var-mobile: "\f10b";
+$fa-var-mobile-phone: "\f10b";
+$fa-var-modx: "\f285";
+$fa-var-money: "\f0d6";
+$fa-var-moon-o: "\f186";
+$fa-var-mortar-board: "\f19d";
+$fa-var-motorcycle: "\f21c";
+$fa-var-mouse-pointer: "\f245";
+$fa-var-music: "\f001";
+$fa-var-navicon: "\f0c9";
+$fa-var-neuter: "\f22c";
+$fa-var-newspaper-o: "\f1ea";
+$fa-var-object-group: "\f247";
+$fa-var-object-ungroup: "\f248";
+$fa-var-odnoklassniki: "\f263";
+$fa-var-odnoklassniki-square: "\f264";
+$fa-var-opencart: "\f23d";
+$fa-var-openid: "\f19b";
+$fa-var-opera: "\f26a";
+$fa-var-optin-monster: "\f23c";
+$fa-var-outdent: "\f03b";
+$fa-var-pagelines: "\f18c";
+$fa-var-paint-brush: "\f1fc";
+$fa-var-paper-plane: "\f1d8";
+$fa-var-paper-plane-o: "\f1d9";
+$fa-var-paperclip: "\f0c6";
+$fa-var-paragraph: "\f1dd";
+$fa-var-paste: "\f0ea";
+$fa-var-pause: "\f04c";
+$fa-var-pause-circle: "\f28b";
+$fa-var-pause-circle-o: "\f28c";
+$fa-var-paw: "\f1b0";
+$fa-var-paypal: "\f1ed";
+$fa-var-pencil: "\f040";
+$fa-var-pencil-square: "\f14b";
+$fa-var-pencil-square-o: "\f044";
+$fa-var-percent: "\f295";
+$fa-var-phone: "\f095";
+$fa-var-phone-square: "\f098";
+$fa-var-photo: "\f03e";
+$fa-var-picture-o: "\f03e";
+$fa-var-pie-chart: "\f200";
+$fa-var-pied-piper: "\f1a7";
+$fa-var-pied-piper-alt: "\f1a8";
+$fa-var-pinterest: "\f0d2";
+$fa-var-pinterest-p: "\f231";
+$fa-var-pinterest-square: "\f0d3";
+$fa-var-plane: "\f072";
+$fa-var-play: "\f04b";
+$fa-var-play-circle: "\f144";
+$fa-var-play-circle-o: "\f01d";
+$fa-var-plug: "\f1e6";
+$fa-var-plus: "\f067";
+$fa-var-plus-circle: "\f055";
+$fa-var-plus-square: "\f0fe";
+$fa-var-plus-square-o: "\f196";
+$fa-var-power-off: "\f011";
+$fa-var-print: "\f02f";
+$fa-var-product-hunt: "\f288";
+$fa-var-puzzle-piece: "\f12e";
+$fa-var-qq: "\f1d6";
+$fa-var-qrcode: "\f029";
+$fa-var-question: "\f128";
+$fa-var-question-circle: "\f059";
+$fa-var-quote-left: "\f10d";
+$fa-var-quote-right: "\f10e";
+$fa-var-ra: "\f1d0";
+$fa-var-random: "\f074";
+$fa-var-rebel: "\f1d0";
+$fa-var-recycle: "\f1b8";
+$fa-var-reddit: "\f1a1";
+$fa-var-reddit-alien: "\f281";
+$fa-var-reddit-square: "\f1a2";
+$fa-var-refresh: "\f021";
+$fa-var-registered: "\f25d";
+$fa-var-remove: "\f00d";
+$fa-var-renren: "\f18b";
+$fa-var-reorder: "\f0c9";
+$fa-var-repeat: "\f01e";
+$fa-var-reply: "\f112";
+$fa-var-reply-all: "\f122";
+$fa-var-retweet: "\f079";
+$fa-var-rmb: "\f157";
+$fa-var-road: "\f018";
+$fa-var-rocket: "\f135";
+$fa-var-rotate-left: "\f0e2";
+$fa-var-rotate-right: "\f01e";
+$fa-var-rouble: "\f158";
+$fa-var-rss: "\f09e";
+$fa-var-rss-square: "\f143";
+$fa-var-rub: "\f158";
+$fa-var-ruble: "\f158";
+$fa-var-rupee: "\f156";
+$fa-var-safari: "\f267";
+$fa-var-save: "\f0c7";
+$fa-var-scissors: "\f0c4";
+$fa-var-scribd: "\f28a";
+$fa-var-search: "\f002";
+$fa-var-search-minus: "\f010";
+$fa-var-search-plus: "\f00e";
+$fa-var-sellsy: "\f213";
+$fa-var-send: "\f1d8";
+$fa-var-send-o: "\f1d9";
+$fa-var-server: "\f233";
+$fa-var-share: "\f064";
+$fa-var-share-alt: "\f1e0";
+$fa-var-share-alt-square: "\f1e1";
+$fa-var-share-square: "\f14d";
+$fa-var-share-square-o: "\f045";
+$fa-var-shekel: "\f20b";
+$fa-var-sheqel: "\f20b";
+$fa-var-shield: "\f132";
+$fa-var-ship: "\f21a";
+$fa-var-shirtsinbulk: "\f214";
+$fa-var-shopping-bag: "\f290";
+$fa-var-shopping-basket: "\f291";
+$fa-var-shopping-cart: "\f07a";
+$fa-var-sign-in: "\f090";
+$fa-var-sign-out: "\f08b";
+$fa-var-signal: "\f012";
+$fa-var-simplybuilt: "\f215";
+$fa-var-sitemap: "\f0e8";
+$fa-var-skyatlas: "\f216";
+$fa-var-skype: "\f17e";
+$fa-var-slack: "\f198";
+$fa-var-sliders: "\f1de";
+$fa-var-slideshare: "\f1e7";
+$fa-var-smile-o: "\f118";
+$fa-var-soccer-ball-o: "\f1e3";
+$fa-var-sort: "\f0dc";
+$fa-var-sort-alpha-asc: "\f15d";
+$fa-var-sort-alpha-desc: "\f15e";
+$fa-var-sort-amount-asc: "\f160";
+$fa-var-sort-amount-desc: "\f161";
+$fa-var-sort-asc: "\f0de";
+$fa-var-sort-desc: "\f0dd";
+$fa-var-sort-down: "\f0dd";
+$fa-var-sort-numeric-asc: "\f162";
+$fa-var-sort-numeric-desc: "\f163";
+$fa-var-sort-up: "\f0de";
+$fa-var-soundcloud: "\f1be";
+$fa-var-space-shuttle: "\f197";
+$fa-var-spinner: "\f110";
+$fa-var-spoon: "\f1b1";
+$fa-var-spotify: "\f1bc";
+$fa-var-square: "\f0c8";
+$fa-var-square-o: "\f096";
+$fa-var-stack-exchange: "\f18d";
+$fa-var-stack-overflow: "\f16c";
+$fa-var-star: "\f005";
+$fa-var-star-half: "\f089";
+$fa-var-star-half-empty: "\f123";
+$fa-var-star-half-full: "\f123";
+$fa-var-star-half-o: "\f123";
+$fa-var-star-o: "\f006";
+$fa-var-steam: "\f1b6";
+$fa-var-steam-square: "\f1b7";
+$fa-var-step-backward: "\f048";
+$fa-var-step-forward: "\f051";
+$fa-var-stethoscope: "\f0f1";
+$fa-var-sticky-note: "\f249";
+$fa-var-sticky-note-o: "\f24a";
+$fa-var-stop: "\f04d";
+$fa-var-stop-circle: "\f28d";
+$fa-var-stop-circle-o: "\f28e";
+$fa-var-street-view: "\f21d";
+$fa-var-strikethrough: "\f0cc";
+$fa-var-stumbleupon: "\f1a4";
+$fa-var-stumbleupon-circle: "\f1a3";
+$fa-var-subscript: "\f12c";
+$fa-var-subway: "\f239";
+$fa-var-suitcase: "\f0f2";
+$fa-var-sun-o: "\f185";
+$fa-var-superscript: "\f12b";
+$fa-var-support: "\f1cd";
+$fa-var-table: "\f0ce";
+$fa-var-tablet: "\f10a";
+$fa-var-tachometer: "\f0e4";
+$fa-var-tag: "\f02b";
+$fa-var-tags: "\f02c";
+$fa-var-tasks: "\f0ae";
+$fa-var-taxi: "\f1ba";
+$fa-var-television: "\f26c";
+$fa-var-tencent-weibo: "\f1d5";
+$fa-var-terminal: "\f120";
+$fa-var-text-height: "\f034";
+$fa-var-text-width: "\f035";
+$fa-var-th: "\f00a";
+$fa-var-th-large: "\f009";
+$fa-var-th-list: "\f00b";
+$fa-var-thumb-tack: "\f08d";
+$fa-var-thumbs-down: "\f165";
+$fa-var-thumbs-o-down: "\f088";
+$fa-var-thumbs-o-up: "\f087";
+$fa-var-thumbs-up: "\f164";
+$fa-var-ticket: "\f145";
+$fa-var-times: "\f00d";
+$fa-var-times-circle: "\f057";
+$fa-var-times-circle-o: "\f05c";
+$fa-var-tint: "\f043";
+$fa-var-toggle-down: "\f150";
+$fa-var-toggle-left: "\f191";
+$fa-var-toggle-off: "\f204";
+$fa-var-toggle-on: "\f205";
+$fa-var-toggle-right: "\f152";
+$fa-var-toggle-up: "\f151";
+$fa-var-trademark: "\f25c";
+$fa-var-train: "\f238";
+$fa-var-transgender: "\f224";
+$fa-var-transgender-alt: "\f225";
+$fa-var-trash: "\f1f8";
+$fa-var-trash-o: "\f014";
+$fa-var-tree: "\f1bb";
+$fa-var-trello: "\f181";
+$fa-var-tripadvisor: "\f262";
+$fa-var-trophy: "\f091";
+$fa-var-truck: "\f0d1";
+$fa-var-try: "\f195";
+$fa-var-tty: "\f1e4";
+$fa-var-tumblr: "\f173";
+$fa-var-tumblr-square: "\f174";
+$fa-var-turkish-lira: "\f195";
+$fa-var-tv: "\f26c";
+$fa-var-twitch: "\f1e8";
+$fa-var-twitter: "\f099";
+$fa-var-twitter-square: "\f081";
+$fa-var-umbrella: "\f0e9";
+$fa-var-underline: "\f0cd";
+$fa-var-undo: "\f0e2";
+$fa-var-university: "\f19c";
+$fa-var-unlink: "\f127";
+$fa-var-unlock: "\f09c";
+$fa-var-unlock-alt: "\f13e";
+$fa-var-unsorted: "\f0dc";
+$fa-var-upload: "\f093";
+$fa-var-usb: "\f287";
+$fa-var-usd: "\f155";
+$fa-var-user: "\f007";
+$fa-var-user-md: "\f0f0";
+$fa-var-user-plus: "\f234";
+$fa-var-user-secret: "\f21b";
+$fa-var-user-times: "\f235";
+$fa-var-users: "\f0c0";
+$fa-var-venus: "\f221";
+$fa-var-venus-double: "\f226";
+$fa-var-venus-mars: "\f228";
+$fa-var-viacoin: "\f237";
+$fa-var-video-camera: "\f03d";
+$fa-var-vimeo: "\f27d";
+$fa-var-vimeo-square: "\f194";
+$fa-var-vine: "\f1ca";
+$fa-var-vk: "\f189";
+$fa-var-volume-down: "\f027";
+$fa-var-volume-off: "\f026";
+$fa-var-volume-up: "\f028";
+$fa-var-warning: "\f071";
+$fa-var-wechat: "\f1d7";
+$fa-var-weibo: "\f18a";
+$fa-var-weixin: "\f1d7";
+$fa-var-whatsapp: "\f232";
+$fa-var-wheelchair: "\f193";
+$fa-var-wifi: "\f1eb";
+$fa-var-wikipedia-w: "\f266";
+$fa-var-windows: "\f17a";
+$fa-var-won: "\f159";
+$fa-var-wordpress: "\f19a";
+$fa-var-wrench: "\f0ad";
+$fa-var-xing: "\f168";
+$fa-var-xing-square: "\f169";
+$fa-var-y-combinator: "\f23b";
+$fa-var-y-combinator-square: "\f1d4";
+$fa-var-yahoo: "\f19e";
+$fa-var-yc: "\f23b";
+$fa-var-yc-square: "\f1d4";
+$fa-var-yelp: "\f1e9";
+$fa-var-yen: "\f157";
+$fa-var-youtube: "\f167";
+$fa-var-youtube-play: "\f16a";
+$fa-var-youtube-square: "\f166";
+

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/font-awesome.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/font-awesome.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/font-awesome.scss
new file mode 100644
index 0000000..f4668a5
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/font-awesome.scss
@@ -0,0 +1,17 @@
+/*!
+ *  Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables";
+@import "mixins";
+@import "path";
+@import "core";
+@import "larger";
+@import "fixed-width";
+@import "list";
+@import "bordered-pulled";
+@import "animated";
+@import "rotated-flipped";
+@import "stacked";
+@import "icons";

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/index.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html
index 3570ca9..4652377 100644
--- a/src/main/webapp/index.html
+++ b/src/main/webapp/index.html
@@ -28,6 +28,7 @@
 
     <link rel="stylesheet" href="/assets/css/codemirror.css">
     <link rel="stylesheet" href="/assets/css/codemirror-brooklyn.css">
+    <link rel="stylesheet" href="/assets/js/libs/font-awesome/css/font-awesome.css">
     <link rel="stylesheet" href="/assets/css/show-hint.css">
     <link rel="stylesheet" href="/assets/css/styles.css">
     <link rel="stylesheet" href="/assets/css/brooklyn.css">


[02/27] brooklyn-ui git commit: a bunch more buttons for the composer

Posted by he...@apache.org.
a bunch more buttons for the composer


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/d67739c8
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/d67739c8
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/d67739c8

Branch: refs/heads/master
Commit: d67739c82e62025fed2a3d170fe254b4b744d89e
Parents: 6120199
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 16:03:42 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/js/view/editor.js    | 106 ++++++++++++++++++++---
 src/main/webapp/assets/tpl/editor/page.html |   8 +-
 2 files changed, 99 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d67739c8/src/main/webapp/assets/js/view/editor.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/editor.js b/src/main/webapp/assets/js/view/editor.js
index fa893fc..1b4dce3 100644
--- a/src/main/webapp/assets/js/view/editor.js
+++ b/src/main/webapp/assets/js/view/editor.js
@@ -60,6 +60,9 @@ define([
         events: {
             'click #button-run':'runBlueprint',
             'click #button-delete':'removeBlueprint',
+            'click #button-convert':'convertBlueprint',
+            'click #button-switch':'switchMode',
+            'click #button-example':'populateExampleBlueprint',
         },
         editorTemplate:_.template(EditorHtml),
 
@@ -79,7 +82,7 @@ define([
             this.options.catalog.fetch({
                 data: $.param({allVersions: true}),
                 success: function () {
-                    vm.refreshEditor();
+                    vm.initializeEditor();
                 }
             });
         },
@@ -97,11 +100,41 @@ define([
         refresh: function() {
             $("#button-run", this.$el).html(this.mode==MODE_CATALOG ? "Add to Catalog" : "Deploy");
             $("#button-delete", this.$el).html("Clear");
+            $("#button-example", this.$el).html(this.mode==MODE_CATALOG ? "Insert Catalog Example" : "Insert Blueprint Example");
+            $("#button-switch", this.$el).html(this.mode==MODE_CATALOG ? "Switch to Application Blueprint Mode" : "Switch to Catalog Mode");
+            this.refreshOnMinorChange();
         },
-        refreshEditor: function() {
+        refreshOnMinorChange: function() {
+            var yaml = this.editor && this.editor.getValue();
+            var parse = this.parse();
+            
+            if (!yaml || parse.problem || this.mode==MODE_CATALOG) {
+                $("#button-convert", this.$el).hide();
+            } else {
+                $("#button-convert", this.$el).html("Convert to Catalog Item");
+                $("#button-convert", this.$el).show();
+            }
+            
+            if (!yaml) {
+                // no yaml
+                $("#button-run", this.$el).attr('disabled','disabled');
+                $("#button-delete", this.$el).hide();
+                // example and switch mode only shown when empty
+                $("#button-example", this.$el).show();
+                $("#button-switch", this.$el).show();
+            } else {
+                $("#button-run", this.$el).attr('disabled','false');
+                // we have yaml
+                $("#button-run", this.$el).show();
+                $("#button-delete", this.$el).show();
+                $("#button-example", this.$el).hide();
+                $("#button-switch", this.$el).hide();
+            }
+        },
+        initializeEditor: function() {
             var cm = this.editor;
             if (typeof(cm) !== "undefined") {
-                var itemText;
+                var itemText = "";
                 if (this.options.typeId === '_') {
                     // _ indicates a literal is being supplied
                     itemText = this.options.content;
@@ -119,14 +152,10 @@ define([
                         }
                     }
                 }
+                cm.getDoc().setValue(itemText);
                 if (!itemText) {
-                    if (this.options.type === 'catalog') {
-                        itemText = _DEFAULT_CATALOG;
-                    } else {
-                        itemText = _DEFAULT_BLUEPRINT;
-                    }
+                    // could populateExampleBlueprint -- but now that is opt-in                    
                 }
-                cm.getDoc().setValue(itemText);
                 //better not to focus as focussing puts the cursor at the beginning which is odd
                 //and cmd-shift-[ and tab are intercepted so user can't navigate
                 // cm.focus();
@@ -144,20 +173,65 @@ define([
                         globalVars: true
                     }
                 });
+                var that = this;
+                this.editor.on("changes", function(editor, changes) {
+                    console.log("editor changed", editor, changes);
+                    that.refreshOnMinorChange();
+                });
             }
 
-            this.refreshEditor();
+            this.initializeEditor();
+        },
+        parse: function(forceRefresh) {
+            if (!forceRefresh && this.lastParse && this.lastParse.input === this.editor.getValue()) {
+                // up to date
+                return this.lastParse;
+            }
+            
+            if (!this.editor) {
+                this.lastParse = { problem: "no editor yet" };
+            } else {
+                this.lastParse = { input: this.editor.getValue() };
+                try {
+                    // TODO use new listener for the parser to get tree w parsing info
+                    this.lastParse.result = jsYaml.safeLoad(this.editor.getValue());
+                } catch (e) {
+                    this.lastParse.problem = e;
+                }
+            }
+            return this.lastParse;
         },
         validate: function() {
             var yaml = this.editor.getValue();
             try{
-                jsYaml.safeLoad(yaml);
+                var parsed = this.parse(true);
+                if (parsed.problem) throw parsed.problem;
                 return true;
             }catch (e){
                 this.showFailure(e.message);
                 return false;
             }
         },
+        convertBlueprint: function() {
+            if (this.mode === MODE_CATALOG) {
+                // not yet supported
+            } else {
+                var newBlueprint = "brooklyn.catalog:\n"+
+                    "  version: 0.0.1\n"+
+                    "    items:\n"+
+                    "    - id: TODO_identifier_for_this_item \n"+
+                    "      description: Some text to display about this\n"+
+                    "      iconUrl: http://www.apache.org/foundation/press/kit/poweredBy/Apache_PoweredBy.png\n"+
+                    "      itemType: template\n"+
+                    "      item:\n"+
+                    "      - \n"+
+                    // indent 8 spaces:
+                    this.editor.getValue().replace(/(\n|^)(.*\n|.+$)/gm,'        $1$2');
+                this.mode = MODE_CATALOG;
+                this.editor.setValue(newBlueprint);
+                this.refresh();
+            }
+        },
         runBlueprint: function() {
             if (this.validate()){
                 if (this.mode === MODE_CATALOG) {
@@ -168,9 +242,15 @@ define([
             }
         },
         removeBlueprint: function() {
-            this.refreshEditor();
-
+            this.initializeEditor();
+        },
+        switchMode: function() {
+            this.setMode(this.mode == MODE_CATALOG ? MODE_APP : MODE_CATALOG);
         },
+        populateExampleBlueprint: function() {
+            this.editor.setValue(this.mode==MODE_CATALOG ? _DEFAULT_CATALOG : _DEFAULT_BLUEPRINT);
+        },
+        
         onSubmissionComplete: function(succeeded, data, type) {
             var that = this;
             if(succeeded){

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d67739c8/src/main/webapp/assets/tpl/editor/page.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/editor/page.html b/src/main/webapp/assets/tpl/editor/page.html
index 727b4d4..fb4410b 100644
--- a/src/main/webapp/assets/tpl/editor/page.html
+++ b/src/main/webapp/assets/tpl/editor/page.html
@@ -22,9 +22,13 @@ under the License.
             <div class="navbar_top">
                 <h3 style="margin-top: 6px;">Blueprint Composer</h3>
                 <div class="apps-tree-toolbar" style="margin-top: -24px !important;">
-                    <!-- will be renamed -->
-                    <button id="button-run" class="btn btn-success btn-sm">Run</button>
+                    <!-- text will be changed by JS -->
+                    <button id="button-convert" class="btn btn-sm">Convert</button>
+                    <button id="button-switch" class="btn btn-sm">Switch</button>
+                    <button id="button-example" class="btn btn-sm">Insert Example</button>
                     <button id="button-delete" class="btn btn-danger btn-sm">Clear</button>
+                    
+                    <button id="button-run" class="btn btn-success btn-sm" style="margin-left: 36px;">Run</button>
                 </div>
             </div>
             <div class="navbar_main_wrapper">


[27/27] brooklyn-ui git commit: apply code review to ui #7 codemirror yaml-parse and completion

Posted by he...@apache.org.
apply code review to ui #7 codemirror yaml-parse and completion

and some styling tweaks so highlight is correct


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/b9ba6544
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/b9ba6544
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/b9ba6544

Branch: refs/heads/master
Commit: b9ba6544dd0a4a8fec6519ab6b3145f7956ad578
Parents: e1646d7
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 18 10:36:23 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 18 10:36:23 2016 +0000

----------------------------------------------------------------------
 .../webapp/assets/css/codemirror-brooklyn.css   | 21 ++++++++++++++------
 .../brooklyn-yaml-completion-proposals.js       | 16 ++++++++++-----
 .../js/util/code-complete/js-yaml-parser.js     |  5 +++++
 src/main/webapp/index.html                      |  2 +-
 4 files changed, 32 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/b9ba6544/src/main/webapp/assets/css/codemirror-brooklyn.css
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/css/codemirror-brooklyn.css b/src/main/webapp/assets/css/codemirror-brooklyn.css
index b1b2c54..e751df3 100644
--- a/src/main/webapp/assets/css/codemirror-brooklyn.css
+++ b/src/main/webapp/assets/css/codemirror-brooklyn.css
@@ -28,16 +28,25 @@
 .CodeMirror .CodeMirror-gutter.CodeMirror-linenumbers {
 }
 
+ul.CodeMirror-hints {
+  overflow: scroll;
+  width: 320px;
+}
 li.CodeMirror-hint {
   max-width: inherit;
   overflow: visible;
+  /* nice trick: table has stretchability based on content (line inline) but otherwise acts like div 
+   * (following content is not on same line). this causes wide (overflow) content to get the right background when active;
+   * otherwise with div the content is shown but background only applies to non-overflow part. */
+  display: table;
+  /* but width of table defaults to ignoring padding so we have to fix it to be parent's less padding */ 
+  min-width: 312px;
 }
-ul.CodeMirror-hints {
-  overflow: scroll;
-  max-width: 30em;
-}
-
 .CodeMirror-hints .CodeMirror-hint.summary {
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   font-style: italic;
-}
\ No newline at end of file
+}
+li.CodeMirror-hint-active {
+  /* override show-hint to have roughly brooklyn colors instead of blue */
+  background: #549e2b;
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/b9ba6544/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js b/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
index 3dfecd7..e183411 100644
--- a/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
+++ b/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
@@ -56,14 +56,20 @@ define([
         
         if (n.result === null) {
             n.type = 'null';
-        } else if (typeof n.result === 'object') {
+        } else if (n.kind == 'sequence') {
+            if (typeof n.result.length === 'undefined') {
+                console.log("WARN: mismatch expected list but had no length", n);
+            }
+            n.type = 'list';
+        } else if (n.kind == 'mapping') {
             if (typeof n.result.length !== 'undefined') {
-                // ^^^ messy way to check is parent a list
-                n.type = 'list';
-            } else {
-                n.type = 'map';
+                console.log("WARN: mismatch expected map but had length", n);
             }
+            n.type = 'map';
         } else {
+            if (n.kind != 'scalar') {
+                console.log("WARN: mismatch expected scalar/primitive", n);
+            }
             n.type = 'primitive';
         }
         

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/b9ba6544/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js b/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js
index 98092f0..b95ebe0 100644
--- a/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js
+++ b/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js
@@ -18,8 +18,13 @@ define([
     }
 
     function closeYamlNode(node, state) {
+        // character offset where this block ends, i.e. 1 means after the first character
+        // NB: if parser unsure may contain additional whitespace
         node.end = state.position;
+        // the actual parsed object
         node.result = state.result;
+        // {mapping,scalar,sequence}
+        node.kind = state.kind;
     }
 
     /** returns a YamlParseNode containing { doc, parent, children, start, end, result } */ 

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/b9ba6544/src/main/webapp/index.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html
index 4652377..b554599 100644
--- a/src/main/webapp/index.html
+++ b/src/main/webapp/index.html
@@ -27,10 +27,10 @@
     <title>Brooklyn JS REST client</title>
 
     <link rel="stylesheet" href="/assets/css/codemirror.css">
-    <link rel="stylesheet" href="/assets/css/codemirror-brooklyn.css">
     <link rel="stylesheet" href="/assets/js/libs/font-awesome/css/font-awesome.css">
     <link rel="stylesheet" href="/assets/css/show-hint.css">
     <link rel="stylesheet" href="/assets/css/styles.css">
+    <link rel="stylesheet" href="/assets/css/codemirror-brooklyn.css">
     <link rel="stylesheet" href="/assets/css/brooklyn.css">
     <style>
         body {


[12/27] brooklyn-ui git commit: move codemirror libraries to the usual places

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/libs/codemirror/addon/display/placeholder.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/codemirror/addon/display/placeholder.js b/src/main/webapp/assets/js/libs/codemirror/addon/display/placeholder.js
new file mode 100644
index 0000000..ba6c096
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/codemirror/addon/display/placeholder.js
@@ -0,0 +1,60 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
+    var prev = old && old != CodeMirror.Init;
+    if (val && !prev) {
+      cm.on("blur", onBlur);
+      cm.on("change", onChange);
+      onChange(cm);
+    } else if (!val && prev) {
+      cm.off("blur", onBlur);
+      cm.off("change", onChange);
+      clearPlaceholder(cm);
+      var wrapper = cm.getWrapperElement();
+      wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
+    }
+
+    if (val && !cm.hasFocus()) onBlur(cm);
+  });
+
+  function clearPlaceholder(cm) {
+    if (cm.state.placeholder) {
+      cm.state.placeholder.parentNode.removeChild(cm.state.placeholder);
+      cm.state.placeholder = null;
+    }
+  }
+  function setPlaceholder(cm) {
+    clearPlaceholder(cm);
+    var elt = cm.state.placeholder = document.createElement("pre");
+    elt.style.cssText = "height: 0; overflow: visible";
+    elt.className = "CodeMirror-placeholder";
+    var placeHolder = cm.getOption("placeholder")
+    if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
+    elt.appendChild(placeHolder)
+    cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
+  }
+
+  function onBlur(cm) {
+    if (isEmpty(cm)) setPlaceholder(cm);
+  }
+  function onChange(cm) {
+    var wrapper = cm.getWrapperElement(), empty = isEmpty(cm);
+    wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : "");
+
+    if (empty) setPlaceholder(cm);
+    else clearPlaceholder(cm);
+  }
+
+  function isEmpty(cm) {
+    return (cm.lineCount() === 1) && (cm.getLine(0) === "");
+  }
+});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/libs/codemirror/addon/hint/anyword-hint.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/codemirror/addon/hint/anyword-hint.js b/src/main/webapp/assets/js/libs/codemirror/addon/hint/anyword-hint.js
new file mode 100644
index 0000000..ade4274
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/codemirror/addon/hint/anyword-hint.js
@@ -0,0 +1,41 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var WORD = /[\w$]+/, RANGE = 500;
+
+  CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
+    var word = options && options.word || WORD;
+    var range = options && options.range || RANGE;
+    var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
+    var end = cur.ch, start = end;
+    while (start && word.test(curLine.charAt(start - 1))) --start;
+    var curWord = start != end && curLine.slice(start, end);
+
+    var list = options && options.list || [], seen = {};
+    var re = new RegExp(word.source, "g");
+    for (var dir = -1; dir <= 1; dir += 2) {
+      var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
+      for (; line != endLine; line += dir) {
+        var text = editor.getLine(line), m;
+        while (m = re.exec(text)) {
+          if (line == cur.line && m[0] === curWord) continue;
+          if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
+            seen[m[0]] = true;
+            list.push(m[0]);
+          }
+        }
+      }
+    }
+    return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
+  });
+});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/libs/codemirror/addon/hint/show-hint.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/codemirror/addon/hint/show-hint.js b/src/main/webapp/assets/js/libs/codemirror/addon/hint/show-hint.js
new file mode 100644
index 0000000..fa27867
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/codemirror/addon/hint/show-hint.js
@@ -0,0 +1,386 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
+  var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
+
+  // This is the old interface, kept around for now to stay
+  // backwards-compatible.
+  CodeMirror.showHint = function(cm, getHints, options) {
+    if (!getHints) return cm.showHint(options);
+    if (options && options.async) getHints.async = true;
+    var newOpts = {hint: getHints};
+    if (options) for (var prop in options) newOpts[prop] = options[prop];
+    return cm.showHint(newOpts);
+  };
+
+  CodeMirror.defineExtension("showHint", function(options) {
+    // We want a single cursor position.
+    if (this.listSelections().length > 1 || this.somethingSelected()) return;
+
+    if (this.state.completionActive) this.state.completionActive.close();
+    var completion = this.state.completionActive = new Completion(this, options);
+    if (!completion.options.hint) return;
+
+    CodeMirror.signal(this, "startCompletion", this);
+    completion.update(true);
+  });
+
+  function Completion(cm, options) {
+    this.cm = cm;
+    this.options = this.buildOptions(options);
+    this.widget = null;
+    this.debounce = 0;
+    this.tick = 0;
+    this.startPos = this.cm.getCursor();
+    this.startLen = this.cm.getLine(this.startPos.line).length;
+
+    var self = this;
+    cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
+  }
+
+  var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
+    return setTimeout(fn, 1000/60);
+  };
+  var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
+
+  Completion.prototype = {
+    close: function() {
+      if (!this.active()) return;
+      this.cm.state.completionActive = null;
+      this.tick = null;
+      this.cm.off("cursorActivity", this.activityFunc);
+
+      if (this.widget && this.data) CodeMirror.signal(this.data, "close");
+      if (this.widget) this.widget.close();
+      CodeMirror.signal(this.cm, "endCompletion", this.cm);
+    },
+
+    active: function() {
+      return this.cm.state.completionActive == this;
+    },
+
+    pick: function(data, i) {
+      var completion = data.list[i];
+      if (completion.hint) completion.hint(this.cm, data, completion);
+      else this.cm.replaceRange(getText(completion), completion.from || data.from,
+                                completion.to || data.to, "complete");
+      CodeMirror.signal(data, "pick", completion);
+      this.close();
+    },
+
+    cursorActivity: function() {
+      if (this.debounce) {
+        cancelAnimationFrame(this.debounce);
+        this.debounce = 0;
+      }
+
+      var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
+      if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
+          pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
+          (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
+        this.close();
+      } else {
+        var self = this;
+        this.debounce = requestAnimationFrame(function() {self.update();});
+        if (this.widget) this.widget.disable();
+      }
+    },
+
+    update: function(first) {
+      if (this.tick == null) return;
+      if (!this.options.hint.async) {
+        this.finishUpdate(this.options.hint(this.cm, this.options), first);
+      } else {
+        var myTick = ++this.tick, self = this;
+        this.options.hint(this.cm, function(data) {
+          if (self.tick == myTick) self.finishUpdate(data, first);
+        }, this.options);
+      }
+    },
+
+    finishUpdate: function(data, first) {
+      if (this.data) CodeMirror.signal(this.data, "update");
+      if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;
+      this.data = data;
+
+      var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
+      if (this.widget) this.widget.close();
+      if (data && data.list.length) {
+        if (picked && data.list.length == 1) {
+          this.pick(data, 0);
+        } else {
+          this.widget = new Widget(this, data);
+          CodeMirror.signal(data, "shown");
+        }
+      }
+    },
+
+    buildOptions: function(options) {
+      var editor = this.cm.options.hintOptions;
+      var out = {};
+      for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
+      if (editor) for (var prop in editor)
+        if (editor[prop] !== undefined) out[prop] = editor[prop];
+      if (options) for (var prop in options)
+        if (options[prop] !== undefined) out[prop] = options[prop];
+      return out;
+    }
+  };
+
+  function getText(completion) {
+    if (typeof completion == "string") return completion;
+    else return completion.text;
+  }
+
+  function buildKeyMap(completion, handle) {
+    var baseMap = {
+      Up: function() {handle.moveFocus(-1);},
+      Down: function() {handle.moveFocus(1);},
+      PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
+      PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
+      Home: function() {handle.setFocus(0);},
+      End: function() {handle.setFocus(handle.length - 1);},
+      Enter: handle.pick,
+      Tab: handle.pick,
+      Esc: handle.close
+    };
+    var custom = completion.options.customKeys;
+    var ourMap = custom ? {} : baseMap;
+    function addBinding(key, val) {
+      var bound;
+      if (typeof val != "string")
+        bound = function(cm) { return val(cm, handle); };
+      // This mechanism is deprecated
+      else if (baseMap.hasOwnProperty(val))
+        bound = baseMap[val];
+      else
+        bound = val;
+      ourMap[key] = bound;
+    }
+    if (custom)
+      for (var key in custom) if (custom.hasOwnProperty(key))
+        addBinding(key, custom[key]);
+    var extra = completion.options.extraKeys;
+    if (extra)
+      for (var key in extra) if (extra.hasOwnProperty(key))
+        addBinding(key, extra[key]);
+    return ourMap;
+  }
+
+  function getHintElement(hintsElement, el) {
+    while (el && el != hintsElement) {
+      if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
+      el = el.parentNode;
+    }
+  }
+
+  function Widget(completion, data) {
+    this.completion = completion;
+    this.data = data;
+    this.picked = false;
+    var widget = this, cm = completion.cm;
+
+    var hints = this.hints = document.createElement("ul");
+    hints.className = "CodeMirror-hints";
+    this.selectedHint = data.selectedHint || 0;
+
+    var completions = data.list;
+    for (var i = 0; i < completions.length; ++i) {
+      var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
+      var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
+      if (cur.className != null) className = cur.className + " " + className;
+      elt.className = className;
+      if (cur.render) cur.render(elt, data, cur);
+      else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
+      elt.hintId = i;
+    }
+
+    var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
+    var left = pos.left, top = pos.bottom, below = true;
+    hints.style.left = left + "px";
+    hints.style.top = top + "px";
+    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
+    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
+    var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
+    (completion.options.container || document.body).appendChild(hints);
+    var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
+    if (overlapY > 0) {
+      var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
+      if (curTop - height > 0) { // Fits above cursor
+        hints.style.top = (top = pos.top - height) + "px";
+        below = false;
+      } else if (height > winH) {
+        hints.style.height = (winH - 5) + "px";
+        hints.style.top = (top = pos.bottom - box.top) + "px";
+        var cursor = cm.getCursor();
+        if (data.from.ch != cursor.ch) {
+          pos = cm.cursorCoords(cursor);
+          hints.style.left = (left = pos.left) + "px";
+          box = hints.getBoundingClientRect();
+        }
+      }
+    }
+    var overlapX = box.right - winW;
+    if (overlapX > 0) {
+      if (box.right - box.left > winW) {
+        hints.style.width = (winW - 5) + "px";
+        overlapX -= (box.right - box.left) - winW;
+      }
+      hints.style.left = (left = pos.left - overlapX) + "px";
+    }
+
+    cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
+      moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
+      setFocus: function(n) { widget.changeActive(n); },
+      menuSize: function() { return widget.screenAmount(); },
+      length: completions.length,
+      close: function() { completion.close(); },
+      pick: function() { widget.pick(); },
+      data: data
+    }));
+
+    if (completion.options.closeOnUnfocus) {
+      var closingOnBlur;
+      cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
+      cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
+    }
+
+    var startScroll = cm.getScrollInfo();
+    cm.on("scroll", this.onScroll = function() {
+      var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
+      var newTop = top + startScroll.top - curScroll.top;
+      var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
+      if (!below) point += hints.offsetHeight;
+      if (point <= editor.top || point >= editor.bottom) return completion.close();
+      hints.style.top = newTop + "px";
+      hints.style.left = (left + startScroll.left - curScroll.left) + "px";
+    });
+
+    CodeMirror.on(hints, "dblclick", function(e) {
+      var t = getHintElement(hints, e.target || e.srcElement);
+      if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
+    });
+
+    CodeMirror.on(hints, "click", function(e) {
+      var t = getHintElement(hints, e.target || e.srcElement);
+      if (t && t.hintId != null) {
+        widget.changeActive(t.hintId);
+        if (completion.options.completeOnSingleClick) widget.pick();
+      }
+    });
+
+    CodeMirror.on(hints, "mousedown", function() {
+      setTimeout(function(){cm.focus();}, 20);
+    });
+
+    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
+    return true;
+  }
+
+  Widget.prototype = {
+    close: function() {
+      if (this.completion.widget != this) return;
+      this.completion.widget = null;
+      this.hints.parentNode.removeChild(this.hints);
+      this.completion.cm.removeKeyMap(this.keyMap);
+
+      var cm = this.completion.cm;
+      if (this.completion.options.closeOnUnfocus) {
+        cm.off("blur", this.onBlur);
+        cm.off("focus", this.onFocus);
+      }
+      cm.off("scroll", this.onScroll);
+    },
+
+    disable: function() {
+      this.completion.cm.removeKeyMap(this.keyMap);
+      var widget = this;
+      this.keyMap = {Enter: function() { widget.picked = true; }};
+      this.completion.cm.addKeyMap(this.keyMap);
+    },
+
+    pick: function() {
+      this.completion.pick(this.data, this.selectedHint);
+    },
+
+    changeActive: function(i, avoidWrap) {
+      if (i >= this.data.list.length)
+        i = avoidWrap ? this.data.list.length - 1 : 0;
+      else if (i < 0)
+        i = avoidWrap ? 0  : this.data.list.length - 1;
+      if (this.selectedHint == i) return;
+      var node = this.hints.childNodes[this.selectedHint];
+      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
+      node = this.hints.childNodes[this.selectedHint = i];
+      node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
+      if (node.offsetTop < this.hints.scrollTop)
+        this.hints.scrollTop = node.offsetTop - 3;
+      else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
+        this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
+      CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
+    },
+
+    screenAmount: function() {
+      return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
+    }
+  };
+
+  CodeMirror.registerHelper("hint", "auto", function(cm, options) {
+    var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
+    if (helpers.length) {
+      for (var i = 0; i < helpers.length; i++) {
+        var cur = helpers[i](cm, options);
+        if (cur && cur.list.length) return cur;
+      }
+    } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
+      if (words) return CodeMirror.hint.fromList(cm, {words: words});
+    } else if (CodeMirror.hint.anyword) {
+      return CodeMirror.hint.anyword(cm, options);
+    }
+  });
+
+  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
+    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
+    var to = CodeMirror.Pos(cur.line, token.end);
+    if (token.string && /\w/.test(token.string[token.string.length - 1])) {
+      var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
+    } else {
+      var term = "", from = to;
+    }
+    var found = [];
+    for (var i = 0; i < options.words.length; i++) {
+      var word = options.words[i];
+      if (word.slice(0, term.length) == term)
+        found.push(word);
+    }
+
+    if (found.length) return {list: found, from: from, to: to};
+  });
+
+  CodeMirror.commands.autocomplete = CodeMirror.showHint;
+
+  var defaultOptions = {
+    hint: CodeMirror.hint.auto,
+    completeSingle: true,
+    alignWithWord: true,
+    closeCharacters: /[\s()\[\]{};:>,]/,
+    closeOnUnfocus: true,
+    completeOnSingleClick: false,
+    container: null,
+    customKeys: null,
+    extraKeys: null
+  };
+
+  CodeMirror.defineOption("hintOptions", null);
+});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/libs/codemirror/mode/yaml/yaml.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/codemirror/mode/yaml/yaml.js b/src/main/webapp/assets/js/libs/codemirror/mode/yaml/yaml.js
new file mode 100644
index 0000000..5ff5d28
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/codemirror/mode/yaml/yaml.js
@@ -0,0 +1,117 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("yaml", function() {
+
+  var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
+  var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
+
+  return {
+    token: function(stream, state) {
+      var ch = stream.peek();
+      var esc = state.escaped;
+      state.escaped = false;
+      /* comments */
+      if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
+        stream.skipToEnd();
+        return "comment";
+      }
+
+      if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))
+        return "string";
+
+      if (state.literal && stream.indentation() > state.keyCol) {
+        stream.skipToEnd(); return "string";
+      } else if (state.literal) { state.literal = false; }
+      if (stream.sol()) {
+        state.keyCol = 0;
+        state.pair = false;
+        state.pairStart = false;
+        /* document start */
+        if(stream.match(/---/)) { return "def"; }
+        /* document end */
+        if (stream.match(/\.\.\./)) { return "def"; }
+        /* array list item */
+        if (stream.match(/\s*-\s+/)) { return 'meta'; }
+      }
+      /* inline pairs/lists */
+      if (stream.match(/^(\{|\}|\[|\])/)) {
+        if (ch == '{')
+          state.inlinePairs++;
+        else if (ch == '}')
+          state.inlinePairs--;
+        else if (ch == '[')
+          state.inlineList++;
+        else
+          state.inlineList--;
+        return 'meta';
+      }
+
+      /* list seperator */
+      if (state.inlineList > 0 && !esc && ch == ',') {
+        stream.next();
+        return 'meta';
+      }
+      /* pairs seperator */
+      if (state.inlinePairs > 0 && !esc && ch == ',') {
+        state.keyCol = 0;
+        state.pair = false;
+        state.pairStart = false;
+        stream.next();
+        return 'meta';
+      }
+
+      /* start of value of a pair */
+      if (state.pairStart) {
+        /* block literals */
+        if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
+        /* references */
+        if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
+        /* numbers */
+        if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
+        if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
+        /* keywords */
+        if (stream.match(keywordRegex)) { return 'keyword'; }
+      }
+
+      /* pairs (associative arrays) -> key */
+      if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) {
+        state.pair = true;
+        state.keyCol = stream.indentation();
+        return "atom";
+      }
+      if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
+
+      /* nothing found, continue */
+      state.pairStart = false;
+      state.escaped = (ch == '\\');
+      stream.next();
+      return null;
+    },
+    startState: function() {
+      return {
+        pair: false,
+        pairStart: false,
+        keyCol: 0,
+        inlinePairs: 0,
+        inlineList: 0,
+        literal: false,
+        escaped: false
+      };
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-yaml", "yaml");
+
+});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/mode/yaml/yaml.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/mode/yaml/yaml.js b/src/main/webapp/assets/js/mode/yaml/yaml.js
deleted file mode 100644
index 5ff5d28..0000000
--- a/src/main/webapp/assets/js/mode/yaml/yaml.js
+++ /dev/null
@@ -1,117 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("yaml", function() {
-
-  var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
-  var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
-
-  return {
-    token: function(stream, state) {
-      var ch = stream.peek();
-      var esc = state.escaped;
-      state.escaped = false;
-      /* comments */
-      if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
-        stream.skipToEnd();
-        return "comment";
-      }
-
-      if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))
-        return "string";
-
-      if (state.literal && stream.indentation() > state.keyCol) {
-        stream.skipToEnd(); return "string";
-      } else if (state.literal) { state.literal = false; }
-      if (stream.sol()) {
-        state.keyCol = 0;
-        state.pair = false;
-        state.pairStart = false;
-        /* document start */
-        if(stream.match(/---/)) { return "def"; }
-        /* document end */
-        if (stream.match(/\.\.\./)) { return "def"; }
-        /* array list item */
-        if (stream.match(/\s*-\s+/)) { return 'meta'; }
-      }
-      /* inline pairs/lists */
-      if (stream.match(/^(\{|\}|\[|\])/)) {
-        if (ch == '{')
-          state.inlinePairs++;
-        else if (ch == '}')
-          state.inlinePairs--;
-        else if (ch == '[')
-          state.inlineList++;
-        else
-          state.inlineList--;
-        return 'meta';
-      }
-
-      /* list seperator */
-      if (state.inlineList > 0 && !esc && ch == ',') {
-        stream.next();
-        return 'meta';
-      }
-      /* pairs seperator */
-      if (state.inlinePairs > 0 && !esc && ch == ',') {
-        state.keyCol = 0;
-        state.pair = false;
-        state.pairStart = false;
-        stream.next();
-        return 'meta';
-      }
-
-      /* start of value of a pair */
-      if (state.pairStart) {
-        /* block literals */
-        if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
-        /* references */
-        if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
-        /* numbers */
-        if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
-        if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
-        /* keywords */
-        if (stream.match(keywordRegex)) { return 'keyword'; }
-      }
-
-      /* pairs (associative arrays) -> key */
-      if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) {
-        state.pair = true;
-        state.keyCol = stream.indentation();
-        return "atom";
-      }
-      if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
-
-      /* nothing found, continue */
-      state.pairStart = false;
-      state.escaped = (ch == '\\');
-      stream.next();
-      return null;
-    },
-    startState: function() {
-      return {
-        pair: false,
-        pairStart: false,
-        keyCol: 0,
-        inlinePairs: 0,
-        inlineList: 0,
-        literal: false,
-        escaped: false
-      };
-    }
-  };
-});
-
-CodeMirror.defineMIME("text/x-yaml", "yaml");
-
-});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/test/javascript/config.txt
----------------------------------------------------------------------
diff --git a/src/test/javascript/config.txt b/src/test/javascript/config.txt
index b1df69a..3ea2e75 100644
--- a/src/test/javascript/config.txt
+++ b/src/test/javascript/config.txt
@@ -43,7 +43,11 @@
         "zeroclipboard":"js/libs/ZeroClipboard",
         "js-yaml":"js/libs/js-yaml",
 
-        "codemirror":"js/lib/codemirror",
+        "codemirror":"js/libs/codemirror",
+        "codemirror-mode-yaml":"js/libs/codemirror/mode/yaml/yaml",
+        "codemirror-addon-show-hint":"js/libs/codemirror/addon/hint/show-hint",
+        "codemirror-addon-anyword-hint":"js/libs/codemirror/addon/hint/anyword-hint",
+        "codemirror-addon-display-placeholder":"js/libs/codemirror/addon/display/placeholder",
 
         "model":"js/model",
         "view":"js/view",


[15/27] brooklyn-ui git commit: move codemirror libraries to the usual places

Posted by he...@apache.org.
move codemirror libraries to the usual places


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/d19e3156
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/d19e3156
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/d19e3156

Branch: refs/heads/master
Commit: d19e315616dcf837bb4117aee9ace0d4c5cc9a20
Parents: 438132f
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Feb 12 15:53:28 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Feb 12 15:56:51 2016 +0000

----------------------------------------------------------------------
 .../assets/js/addon/display/placeholder.js      |   60 -
 .../webapp/assets/js/addon/hint/anyword-hint.js |   41 -
 .../webapp/assets/js/addon/hint/show-hint.js    |  386 -
 src/main/webapp/assets/js/config.js             |   14 +-
 src/main/webapp/assets/js/lib/codemirror.js     | 8835 ------------------
 src/main/webapp/assets/js/libs/codemirror.js    | 8835 ++++++++++++++++++
 .../codemirror/addon/display/placeholder.js     |   60 +
 .../libs/codemirror/addon/hint/anyword-hint.js  |   41 +
 .../js/libs/codemirror/addon/hint/show-hint.js  |  386 +
 .../assets/js/libs/codemirror/mode/yaml/yaml.js |  117 +
 src/main/webapp/assets/js/mode/yaml/yaml.js     |  117 -
 src/test/javascript/config.txt                  |    6 +-
 12 files changed, 9449 insertions(+), 9449 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/addon/display/placeholder.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/addon/display/placeholder.js b/src/main/webapp/assets/js/addon/display/placeholder.js
deleted file mode 100644
index ba6c096..0000000
--- a/src/main/webapp/assets/js/addon/display/placeholder.js
+++ /dev/null
@@ -1,60 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
-    var prev = old && old != CodeMirror.Init;
-    if (val && !prev) {
-      cm.on("blur", onBlur);
-      cm.on("change", onChange);
-      onChange(cm);
-    } else if (!val && prev) {
-      cm.off("blur", onBlur);
-      cm.off("change", onChange);
-      clearPlaceholder(cm);
-      var wrapper = cm.getWrapperElement();
-      wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
-    }
-
-    if (val && !cm.hasFocus()) onBlur(cm);
-  });
-
-  function clearPlaceholder(cm) {
-    if (cm.state.placeholder) {
-      cm.state.placeholder.parentNode.removeChild(cm.state.placeholder);
-      cm.state.placeholder = null;
-    }
-  }
-  function setPlaceholder(cm) {
-    clearPlaceholder(cm);
-    var elt = cm.state.placeholder = document.createElement("pre");
-    elt.style.cssText = "height: 0; overflow: visible";
-    elt.className = "CodeMirror-placeholder";
-    var placeHolder = cm.getOption("placeholder")
-    if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
-    elt.appendChild(placeHolder)
-    cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
-  }
-
-  function onBlur(cm) {
-    if (isEmpty(cm)) setPlaceholder(cm);
-  }
-  function onChange(cm) {
-    var wrapper = cm.getWrapperElement(), empty = isEmpty(cm);
-    wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : "");
-
-    if (empty) setPlaceholder(cm);
-    else clearPlaceholder(cm);
-  }
-
-  function isEmpty(cm) {
-    return (cm.lineCount() === 1) && (cm.getLine(0) === "");
-  }
-});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/addon/hint/anyword-hint.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/addon/hint/anyword-hint.js b/src/main/webapp/assets/js/addon/hint/anyword-hint.js
deleted file mode 100644
index ade4274..0000000
--- a/src/main/webapp/assets/js/addon/hint/anyword-hint.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  var WORD = /[\w$]+/, RANGE = 500;
-
-  CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
-    var word = options && options.word || WORD;
-    var range = options && options.range || RANGE;
-    var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
-    var end = cur.ch, start = end;
-    while (start && word.test(curLine.charAt(start - 1))) --start;
-    var curWord = start != end && curLine.slice(start, end);
-
-    var list = options && options.list || [], seen = {};
-    var re = new RegExp(word.source, "g");
-    for (var dir = -1; dir <= 1; dir += 2) {
-      var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
-      for (; line != endLine; line += dir) {
-        var text = editor.getLine(line), m;
-        while (m = re.exec(text)) {
-          if (line == cur.line && m[0] === curWord) continue;
-          if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
-            seen[m[0]] = true;
-            list.push(m[0]);
-          }
-        }
-      }
-    }
-    return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
-  });
-});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/addon/hint/show-hint.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/addon/hint/show-hint.js b/src/main/webapp/assets/js/addon/hint/show-hint.js
deleted file mode 100644
index fa27867..0000000
--- a/src/main/webapp/assets/js/addon/hint/show-hint.js
+++ /dev/null
@@ -1,386 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
-  var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
-
-  // This is the old interface, kept around for now to stay
-  // backwards-compatible.
-  CodeMirror.showHint = function(cm, getHints, options) {
-    if (!getHints) return cm.showHint(options);
-    if (options && options.async) getHints.async = true;
-    var newOpts = {hint: getHints};
-    if (options) for (var prop in options) newOpts[prop] = options[prop];
-    return cm.showHint(newOpts);
-  };
-
-  CodeMirror.defineExtension("showHint", function(options) {
-    // We want a single cursor position.
-    if (this.listSelections().length > 1 || this.somethingSelected()) return;
-
-    if (this.state.completionActive) this.state.completionActive.close();
-    var completion = this.state.completionActive = new Completion(this, options);
-    if (!completion.options.hint) return;
-
-    CodeMirror.signal(this, "startCompletion", this);
-    completion.update(true);
-  });
-
-  function Completion(cm, options) {
-    this.cm = cm;
-    this.options = this.buildOptions(options);
-    this.widget = null;
-    this.debounce = 0;
-    this.tick = 0;
-    this.startPos = this.cm.getCursor();
-    this.startLen = this.cm.getLine(this.startPos.line).length;
-
-    var self = this;
-    cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
-  }
-
-  var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
-    return setTimeout(fn, 1000/60);
-  };
-  var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
-
-  Completion.prototype = {
-    close: function() {
-      if (!this.active()) return;
-      this.cm.state.completionActive = null;
-      this.tick = null;
-      this.cm.off("cursorActivity", this.activityFunc);
-
-      if (this.widget && this.data) CodeMirror.signal(this.data, "close");
-      if (this.widget) this.widget.close();
-      CodeMirror.signal(this.cm, "endCompletion", this.cm);
-    },
-
-    active: function() {
-      return this.cm.state.completionActive == this;
-    },
-
-    pick: function(data, i) {
-      var completion = data.list[i];
-      if (completion.hint) completion.hint(this.cm, data, completion);
-      else this.cm.replaceRange(getText(completion), completion.from || data.from,
-                                completion.to || data.to, "complete");
-      CodeMirror.signal(data, "pick", completion);
-      this.close();
-    },
-
-    cursorActivity: function() {
-      if (this.debounce) {
-        cancelAnimationFrame(this.debounce);
-        this.debounce = 0;
-      }
-
-      var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
-      if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
-          pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
-          (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
-        this.close();
-      } else {
-        var self = this;
-        this.debounce = requestAnimationFrame(function() {self.update();});
-        if (this.widget) this.widget.disable();
-      }
-    },
-
-    update: function(first) {
-      if (this.tick == null) return;
-      if (!this.options.hint.async) {
-        this.finishUpdate(this.options.hint(this.cm, this.options), first);
-      } else {
-        var myTick = ++this.tick, self = this;
-        this.options.hint(this.cm, function(data) {
-          if (self.tick == myTick) self.finishUpdate(data, first);
-        }, this.options);
-      }
-    },
-
-    finishUpdate: function(data, first) {
-      if (this.data) CodeMirror.signal(this.data, "update");
-      if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;
-      this.data = data;
-
-      var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
-      if (this.widget) this.widget.close();
-      if (data && data.list.length) {
-        if (picked && data.list.length == 1) {
-          this.pick(data, 0);
-        } else {
-          this.widget = new Widget(this, data);
-          CodeMirror.signal(data, "shown");
-        }
-      }
-    },
-
-    buildOptions: function(options) {
-      var editor = this.cm.options.hintOptions;
-      var out = {};
-      for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
-      if (editor) for (var prop in editor)
-        if (editor[prop] !== undefined) out[prop] = editor[prop];
-      if (options) for (var prop in options)
-        if (options[prop] !== undefined) out[prop] = options[prop];
-      return out;
-    }
-  };
-
-  function getText(completion) {
-    if (typeof completion == "string") return completion;
-    else return completion.text;
-  }
-
-  function buildKeyMap(completion, handle) {
-    var baseMap = {
-      Up: function() {handle.moveFocus(-1);},
-      Down: function() {handle.moveFocus(1);},
-      PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
-      PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
-      Home: function() {handle.setFocus(0);},
-      End: function() {handle.setFocus(handle.length - 1);},
-      Enter: handle.pick,
-      Tab: handle.pick,
-      Esc: handle.close
-    };
-    var custom = completion.options.customKeys;
-    var ourMap = custom ? {} : baseMap;
-    function addBinding(key, val) {
-      var bound;
-      if (typeof val != "string")
-        bound = function(cm) { return val(cm, handle); };
-      // This mechanism is deprecated
-      else if (baseMap.hasOwnProperty(val))
-        bound = baseMap[val];
-      else
-        bound = val;
-      ourMap[key] = bound;
-    }
-    if (custom)
-      for (var key in custom) if (custom.hasOwnProperty(key))
-        addBinding(key, custom[key]);
-    var extra = completion.options.extraKeys;
-    if (extra)
-      for (var key in extra) if (extra.hasOwnProperty(key))
-        addBinding(key, extra[key]);
-    return ourMap;
-  }
-
-  function getHintElement(hintsElement, el) {
-    while (el && el != hintsElement) {
-      if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
-      el = el.parentNode;
-    }
-  }
-
-  function Widget(completion, data) {
-    this.completion = completion;
-    this.data = data;
-    this.picked = false;
-    var widget = this, cm = completion.cm;
-
-    var hints = this.hints = document.createElement("ul");
-    hints.className = "CodeMirror-hints";
-    this.selectedHint = data.selectedHint || 0;
-
-    var completions = data.list;
-    for (var i = 0; i < completions.length; ++i) {
-      var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
-      var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
-      if (cur.className != null) className = cur.className + " " + className;
-      elt.className = className;
-      if (cur.render) cur.render(elt, data, cur);
-      else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
-      elt.hintId = i;
-    }
-
-    var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
-    var left = pos.left, top = pos.bottom, below = true;
-    hints.style.left = left + "px";
-    hints.style.top = top + "px";
-    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
-    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
-    var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
-    (completion.options.container || document.body).appendChild(hints);
-    var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
-    if (overlapY > 0) {
-      var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
-      if (curTop - height > 0) { // Fits above cursor
-        hints.style.top = (top = pos.top - height) + "px";
-        below = false;
-      } else if (height > winH) {
-        hints.style.height = (winH - 5) + "px";
-        hints.style.top = (top = pos.bottom - box.top) + "px";
-        var cursor = cm.getCursor();
-        if (data.from.ch != cursor.ch) {
-          pos = cm.cursorCoords(cursor);
-          hints.style.left = (left = pos.left) + "px";
-          box = hints.getBoundingClientRect();
-        }
-      }
-    }
-    var overlapX = box.right - winW;
-    if (overlapX > 0) {
-      if (box.right - box.left > winW) {
-        hints.style.width = (winW - 5) + "px";
-        overlapX -= (box.right - box.left) - winW;
-      }
-      hints.style.left = (left = pos.left - overlapX) + "px";
-    }
-
-    cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
-      moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
-      setFocus: function(n) { widget.changeActive(n); },
-      menuSize: function() { return widget.screenAmount(); },
-      length: completions.length,
-      close: function() { completion.close(); },
-      pick: function() { widget.pick(); },
-      data: data
-    }));
-
-    if (completion.options.closeOnUnfocus) {
-      var closingOnBlur;
-      cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
-      cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
-    }
-
-    var startScroll = cm.getScrollInfo();
-    cm.on("scroll", this.onScroll = function() {
-      var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
-      var newTop = top + startScroll.top - curScroll.top;
-      var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
-      if (!below) point += hints.offsetHeight;
-      if (point <= editor.top || point >= editor.bottom) return completion.close();
-      hints.style.top = newTop + "px";
-      hints.style.left = (left + startScroll.left - curScroll.left) + "px";
-    });
-
-    CodeMirror.on(hints, "dblclick", function(e) {
-      var t = getHintElement(hints, e.target || e.srcElement);
-      if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
-    });
-
-    CodeMirror.on(hints, "click", function(e) {
-      var t = getHintElement(hints, e.target || e.srcElement);
-      if (t && t.hintId != null) {
-        widget.changeActive(t.hintId);
-        if (completion.options.completeOnSingleClick) widget.pick();
-      }
-    });
-
-    CodeMirror.on(hints, "mousedown", function() {
-      setTimeout(function(){cm.focus();}, 20);
-    });
-
-    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
-    return true;
-  }
-
-  Widget.prototype = {
-    close: function() {
-      if (this.completion.widget != this) return;
-      this.completion.widget = null;
-      this.hints.parentNode.removeChild(this.hints);
-      this.completion.cm.removeKeyMap(this.keyMap);
-
-      var cm = this.completion.cm;
-      if (this.completion.options.closeOnUnfocus) {
-        cm.off("blur", this.onBlur);
-        cm.off("focus", this.onFocus);
-      }
-      cm.off("scroll", this.onScroll);
-    },
-
-    disable: function() {
-      this.completion.cm.removeKeyMap(this.keyMap);
-      var widget = this;
-      this.keyMap = {Enter: function() { widget.picked = true; }};
-      this.completion.cm.addKeyMap(this.keyMap);
-    },
-
-    pick: function() {
-      this.completion.pick(this.data, this.selectedHint);
-    },
-
-    changeActive: function(i, avoidWrap) {
-      if (i >= this.data.list.length)
-        i = avoidWrap ? this.data.list.length - 1 : 0;
-      else if (i < 0)
-        i = avoidWrap ? 0  : this.data.list.length - 1;
-      if (this.selectedHint == i) return;
-      var node = this.hints.childNodes[this.selectedHint];
-      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
-      node = this.hints.childNodes[this.selectedHint = i];
-      node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
-      if (node.offsetTop < this.hints.scrollTop)
-        this.hints.scrollTop = node.offsetTop - 3;
-      else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
-        this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
-      CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
-    },
-
-    screenAmount: function() {
-      return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
-    }
-  };
-
-  CodeMirror.registerHelper("hint", "auto", function(cm, options) {
-    var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
-    if (helpers.length) {
-      for (var i = 0; i < helpers.length; i++) {
-        var cur = helpers[i](cm, options);
-        if (cur && cur.list.length) return cur;
-      }
-    } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
-      if (words) return CodeMirror.hint.fromList(cm, {words: words});
-    } else if (CodeMirror.hint.anyword) {
-      return CodeMirror.hint.anyword(cm, options);
-    }
-  });
-
-  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
-    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
-    var to = CodeMirror.Pos(cur.line, token.end);
-    if (token.string && /\w/.test(token.string[token.string.length - 1])) {
-      var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
-    } else {
-      var term = "", from = to;
-    }
-    var found = [];
-    for (var i = 0; i < options.words.length; i++) {
-      var word = options.words[i];
-      if (word.slice(0, term.length) == term)
-        found.push(word);
-    }
-
-    if (found.length) return {list: found, from: from, to: to};
-  });
-
-  CodeMirror.commands.autocomplete = CodeMirror.showHint;
-
-  var defaultOptions = {
-    hint: CodeMirror.hint.auto,
-    completeSingle: true,
-    alignWithWord: true,
-    closeCharacters: /[\s()\[\]{};:>,]/,
-    closeOnUnfocus: true,
-    completeOnSingleClick: false,
-    container: null,
-    customKeys: null,
-    extraKeys: null
-  };
-
-  CodeMirror.defineOption("hintOptions", null);
-});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/config.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/config.js b/src/main/webapp/assets/js/config.js
index 24965a8..05afbb6 100644
--- a/src/main/webapp/assets/js/config.js
+++ b/src/main/webapp/assets/js/config.js
@@ -50,15 +50,11 @@ require.config({
         "zeroclipboard":"libs/ZeroClipboard",
         "js-yaml":"libs/js-yaml",
 
-        "codemirror":"lib/codemirror",
-
-        "mode":"mode",
-        "addon":"addon",
-
-        "codemirror-mode-yaml":"mode/yaml/yaml",
-        "codemirror-addon-show-hint":"addon/hint/show-hint",
-        "codemirror-addon-anyword-hint":"addon/hint/anyword-hint",
-        "codemirror-addon-display-placeholder":"addon/display/placeholder",
+        "codemirror":"libs/codemirror",
+        "codemirror-mode-yaml":"libs/codemirror/mode/yaml/yaml",
+        "codemirror-addon-show-hint":"libs/codemirror/addon/hint/show-hint",
+        "codemirror-addon-anyword-hint":"libs/codemirror/addon/hint/anyword-hint",
+        "codemirror-addon-display-placeholder":"libs/codemirror/addon/display/placeholder",
 
         "tpl":"../tpl"
     },


[14/27] brooklyn-ui git commit: move codemirror libraries to the usual places

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/lib/codemirror.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/lib/codemirror.js b/src/main/webapp/assets/js/lib/codemirror.js
deleted file mode 100644
index c6f9af8..0000000
--- a/src/main/webapp/assets/js/lib/codemirror.js
+++ /dev/null
@@ -1,8835 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-// This is CodeMirror (http://codemirror.net), a code editor
-// implemented in JavaScript on top of the browser's DOM.
-//
-// You can find some technical background for some of the code below
-// at http://marijnhaverbeke.nl/blog/#cm-internals .
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    module.exports = mod();
-  else if (typeof define == "function" && define.amd) // AMD
-    return define([], mod);
-  else // Plain browser env
-    this.CodeMirror = mod();
-})(function() {
-  "use strict";
-
-  // BROWSER SNIFFING
-
-  // Kludges for bugs and behavior differences that can't be feature
-  // detected are enabled based on userAgent etc sniffing.
-
-  var gecko = /gecko\/\d/i.test(navigator.userAgent);
-  var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
-  var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
-  var ie = ie_upto10 || ie_11up;
-  var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
-  var webkit = /WebKit\//.test(navigator.userAgent);
-  var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
-  var chrome = /Chrome\//.test(navigator.userAgent);
-  var presto = /Opera\//.test(navigator.userAgent);
-  var safari = /Apple Computer/.test(navigator.vendor);
-  var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
-  var phantom = /PhantomJS/.test(navigator.userAgent);
-
-  var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
-  // This is woefully incomplete. Suggestions for alternative methods welcome.
-  var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
-  var mac = ios || /Mac/.test(navigator.platform);
-  var windows = /win/i.test(navigator.platform);
-
-  var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
-  if (presto_version) presto_version = Number(presto_version[1]);
-  if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
-  // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
-  var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
-  var captureRightClick = gecko || (ie && ie_version >= 9);
-
-  // Optimize some code when these features are not used.
-  var sawReadOnlySpans = false, sawCollapsedSpans = false;
-
-  // EDITOR CONSTRUCTOR
-
-  // A CodeMirror instance represents an editor. This is the object
-  // that user code is usually dealing with.
-
-  function CodeMirror(place, options) {
-    if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
-
-    this.options = options = options ? copyObj(options) : {};
-    // Determine effective options based on given values and defaults.
-    copyObj(defaults, options, false);
-    setGuttersForLineNumbers(options);
-
-    var doc = options.value;
-    if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator);
-    this.doc = doc;
-
-    var input = new CodeMirror.inputStyles[options.inputStyle](this);
-    var display = this.display = new Display(place, doc, input);
-    display.wrapper.CodeMirror = this;
-    updateGutters(this);
-    themeChanged(this);
-    if (options.lineWrapping)
-      this.display.wrapper.className += " CodeMirror-wrap";
-    if (options.autofocus && !mobile) display.input.focus();
-    initScrollbars(this);
-
-    this.state = {
-      keyMaps: [],  // stores maps added by addKeyMap
-      overlays: [], // highlighting overlays, as added by addOverlay
-      modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
-      overwrite: false,
-      delayingBlurEvent: false,
-      focused: false,
-      suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
-      pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
-      selectingText: false,
-      draggingText: false,
-      highlight: new Delayed(), // stores highlight worker timeout
-      keySeq: null,  // Unfinished key sequence
-      specialChars: null
-    };
-
-    var cm = this;
-
-    // Override magic textarea content restore that IE sometimes does
-    // on our hidden textarea on reload
-    if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20);
-
-    registerEventHandlers(this);
-    ensureGlobalHandlers();
-
-    startOperation(this);
-    this.curOp.forceUpdate = true;
-    attachDoc(this, doc);
-
-    if ((options.autofocus && !mobile) || cm.hasFocus())
-      setTimeout(bind(onFocus, this), 20);
-    else
-      onBlur(this);
-
-    for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
-      optionHandlers[opt](this, options[opt], Init);
-    maybeUpdateLineNumberWidth(this);
-    if (options.finishInit) options.finishInit(this);
-    for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
-    endOperation(this);
-    // Suppress optimizelegibility in Webkit, since it breaks text
-    // measuring on line wrapping boundaries.
-    if (webkit && options.lineWrapping &&
-        getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
-      display.lineDiv.style.textRendering = "auto";
-  }
-
-  // DISPLAY CONSTRUCTOR
-
-  // The display handles the DOM integration, both for input reading
-  // and content drawing. It holds references to DOM nodes and
-  // display-related state.
-
-  function Display(place, doc, input) {
-    var d = this;
-    this.input = input;
-
-    // Covers bottom-right square when both scrollbars are present.
-    d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
-    d.scrollbarFiller.setAttribute("cm-not-content", "true");
-    // Covers bottom of gutter when coverGutterNextToScrollbar is on
-    // and h scrollbar is present.
-    d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
-    d.gutterFiller.setAttribute("cm-not-content", "true");
-    // Will contain the actual code, positioned to cover the viewport.
-    d.lineDiv = elt("div", null, "CodeMirror-code");
-    // Elements are added to these to represent selection and cursors.
-    d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
-    d.cursorDiv = elt("div", null, "CodeMirror-cursors");
-    // A visibility: hidden element used to find the size of things.
-    d.measure = elt("div", null, "CodeMirror-measure");
-    // When lines outside of the viewport are measured, they are drawn in this.
-    d.lineMeasure = elt("div", null, "CodeMirror-measure");
-    // Wraps everything that needs to exist inside the vertically-padded coordinate system
-    d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
-                      null, "position: relative; outline: none");
-    // Moved around its parent to cover visible view.
-    d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
-    // Set to the height of the document, allowing scrolling.
-    d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
-    d.sizerWidth = null;
-    // Behavior of elts with overflow: auto and padding is
-    // inconsistent across browsers. This is used to ensure the
-    // scrollable area is big enough.
-    d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
-    // Will contain the gutters, if any.
-    d.gutters = elt("div", null, "CodeMirror-gutters");
-    d.lineGutter = null;
-    // Actual scrollable element.
-    d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
-    d.scroller.setAttribute("tabIndex", "-1");
-    // The element in which the editor lives.
-    d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
-
-    // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
-    if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
-    if (!webkit && !(gecko && mobile)) d.scroller.draggable = true;
-
-    if (place) {
-      if (place.appendChild) place.appendChild(d.wrapper);
-      else place(d.wrapper);
-    }
-
-    // Current rendered range (may be bigger than the view window).
-    d.viewFrom = d.viewTo = doc.first;
-    d.reportedViewFrom = d.reportedViewTo = doc.first;
-    // Information about the rendered lines.
-    d.view = [];
-    d.renderedView = null;
-    // Holds info about a single rendered line when it was rendered
-    // for measurement, while not in view.
-    d.externalMeasured = null;
-    // Empty space (in pixels) above the view
-    d.viewOffset = 0;
-    d.lastWrapHeight = d.lastWrapWidth = 0;
-    d.updateLineNumbers = null;
-
-    d.nativeBarWidth = d.barHeight = d.barWidth = 0;
-    d.scrollbarsClipped = false;
-
-    // Used to only resize the line number gutter when necessary (when
-    // the amount of lines crosses a boundary that makes its width change)
-    d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
-    // Set to true when a non-horizontal-scrolling line widget is
-    // added. As an optimization, line widget aligning is skipped when
-    // this is false.
-    d.alignWidgets = false;
-
-    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
-
-    // Tracks the maximum line length so that the horizontal scrollbar
-    // can be kept static when scrolling.
-    d.maxLine = null;
-    d.maxLineLength = 0;
-    d.maxLineChanged = false;
-
-    // Used for measuring wheel scrolling granularity
-    d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
-
-    // True when shift is held down.
-    d.shift = false;
-
-    // Used to track whether anything happened since the context menu
-    // was opened.
-    d.selForContextMenu = null;
-
-    d.activeTouch = null;
-
-    input.init(d);
-  }
-
-  // STATE UPDATES
-
-  // Used to get the editor into a consistent state again when options change.
-
-  function loadMode(cm) {
-    cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
-    resetModeState(cm);
-  }
-
-  function resetModeState(cm) {
-    cm.doc.iter(function(line) {
-      if (line.stateAfter) line.stateAfter = null;
-      if (line.styles) line.styles = null;
-    });
-    cm.doc.frontier = cm.doc.first;
-    startWorker(cm, 100);
-    cm.state.modeGen++;
-    if (cm.curOp) regChange(cm);
-  }
-
-  function wrappingChanged(cm) {
-    if (cm.options.lineWrapping) {
-      addClass(cm.display.wrapper, "CodeMirror-wrap");
-      cm.display.sizer.style.minWidth = "";
-      cm.display.sizerWidth = null;
-    } else {
-      rmClass(cm.display.wrapper, "CodeMirror-wrap");
-      findMaxLine(cm);
-    }
-    estimateLineHeights(cm);
-    regChange(cm);
-    clearCaches(cm);
-    setTimeout(function(){updateScrollbars(cm);}, 100);
-  }
-
-  // Returns a function that estimates the height of a line, to use as
-  // first approximation until the line becomes visible (and is thus
-  // properly measurable).
-  function estimateHeight(cm) {
-    var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
-    var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
-    return function(line) {
-      if (lineIsHidden(cm.doc, line)) return 0;
-
-      var widgetsHeight = 0;
-      if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
-        if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
-      }
-
-      if (wrapping)
-        return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
-      else
-        return widgetsHeight + th;
-    };
-  }
-
-  function estimateLineHeights(cm) {
-    var doc = cm.doc, est = estimateHeight(cm);
-    doc.iter(function(line) {
-      var estHeight = est(line);
-      if (estHeight != line.height) updateLineHeight(line, estHeight);
-    });
-  }
-
-  function themeChanged(cm) {
-    cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
-      cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
-    clearCaches(cm);
-  }
-
-  function guttersChanged(cm) {
-    updateGutters(cm);
-    regChange(cm);
-    setTimeout(function(){alignHorizontally(cm);}, 20);
-  }
-
-  // Rebuild the gutter elements, ensure the margin to the left of the
-  // code matches their width.
-  function updateGutters(cm) {
-    var gutters = cm.display.gutters, specs = cm.options.gutters;
-    removeChildren(gutters);
-    for (var i = 0; i < specs.length; ++i) {
-      var gutterClass = specs[i];
-      var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
-      if (gutterClass == "CodeMirror-linenumbers") {
-        cm.display.lineGutter = gElt;
-        gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
-      }
-    }
-    gutters.style.display = i ? "" : "none";
-    updateGutterSpace(cm);
-  }
-
-  function updateGutterSpace(cm) {
-    var width = cm.display.gutters.offsetWidth;
-    cm.display.sizer.style.marginLeft = width + "px";
-  }
-
-  // Compute the character length of a line, taking into account
-  // collapsed ranges (see markText) that might hide parts, and join
-  // other lines onto it.
-  function lineLength(line) {
-    if (line.height == 0) return 0;
-    var len = line.text.length, merged, cur = line;
-    while (merged = collapsedSpanAtStart(cur)) {
-      var found = merged.find(0, true);
-      cur = found.from.line;
-      len += found.from.ch - found.to.ch;
-    }
-    cur = line;
-    while (merged = collapsedSpanAtEnd(cur)) {
-      var found = merged.find(0, true);
-      len -= cur.text.length - found.from.ch;
-      cur = found.to.line;
-      len += cur.text.length - found.to.ch;
-    }
-    return len;
-  }
-
-  // Find the longest line in the document.
-  function findMaxLine(cm) {
-    var d = cm.display, doc = cm.doc;
-    d.maxLine = getLine(doc, doc.first);
-    d.maxLineLength = lineLength(d.maxLine);
-    d.maxLineChanged = true;
-    doc.iter(function(line) {
-      var len = lineLength(line);
-      if (len > d.maxLineLength) {
-        d.maxLineLength = len;
-        d.maxLine = line;
-      }
-    });
-  }
-
-  // Make sure the gutters options contains the element
-  // "CodeMirror-linenumbers" when the lineNumbers option is true.
-  function setGuttersForLineNumbers(options) {
-    var found = indexOf(options.gutters, "CodeMirror-linenumbers");
-    if (found == -1 && options.lineNumbers) {
-      options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
-    } else if (found > -1 && !options.lineNumbers) {
-      options.gutters = options.gutters.slice(0);
-      options.gutters.splice(found, 1);
-    }
-  }
-
-  // SCROLLBARS
-
-  // Prepare DOM reads needed to update the scrollbars. Done in one
-  // shot to minimize update/measure roundtrips.
-  function measureForScrollbars(cm) {
-    var d = cm.display, gutterW = d.gutters.offsetWidth;
-    var docH = Math.round(cm.doc.height + paddingVert(cm.display));
-    return {
-      clientHeight: d.scroller.clientHeight,
-      viewHeight: d.wrapper.clientHeight,
-      scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
-      viewWidth: d.wrapper.clientWidth,
-      barLeft: cm.options.fixedGutter ? gutterW : 0,
-      docHeight: docH,
-      scrollHeight: docH + scrollGap(cm) + d.barHeight,
-      nativeBarWidth: d.nativeBarWidth,
-      gutterWidth: gutterW
-    };
-  }
-
-  function NativeScrollbars(place, scroll, cm) {
-    this.cm = cm;
-    var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
-    var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
-    place(vert); place(horiz);
-
-    on(vert, "scroll", function() {
-      if (vert.clientHeight) scroll(vert.scrollTop, "vertical");
-    });
-    on(horiz, "scroll", function() {
-      if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
-    });
-
-    this.checkedOverlay = false;
-    // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
-    if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
-  }
-
-  NativeScrollbars.prototype = copyObj({
-    update: function(measure) {
-      var needsH = measure.scrollWidth > measure.clientWidth + 1;
-      var needsV = measure.scrollHeight > measure.clientHeight + 1;
-      var sWidth = measure.nativeBarWidth;
-
-      if (needsV) {
-        this.vert.style.display = "block";
-        this.vert.style.bottom = needsH ? sWidth + "px" : "0";
-        var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
-        // A bug in IE8 can cause this value to be negative, so guard it.
-        this.vert.firstChild.style.height =
-          Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
-      } else {
-        this.vert.style.display = "";
-        this.vert.firstChild.style.height = "0";
-      }
-
-      if (needsH) {
-        this.horiz.style.display = "block";
-        this.horiz.style.right = needsV ? sWidth + "px" : "0";
-        this.horiz.style.left = measure.barLeft + "px";
-        var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
-        this.horiz.firstChild.style.width =
-          (measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
-      } else {
-        this.horiz.style.display = "";
-        this.horiz.firstChild.style.width = "0";
-      }
-
-      if (!this.checkedOverlay && measure.clientHeight > 0) {
-        if (sWidth == 0) this.overlayHack();
-        this.checkedOverlay = true;
-      }
-
-      return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
-    },
-    setScrollLeft: function(pos) {
-      if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
-    },
-    setScrollTop: function(pos) {
-      if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
-    },
-    overlayHack: function() {
-      var w = mac && !mac_geMountainLion ? "12px" : "18px";
-      this.horiz.style.minHeight = this.vert.style.minWidth = w;
-      var self = this;
-      var barMouseDown = function(e) {
-        if (e_target(e) != self.vert && e_target(e) != self.horiz)
-          operation(self.cm, onMouseDown)(e);
-      };
-      on(this.vert, "mousedown", barMouseDown);
-      on(this.horiz, "mousedown", barMouseDown);
-    },
-    clear: function() {
-      var parent = this.horiz.parentNode;
-      parent.removeChild(this.horiz);
-      parent.removeChild(this.vert);
-    }
-  }, NativeScrollbars.prototype);
-
-  function NullScrollbars() {}
-
-  NullScrollbars.prototype = copyObj({
-    update: function() { return {bottom: 0, right: 0}; },
-    setScrollLeft: function() {},
-    setScrollTop: function() {},
-    clear: function() {}
-  }, NullScrollbars.prototype);
-
-  CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
-
-  function initScrollbars(cm) {
-    if (cm.display.scrollbars) {
-      cm.display.scrollbars.clear();
-      if (cm.display.scrollbars.addClass)
-        rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);
-    }
-
-    cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {
-      cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
-      // Prevent clicks in the scrollbars from killing focus
-      on(node, "mousedown", function() {
-        if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0);
-      });
-      node.setAttribute("cm-not-content", "true");
-    }, function(pos, axis) {
-      if (axis == "horizontal") setScrollLeft(cm, pos);
-      else setScrollTop(cm, pos);
-    }, cm);
-    if (cm.display.scrollbars.addClass)
-      addClass(cm.display.wrapper, cm.display.scrollbars.addClass);
-  }
-
-  function updateScrollbars(cm, measure) {
-    if (!measure) measure = measureForScrollbars(cm);
-    var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
-    updateScrollbarsInner(cm, measure);
-    for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
-      if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
-        updateHeightsInViewport(cm);
-      updateScrollbarsInner(cm, measureForScrollbars(cm));
-      startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
-    }
-  }
-
-  // Re-synchronize the fake scrollbars with the actual size of the
-  // content.
-  function updateScrollbarsInner(cm, measure) {
-    var d = cm.display;
-    var sizes = d.scrollbars.update(measure);
-
-    d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
-    d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
-
-    if (sizes.right && sizes.bottom) {
-      d.scrollbarFiller.style.display = "block";
-      d.scrollbarFiller.style.height = sizes.bottom + "px";
-      d.scrollbarFiller.style.width = sizes.right + "px";
-    } else d.scrollbarFiller.style.display = "";
-    if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
-      d.gutterFiller.style.display = "block";
-      d.gutterFiller.style.height = sizes.bottom + "px";
-      d.gutterFiller.style.width = measure.gutterWidth + "px";
-    } else d.gutterFiller.style.display = "";
-  }
-
-  // Compute the lines that are visible in a given viewport (defaults
-  // the the current scroll position). viewport may contain top,
-  // height, and ensure (see op.scrollToPos) properties.
-  function visibleLines(display, doc, viewport) {
-    var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
-    top = Math.floor(top - paddingTop(display));
-    var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
-
-    var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
-    // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
-    // forces those lines into the viewport (if possible).
-    if (viewport && viewport.ensure) {
-      var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
-      if (ensureFrom < from) {
-        from = ensureFrom;
-        to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
-      } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
-        from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
-        to = ensureTo;
-      }
-    }
-    return {from: from, to: Math.max(to, from + 1)};
-  }
-
-  // LINE NUMBERS
-
-  // Re-align line numbers and gutter marks to compensate for
-  // horizontal scrolling.
-  function alignHorizontally(cm) {
-    var display = cm.display, view = display.view;
-    if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
-    var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
-    var gutterW = display.gutters.offsetWidth, left = comp + "px";
-    for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
-      if (cm.options.fixedGutter && view[i].gutter)
-        view[i].gutter.style.left = left;
-      var align = view[i].alignable;
-      if (align) for (var j = 0; j < align.length; j++)
-        align[j].style.left = left;
-    }
-    if (cm.options.fixedGutter)
-      display.gutters.style.left = (comp + gutterW) + "px";
-  }
-
-  // Used to ensure that the line number gutter is still the right
-  // size for the current document size. Returns true when an update
-  // is needed.
-  function maybeUpdateLineNumberWidth(cm) {
-    if (!cm.options.lineNumbers) return false;
-    var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
-    if (last.length != display.lineNumChars) {
-      var test = display.measure.appendChild(elt("div", [elt("div", last)],
-                                                 "CodeMirror-linenumber CodeMirror-gutter-elt"));
-      var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
-      display.lineGutter.style.width = "";
-      display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
-      display.lineNumWidth = display.lineNumInnerWidth + padding;
-      display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
-      display.lineGutter.style.width = display.lineNumWidth + "px";
-      updateGutterSpace(cm);
-      return true;
-    }
-    return false;
-  }
-
-  function lineNumberFor(options, i) {
-    return String(options.lineNumberFormatter(i + options.firstLineNumber));
-  }
-
-  // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
-  // but using getBoundingClientRect to get a sub-pixel-accurate
-  // result.
-  function compensateForHScroll(display) {
-    return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
-  }
-
-  // DISPLAY DRAWING
-
-  function DisplayUpdate(cm, viewport, force) {
-    var display = cm.display;
-
-    this.viewport = viewport;
-    // Store some values that we'll need later (but don't want to force a relayout for)
-    this.visible = visibleLines(display, cm.doc, viewport);
-    this.editorIsHidden = !display.wrapper.offsetWidth;
-    this.wrapperHeight = display.wrapper.clientHeight;
-    this.wrapperWidth = display.wrapper.clientWidth;
-    this.oldDisplayWidth = displayWidth(cm);
-    this.force = force;
-    this.dims = getDimensions(cm);
-    this.events = [];
-  }
-
-  DisplayUpdate.prototype.signal = function(emitter, type) {
-    if (hasHandler(emitter, type))
-      this.events.push(arguments);
-  };
-  DisplayUpdate.prototype.finish = function() {
-    for (var i = 0; i < this.events.length; i++)
-      signal.apply(null, this.events[i]);
-  };
-
-  function maybeClipScrollbars(cm) {
-    var display = cm.display;
-    if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
-      display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
-      display.heightForcer.style.height = scrollGap(cm) + "px";
-      display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
-      display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
-      display.scrollbarsClipped = true;
-    }
-  }
-
-  // Does the actual updating of the line display. Bails out
-  // (returning false) when there is nothing to be done and forced is
-  // false.
-  function updateDisplayIfNeeded(cm, update) {
-    var display = cm.display, doc = cm.doc;
-
-    if (update.editorIsHidden) {
-      resetView(cm);
-      return false;
-    }
-
-    // Bail out if the visible area is already rendered and nothing changed.
-    if (!update.force &&
-        update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
-        (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
-        display.renderedView == display.view && countDirtyView(cm) == 0)
-      return false;
-
-    if (maybeUpdateLineNumberWidth(cm)) {
-      resetView(cm);
-      update.dims = getDimensions(cm);
-    }
-
-    // Compute a suitable new viewport (from & to)
-    var end = doc.first + doc.size;
-    var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
-    var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
-    if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
-    if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
-    if (sawCollapsedSpans) {
-      from = visualLineNo(cm.doc, from);
-      to = visualLineEndNo(cm.doc, to);
-    }
-
-    var different = from != display.viewFrom || to != display.viewTo ||
-      display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
-    adjustView(cm, from, to);
-
-    display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
-    // Position the mover div to align with the current scroll position
-    cm.display.mover.style.top = display.viewOffset + "px";
-
-    var toUpdate = countDirtyView(cm);
-    if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
-        (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
-      return false;
-
-    // For big changes, we hide the enclosing element during the
-    // update, since that speeds up the operations on most browsers.
-    var focused = activeElt();
-    if (toUpdate > 4) display.lineDiv.style.display = "none";
-    patchDisplay(cm, display.updateLineNumbers, update.dims);
-    if (toUpdate > 4) display.lineDiv.style.display = "";
-    display.renderedView = display.view;
-    // There might have been a widget with a focused element that got
-    // hidden or updated, if so re-focus it.
-    if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
-
-    // Prevent selection and cursors from interfering with the scroll
-    // width and height.
-    removeChildren(display.cursorDiv);
-    removeChildren(display.selectionDiv);
-    display.gutters.style.height = display.sizer.style.minHeight = 0;
-
-    if (different) {
-      display.lastWrapHeight = update.wrapperHeight;
-      display.lastWrapWidth = update.wrapperWidth;
-      startWorker(cm, 400);
-    }
-
-    display.updateLineNumbers = null;
-
-    return true;
-  }
-
-  function postUpdateDisplay(cm, update) {
-    var viewport = update.viewport;
-    for (var first = true;; first = false) {
-      if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
-        // Clip forced viewport to actual scrollable area.
-        if (viewport && viewport.top != null)
-          viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
-        // Updated line heights might result in the drawn area not
-        // actually covering the viewport. Keep looping until it does.
-        update.visible = visibleLines(cm.display, cm.doc, viewport);
-        if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
-          break;
-      }
-      if (!updateDisplayIfNeeded(cm, update)) break;
-      updateHeightsInViewport(cm);
-      var barMeasure = measureForScrollbars(cm);
-      updateSelection(cm);
-      setDocumentHeight(cm, barMeasure);
-      updateScrollbars(cm, barMeasure);
-    }
-
-    update.signal(cm, "update", cm);
-    if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
-      update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
-      cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
-    }
-  }
-
-  function updateDisplaySimple(cm, viewport) {
-    var update = new DisplayUpdate(cm, viewport);
-    if (updateDisplayIfNeeded(cm, update)) {
-      updateHeightsInViewport(cm);
-      postUpdateDisplay(cm, update);
-      var barMeasure = measureForScrollbars(cm);
-      updateSelection(cm);
-      setDocumentHeight(cm, barMeasure);
-      updateScrollbars(cm, barMeasure);
-      update.finish();
-    }
-  }
-
-  function setDocumentHeight(cm, measure) {
-    cm.display.sizer.style.minHeight = measure.docHeight + "px";
-    var total = measure.docHeight + cm.display.barHeight;
-    cm.display.heightForcer.style.top = total + "px";
-    cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px";
-  }
-
-  // Read the actual heights of the rendered lines, and update their
-  // stored heights to match.
-  function updateHeightsInViewport(cm) {
-    var display = cm.display;
-    var prevBottom = display.lineDiv.offsetTop;
-    for (var i = 0; i < display.view.length; i++) {
-      var cur = display.view[i], height;
-      if (cur.hidden) continue;
-      if (ie && ie_version < 8) {
-        var bot = cur.node.offsetTop + cur.node.offsetHeight;
-        height = bot - prevBottom;
-        prevBottom = bot;
-      } else {
-        var box = cur.node.getBoundingClientRect();
-        height = box.bottom - box.top;
-      }
-      var diff = cur.line.height - height;
-      if (height < 2) height = textHeight(display);
-      if (diff > .001 || diff < -.001) {
-        updateLineHeight(cur.line, height);
-        updateWidgetHeight(cur.line);
-        if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
-          updateWidgetHeight(cur.rest[j]);
-      }
-    }
-  }
-
-  // Read and store the height of line widgets associated with the
-  // given line.
-  function updateWidgetHeight(line) {
-    if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
-      line.widgets[i].height = line.widgets[i].node.offsetHeight;
-  }
-
-  // Do a bulk-read of the DOM positions and sizes needed to draw the
-  // view, so that we don't interleave reading and writing to the DOM.
-  function getDimensions(cm) {
-    var d = cm.display, left = {}, width = {};
-    var gutterLeft = d.gutters.clientLeft;
-    for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
-      left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
-      width[cm.options.gutters[i]] = n.clientWidth;
-    }
-    return {fixedPos: compensateForHScroll(d),
-            gutterTotalWidth: d.gutters.offsetWidth,
-            gutterLeft: left,
-            gutterWidth: width,
-            wrapperWidth: d.wrapper.clientWidth};
-  }
-
-  // Sync the actual display DOM structure with display.view, removing
-  // nodes for lines that are no longer in view, and creating the ones
-  // that are not there yet, and updating the ones that are out of
-  // date.
-  function patchDisplay(cm, updateNumbersFrom, dims) {
-    var display = cm.display, lineNumbers = cm.options.lineNumbers;
-    var container = display.lineDiv, cur = container.firstChild;
-
-    function rm(node) {
-      var next = node.nextSibling;
-      // Works around a throw-scroll bug in OS X Webkit
-      if (webkit && mac && cm.display.currentWheelTarget == node)
-        node.style.display = "none";
-      else
-        node.parentNode.removeChild(node);
-      return next;
-    }
-
-    var view = display.view, lineN = display.viewFrom;
-    // Loop over the elements in the view, syncing cur (the DOM nodes
-    // in display.lineDiv) with the view as we go.
-    for (var i = 0; i < view.length; i++) {
-      var lineView = view[i];
-      if (lineView.hidden) {
-      } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
-        var node = buildLineElement(cm, lineView, lineN, dims);
-        container.insertBefore(node, cur);
-      } else { // Already drawn
-        while (cur != lineView.node) cur = rm(cur);
-        var updateNumber = lineNumbers && updateNumbersFrom != null &&
-          updateNumbersFrom <= lineN && lineView.lineNumber;
-        if (lineView.changes) {
-          if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
-          updateLineForChanges(cm, lineView, lineN, dims);
-        }
-        if (updateNumber) {
-          removeChildren(lineView.lineNumber);
-          lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
-        }
-        cur = lineView.node.nextSibling;
-      }
-      lineN += lineView.size;
-    }
-    while (cur) cur = rm(cur);
-  }
-
-  // When an aspect of a line changes, a string is added to
-  // lineView.changes. This updates the relevant part of the line's
-  // DOM structure.
-  function updateLineForChanges(cm, lineView, lineN, dims) {
-    for (var j = 0; j < lineView.changes.length; j++) {
-      var type = lineView.changes[j];
-      if (type == "text") updateLineText(cm, lineView);
-      else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
-      else if (type == "class") updateLineClasses(lineView);
-      else if (type == "widget") updateLineWidgets(cm, lineView, dims);
-    }
-    lineView.changes = null;
-  }
-
-  // Lines with gutter elements, widgets or a background class need to
-  // be wrapped, and have the extra elements added to the wrapper div
-  function ensureLineWrapped(lineView) {
-    if (lineView.node == lineView.text) {
-      lineView.node = elt("div", null, null, "position: relative");
-      if (lineView.text.parentNode)
-        lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
-      lineView.node.appendChild(lineView.text);
-      if (ie && ie_version < 8) lineView.node.style.zIndex = 2;
-    }
-    return lineView.node;
-  }
-
-  function updateLineBackground(lineView) {
-    var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
-    if (cls) cls += " CodeMirror-linebackground";
-    if (lineView.background) {
-      if (cls) lineView.background.className = cls;
-      else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
-    } else if (cls) {
-      var wrap = ensureLineWrapped(lineView);
-      lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
-    }
-  }
-
-  // Wrapper around buildLineContent which will reuse the structure
-  // in display.externalMeasured when possible.
-  function getLineContent(cm, lineView) {
-    var ext = cm.display.externalMeasured;
-    if (ext && ext.line == lineView.line) {
-      cm.display.externalMeasured = null;
-      lineView.measure = ext.measure;
-      return ext.built;
-    }
-    return buildLineContent(cm, lineView);
-  }
-
-  // Redraw the line's text. Interacts with the background and text
-  // classes because the mode may output tokens that influence these
-  // classes.
-  function updateLineText(cm, lineView) {
-    var cls = lineView.text.className;
-    var built = getLineContent(cm, lineView);
-    if (lineView.text == lineView.node) lineView.node = built.pre;
-    lineView.text.parentNode.replaceChild(built.pre, lineView.text);
-    lineView.text = built.pre;
-    if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
-      lineView.bgClass = built.bgClass;
-      lineView.textClass = built.textClass;
-      updateLineClasses(lineView);
-    } else if (cls) {
-      lineView.text.className = cls;
-    }
-  }
-
-  function updateLineClasses(lineView) {
-    updateLineBackground(lineView);
-    if (lineView.line.wrapClass)
-      ensureLineWrapped(lineView).className = lineView.line.wrapClass;
-    else if (lineView.node != lineView.text)
-      lineView.node.className = "";
-    var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
-    lineView.text.className = textClass || "";
-  }
-
-  function updateLineGutter(cm, lineView, lineN, dims) {
-    if (lineView.gutter) {
-      lineView.node.removeChild(lineView.gutter);
-      lineView.gutter = null;
-    }
-    if (lineView.gutterBackground) {
-      lineView.node.removeChild(lineView.gutterBackground);
-      lineView.gutterBackground = null;
-    }
-    if (lineView.line.gutterClass) {
-      var wrap = ensureLineWrapped(lineView);
-      lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
-                                      "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
-                                      "px; width: " + dims.gutterTotalWidth + "px");
-      wrap.insertBefore(lineView.gutterBackground, lineView.text);
-    }
-    var markers = lineView.line.gutterMarkers;
-    if (cm.options.lineNumbers || markers) {
-      var wrap = ensureLineWrapped(lineView);
-      var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
-                                             (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px");
-      cm.display.input.setUneditable(gutterWrap);
-      wrap.insertBefore(gutterWrap, lineView.text);
-      if (lineView.line.gutterClass)
-        gutterWrap.className += " " + lineView.line.gutterClass;
-      if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
-        lineView.lineNumber = gutterWrap.appendChild(
-          elt("div", lineNumberFor(cm.options, lineN),
-              "CodeMirror-linenumber CodeMirror-gutter-elt",
-              "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
-              + cm.display.lineNumInnerWidth + "px"));
-      if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
-        var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
-        if (found)
-          gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
-                                     dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
-      }
-    }
-  }
-
-  function updateLineWidgets(cm, lineView, dims) {
-    if (lineView.alignable) lineView.alignable = null;
-    for (var node = lineView.node.firstChild, next; node; node = next) {
-      var next = node.nextSibling;
-      if (node.className == "CodeMirror-linewidget")
-        lineView.node.removeChild(node);
-    }
-    insertLineWidgets(cm, lineView, dims);
-  }
-
-  // Build a line's DOM representation from scratch
-  function buildLineElement(cm, lineView, lineN, dims) {
-    var built = getLineContent(cm, lineView);
-    lineView.text = lineView.node = built.pre;
-    if (built.bgClass) lineView.bgClass = built.bgClass;
-    if (built.textClass) lineView.textClass = built.textClass;
-
-    updateLineClasses(lineView);
-    updateLineGutter(cm, lineView, lineN, dims);
-    insertLineWidgets(cm, lineView, dims);
-    return lineView.node;
-  }
-
-  // A lineView may contain multiple logical lines (when merged by
-  // collapsed spans). The widgets for all of them need to be drawn.
-  function insertLineWidgets(cm, lineView, dims) {
-    insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
-    if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
-      insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false);
-  }
-
-  function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
-    if (!line.widgets) return;
-    var wrap = ensureLineWrapped(lineView);
-    for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
-      var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
-      if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true");
-      positionLineWidget(widget, node, lineView, dims);
-      cm.display.input.setUneditable(node);
-      if (allowAbove && widget.above)
-        wrap.insertBefore(node, lineView.gutter || lineView.text);
-      else
-        wrap.appendChild(node);
-      signalLater(widget, "redraw");
-    }
-  }
-
-  function positionLineWidget(widget, node, lineView, dims) {
-    if (widget.noHScroll) {
-      (lineView.alignable || (lineView.alignable = [])).push(node);
-      var width = dims.wrapperWidth;
-      node.style.left = dims.fixedPos + "px";
-      if (!widget.coverGutter) {
-        width -= dims.gutterTotalWidth;
-        node.style.paddingLeft = dims.gutterTotalWidth + "px";
-      }
-      node.style.width = width + "px";
-    }
-    if (widget.coverGutter) {
-      node.style.zIndex = 5;
-      node.style.position = "relative";
-      if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
-    }
-  }
-
-  // POSITION OBJECT
-
-  // A Pos instance represents a position within the text.
-  var Pos = CodeMirror.Pos = function(line, ch) {
-    if (!(this instanceof Pos)) return new Pos(line, ch);
-    this.line = line; this.ch = ch;
-  };
-
-  // Compare two positions, return 0 if they are the same, a negative
-  // number when a is less, and a positive number otherwise.
-  var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
-
-  function copyPos(x) {return Pos(x.line, x.ch);}
-  function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
-  function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
-
-  // INPUT HANDLING
-
-  function ensureFocus(cm) {
-    if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
-  }
-
-  function isReadOnly(cm) {
-    return cm.options.readOnly || cm.doc.cantEdit;
-  }
-
-  // This will be set to an array of strings when copying, so that,
-  // when pasting, we know what kind of selections the copied text
-  // was made out of.
-  var lastCopied = null;
-
-  function applyTextInput(cm, inserted, deleted, sel, origin) {
-    var doc = cm.doc;
-    cm.display.shift = false;
-    if (!sel) sel = doc.sel;
-
-    var paste = cm.state.pasteIncoming || origin == "paste";
-    var textLines = doc.splitLines(inserted), multiPaste = null;
-    // When pasing N lines into N selections, insert one line per selection
-    if (paste && sel.ranges.length > 1) {
-      if (lastCopied && lastCopied.join("\n") == inserted) {
-        if (sel.ranges.length % lastCopied.length == 0) {
-          multiPaste = [];
-          for (var i = 0; i < lastCopied.length; i++)
-            multiPaste.push(doc.splitLines(lastCopied[i]));
-        }
-      } else if (textLines.length == sel.ranges.length) {
-        multiPaste = map(textLines, function(l) { return [l]; });
-      }
-    }
-
-    // Normal behavior is to insert the new text into every selection
-    for (var i = sel.ranges.length - 1; i >= 0; i--) {
-      var range = sel.ranges[i];
-      var from = range.from(), to = range.to();
-      if (range.empty()) {
-        if (deleted && deleted > 0) // Handle deletion
-          from = Pos(from.line, from.ch - deleted);
-        else if (cm.state.overwrite && !paste) // Handle overwrite
-          to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
-      }
-      var updateInput = cm.curOp.updateInput;
-      var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
-                         origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
-      makeChange(cm.doc, changeEvent);
-      signalLater(cm, "inputRead", cm, changeEvent);
-    }
-    if (inserted && !paste)
-      triggerElectric(cm, inserted);
-
-    ensureCursorVisible(cm);
-    cm.curOp.updateInput = updateInput;
-    cm.curOp.typing = true;
-    cm.state.pasteIncoming = cm.state.cutIncoming = false;
-  }
-
-  function handlePaste(e, cm) {
-    var pasted = e.clipboardData && e.clipboardData.getData("text/plain");
-    if (pasted) {
-      e.preventDefault();
-      if (!isReadOnly(cm) && !cm.options.disableInput)
-        runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); });
-      return true;
-    }
-  }
-
-  function triggerElectric(cm, inserted) {
-    // When an 'electric' character is inserted, immediately trigger a reindent
-    if (!cm.options.electricChars || !cm.options.smartIndent) return;
-    var sel = cm.doc.sel;
-
-    for (var i = sel.ranges.length - 1; i >= 0; i--) {
-      var range = sel.ranges[i];
-      if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue;
-      var mode = cm.getModeAt(range.head);
-      var indented = false;
-      if (mode.electricChars) {
-        for (var j = 0; j < mode.electricChars.length; j++)
-          if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
-            indented = indentLine(cm, range.head.line, "smart");
-            break;
-          }
-      } else if (mode.electricInput) {
-        if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
-          indented = indentLine(cm, range.head.line, "smart");
-      }
-      if (indented) signalLater(cm, "electricInput", cm, range.head.line);
-    }
-  }
-
-  function copyableRanges(cm) {
-    var text = [], ranges = [];
-    for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
-      var line = cm.doc.sel.ranges[i].head.line;
-      var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
-      ranges.push(lineRange);
-      text.push(cm.getRange(lineRange.anchor, lineRange.head));
-    }
-    return {text: text, ranges: ranges};
-  }
-
-  function disableBrowserMagic(field) {
-    field.setAttribute("autocorrect", "off");
-    field.setAttribute("autocapitalize", "off");
-    field.setAttribute("spellcheck", "false");
-  }
-
-  // TEXTAREA INPUT STYLE
-
-  function TextareaInput(cm) {
-    this.cm = cm;
-    // See input.poll and input.reset
-    this.prevInput = "";
-
-    // Flag that indicates whether we expect input to appear real soon
-    // now (after some event like 'keypress' or 'input') and are
-    // polling intensively.
-    this.pollingFast = false;
-    // Self-resetting timeout for the poller
-    this.polling = new Delayed();
-    // Tracks when input.reset has punted to just putting a short
-    // string into the textarea instead of the full selection.
-    this.inaccurateSelection = false;
-    // Used to work around IE issue with selection being forgotten when focus moves away from textarea
-    this.hasSelection = false;
-    this.composing = null;
-  };
-
-  function hiddenTextarea() {
-    var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
-    var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
-    // The textarea is kept positioned near the cursor to prevent the
-    // fact that it'll be scrolled into view on input from scrolling
-    // our fake cursor out of view. On webkit, when wrap=off, paste is
-    // very slow. So make the area wide instead.
-    if (webkit) te.style.width = "1000px";
-    else te.setAttribute("wrap", "off");
-    // If border: 0; -- iOS fails to open keyboard (issue #1287)
-    if (ios) te.style.border = "1px solid black";
-    disableBrowserMagic(te);
-    return div;
-  }
-
-  TextareaInput.prototype = copyObj({
-    init: function(display) {
-      var input = this, cm = this.cm;
-
-      // Wraps and hides input textarea
-      var div = this.wrapper = hiddenTextarea();
-      // The semihidden textarea that is focused when the editor is
-      // focused, and receives input.
-      var te = this.textarea = div.firstChild;
-      display.wrapper.insertBefore(div, display.wrapper.firstChild);
-
-      // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
-      if (ios) te.style.width = "0px";
-
-      on(te, "input", function() {
-        if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null;
-        input.poll();
-      });
-
-      on(te, "paste", function(e) {
-        if (handlePaste(e, cm)) return true;
-
-        cm.state.pasteIncoming = true;
-        input.fastPoll();
-      });
-
-      function prepareCopyCut(e) {
-        if (cm.somethingSelected()) {
-          lastCopied = cm.getSelections();
-          if (input.inaccurateSelection) {
-            input.prevInput = "";
-            input.inaccurateSelection = false;
-            te.value = lastCopied.join("\n");
-            selectInput(te);
-          }
-        } else if (!cm.options.lineWiseCopyCut) {
-          return;
-        } else {
-          var ranges = copyableRanges(cm);
-          lastCopied = ranges.text;
-          if (e.type == "cut") {
-            cm.setSelections(ranges.ranges, null, sel_dontScroll);
-          } else {
-            input.prevInput = "";
-            te.value = ranges.text.join("\n");
-            selectInput(te);
-          }
-        }
-        if (e.type == "cut") cm.state.cutIncoming = true;
-      }
-      on(te, "cut", prepareCopyCut);
-      on(te, "copy", prepareCopyCut);
-
-      on(display.scroller, "paste", function(e) {
-        if (eventInWidget(display, e)) return;
-        cm.state.pasteIncoming = true;
-        input.focus();
-      });
-
-      // Prevent normal selection in the editor (we handle our own)
-      on(display.lineSpace, "selectstart", function(e) {
-        if (!eventInWidget(display, e)) e_preventDefault(e);
-      });
-
-      on(te, "compositionstart", function() {
-        var start = cm.getCursor("from");
-        if (input.composing) input.composing.range.clear()
-        input.composing = {
-          start: start,
-          range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
-        };
-      });
-      on(te, "compositionend", function() {
-        if (input.composing) {
-          input.poll();
-          input.composing.range.clear();
-          input.composing = null;
-        }
-      });
-    },
-
-    prepareSelection: function() {
-      // Redraw the selection and/or cursor
-      var cm = this.cm, display = cm.display, doc = cm.doc;
-      var result = prepareSelection(cm);
-
-      // Move the hidden textarea near the cursor to prevent scrolling artifacts
-      if (cm.options.moveInputWithCursor) {
-        var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
-        var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
-        result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
-                                            headPos.top + lineOff.top - wrapOff.top));
-        result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
-                                             headPos.left + lineOff.left - wrapOff.left));
-      }
-
-      return result;
-    },
-
-    showSelection: function(drawn) {
-      var cm = this.cm, display = cm.display;
-      removeChildrenAndAdd(display.cursorDiv, drawn.cursors);
-      removeChildrenAndAdd(display.selectionDiv, drawn.selection);
-      if (drawn.teTop != null) {
-        this.wrapper.style.top = drawn.teTop + "px";
-        this.wrapper.style.left = drawn.teLeft + "px";
-      }
-    },
-
-    // Reset the input to correspond to the selection (or to be empty,
-    // when not typing and nothing is selected)
-    reset: function(typing) {
-      if (this.contextMenuPending) return;
-      var minimal, selected, cm = this.cm, doc = cm.doc;
-      if (cm.somethingSelected()) {
-        this.prevInput = "";
-        var range = doc.sel.primary();
-        minimal = hasCopyEvent &&
-          (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
-        var content = minimal ? "-" : selected || cm.getSelection();
-        this.textarea.value = content;
-        if (cm.state.focused) selectInput(this.textarea);
-        if (ie && ie_version >= 9) this.hasSelection = content;
-      } else if (!typing) {
-        this.prevInput = this.textarea.value = "";
-        if (ie && ie_version >= 9) this.hasSelection = null;
-      }
-      this.inaccurateSelection = minimal;
-    },
-
-    getField: function() { return this.textarea; },
-
-    supportsTouch: function() { return false; },
-
-    focus: function() {
-      if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
-        try { this.textarea.focus(); }
-        catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
-      }
-    },
-
-    blur: function() { this.textarea.blur(); },
-
-    resetPosition: function() {
-      this.wrapper.style.top = this.wrapper.style.left = 0;
-    },
-
-    receivedFocus: function() { this.slowPoll(); },
-
-    // Poll for input changes, using the normal rate of polling. This
-    // runs as long as the editor is focused.
-    slowPoll: function() {
-      var input = this;
-      if (input.pollingFast) return;
-      input.polling.set(this.cm.options.pollInterval, function() {
-        input.poll();
-        if (input.cm.state.focused) input.slowPoll();
-      });
-    },
-
-    // When an event has just come in that is likely to add or change
-    // something in the input textarea, we poll faster, to ensure that
-    // the change appears on the screen quickly.
-    fastPoll: function() {
-      var missed = false, input = this;
-      input.pollingFast = true;
-      function p() {
-        var changed = input.poll();
-        if (!changed && !missed) {missed = true; input.polling.set(60, p);}
-        else {input.pollingFast = false; input.slowPoll();}
-      }
-      input.polling.set(20, p);
-    },
-
-    // Read input from the textarea, and update the document to match.
-    // When something is selected, it is present in the textarea, and
-    // selected (unless it is huge, in which case a placeholder is
-    // used). When nothing is selected, the cursor sits after previously
-    // seen text (can be empty), which is stored in prevInput (we must
-    // not reset the textarea when typing, because that breaks IME).
-    poll: function() {
-      var cm = this.cm, input = this.textarea, prevInput = this.prevInput;
-      // Since this is called a *lot*, try to bail out as cheaply as
-      // possible when it is clear that nothing happened. hasSelection
-      // will be the case when there is a lot of text in the textarea,
-      // in which case reading its value would be expensive.
-      if (this.contextMenuPending || !cm.state.focused ||
-          (hasSelection(input) && !prevInput && !this.composing) ||
-          isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)
-        return false;
-
-      var text = input.value;
-      // If nothing changed, bail.
-      if (text == prevInput && !cm.somethingSelected()) return false;
-      // Work around nonsensical selection resetting in IE9/10, and
-      // inexplicable appearance of private area unicode characters on
-      // some key combos in Mac (#2689).
-      if (ie && ie_version >= 9 && this.hasSelection === text ||
-          mac && /[\uf700-\uf7ff]/.test(text)) {
-        cm.display.input.reset();
-        return false;
-      }
-
-      if (cm.doc.sel == cm.display.selForContextMenu) {
-        var first = text.charCodeAt(0);
-        if (first == 0x200b && !prevInput) prevInput = "\u200b";
-        if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); }
-      }
-      // Find the part of the input that is actually new
-      var same = 0, l = Math.min(prevInput.length, text.length);
-      while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
-
-      var self = this;
-      runInOp(cm, function() {
-        applyTextInput(cm, text.slice(same), prevInput.length - same,
-                       null, self.composing ? "*compose" : null);
-
-        // Don't leave long text in the textarea, since it makes further polling slow
-        if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = "";
-        else self.prevInput = text;
-
-        if (self.composing) {
-          self.composing.range.clear();
-          self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"),
-                                             {className: "CodeMirror-composing"});
-        }
-      });
-      return true;
-    },
-
-    ensurePolled: function() {
-      if (this.pollingFast && this.poll()) this.pollingFast = false;
-    },
-
-    onKeyPress: function() {
-      if (ie && ie_version >= 9) this.hasSelection = null;
-      this.fastPoll();
-    },
-
-    onContextMenu: function(e) {
-      var input = this, cm = input.cm, display = cm.display, te = input.textarea;
-      var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
-      if (!pos || presto) return; // Opera is difficult.
-
-      // Reset the current text selection only if the click is done outside of the selection
-      // and 'resetSelectionOnContextMenu' option is true.
-      var reset = cm.options.resetSelectionOnContextMenu;
-      if (reset && cm.doc.sel.contains(pos) == -1)
-        operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
-
-      var oldCSS = te.style.cssText;
-      input.wrapper.style.position = "absolute";
-      te.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
-        "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
-        (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
-        "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
-      if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
-      display.input.focus();
-      if (webkit) window.scrollTo(null, oldScrollY);
-      display.input.reset();
-      // Adds "Select all" to context menu in FF
-      if (!cm.somethingSelected()) te.value = input.prevInput = " ";
-      input.contextMenuPending = true;
-      display.selForContextMenu = cm.doc.sel;
-      clearTimeout(display.detectingSelectAll);
-
-      // Select-all will be greyed out if there's nothing to select, so
-      // this adds a zero-width space so that we can later check whether
-      // it got selected.
-      function prepareSelectAllHack() {
-        if (te.selectionStart != null) {
-          var selected = cm.somethingSelected();
-          var extval = "\u200b" + (selected ? te.value : "");
-          te.value = "\u21da"; // Used to catch context-menu undo
-          te.value = extval;
-          input.prevInput = selected ? "" : "\u200b";
-          te.selectionStart = 1; te.selectionEnd = extval.length;
-          // Re-set this, in case some other handler touched the
-          // selection in the meantime.
-          display.selForContextMenu = cm.doc.sel;
-        }
-      }
-      function rehide() {
-        input.contextMenuPending = false;
-        input.wrapper.style.position = "relative";
-        te.style.cssText = oldCSS;
-        if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);
-
-        // Try to detect the user choosing select-all
-        if (te.selectionStart != null) {
-          if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
-          var i = 0, poll = function() {
-            if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
-                te.selectionEnd > 0 && input.prevInput == "\u200b")
-              operation(cm, commands.selectAll)(cm);
-            else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
-            else display.input.reset();
-          };
-          display.detectingSelectAll = setTimeout(poll, 200);
-        }
-      }
-
-      if (ie && ie_version >= 9) prepareSelectAllHack();
-      if (captureRightClick) {
-        e_stop(e);
-        var mouseup = function() {
-          off(window, "mouseup", mouseup);
-          setTimeout(rehide, 20);
-        };
-        on(window, "mouseup", mouseup);
-      } else {
-        setTimeout(rehide, 50);
-      }
-    },
-
-    readOnlyChanged: function(val) {
-      if (!val) this.reset();
-    },
-
-    setUneditable: nothing,
-
-    needsContentAttribute: false
-  }, TextareaInput.prototype);
-
-  // CONTENTEDITABLE INPUT STYLE
-
-  function ContentEditableInput(cm) {
-    this.cm = cm;
-    this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
-    this.polling = new Delayed();
-    this.gracePeriod = false;
-  }
-
-  ContentEditableInput.prototype = copyObj({
-    init: function(display) {
-      var input = this, cm = input.cm;
-      var div = input.div = display.lineDiv;
-      disableBrowserMagic(div);
-
-      on(div, "paste", function(e) { handlePaste(e, cm); })
-
-      on(div, "compositionstart", function(e) {
-        var data = e.data;
-        input.composing = {sel: cm.doc.sel, data: data, startData: data};
-        if (!data) return;
-        var prim = cm.doc.sel.primary();
-        var line = cm.getLine(prim.head.line);
-        var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length));
-        if (found > -1 && found <= prim.head.ch)
-          input.composing.sel = simpleSelection(Pos(prim.head.line, found),
-                                                Pos(prim.head.line, found + data.length));
-      });
-      on(div, "compositionupdate", function(e) {
-        input.composing.data = e.data;
-      });
-      on(div, "compositionend", function(e) {
-        var ours = input.composing;
-        if (!ours) return;
-        if (e.data != ours.startData && !/\u200b/.test(e.data))
-          ours.data = e.data;
-        // Need a small delay to prevent other code (input event,
-        // selection polling) from doing damage when fired right after
-        // compositionend.
-        setTimeout(function() {
-          if (!ours.handled)
-            input.applyComposition(ours);
-          if (input.composing == ours)
-            input.composing = null;
-        }, 50);
-      });
-
-      on(div, "touchstart", function() {
-        input.forceCompositionEnd();
-      });
-
-      on(div, "input", function() {
-        if (input.composing) return;
-        if (isReadOnly(cm) || !input.pollContent())
-          runInOp(input.cm, function() {regChange(cm);});
-      });
-
-      function onCopyCut(e) {
-        if (cm.somethingSelected()) {
-          lastCopied = cm.getSelections();
-          if (e.type == "cut") cm.replaceSelection("", null, "cut");
-        } else if (!cm.options.lineWiseCopyCut) {
-          return;
-        } else {
-          var ranges = copyableRanges(cm);
-          lastCopied = ranges.text;
-          if (e.type == "cut") {
-            cm.operation(function() {
-              cm.setSelections(ranges.ranges, 0, sel_dontScroll);
-              cm.replaceSelection("", null, "cut");
-            });
-          }
-        }
-        // iOS exposes the clipboard API, but seems to discard content inserted into it
-        if (e.clipboardData && !ios) {
-          e.preventDefault();
-          e.clipboardData.clearData();
-          e.clipboardData.setData("text/plain", lastCopied.join("\n"));
-        } else {
-          // Old-fashioned briefly-focus-a-textarea hack
-          var kludge = hiddenTextarea(), te = kludge.firstChild;
-          cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
-          te.value = lastCopied.join("\n");
-          var hadFocus = document.activeElement;
-          selectInput(te);
-          setTimeout(function() {
-            cm.display.lineSpace.removeChild(kludge);
-            hadFocus.focus();
-          }, 50);
-        }
-      }
-      on(div, "copy", onCopyCut);
-      on(div, "cut", onCopyCut);
-    },
-
-    prepareSelection: function() {
-      var result = prepareSelection(this.cm, false);
-      result.focus = this.cm.state.focused;
-      return result;
-    },
-
-    showSelection: function(info) {
-      if (!info || !this.cm.display.view.length) return;
-      if (info.focus) this.showPrimarySelection();
-      this.showMultipleSelections(info);
-    },
-
-    showPrimarySelection: function() {
-      var sel = window.getSelection(), prim = this.cm.doc.sel.primary();
-      var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset);
-      var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset);
-      if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
-          cmp(minPos(curAnchor, curFocus), prim.from()) == 0 &&
-          cmp(maxPos(curAnchor, curFocus), prim.to()) == 0)
-        return;
-
-      var start = posToDOM(this.cm, prim.from());
-      var end = posToDOM(this.cm, prim.to());
-      if (!start && !end) return;
-
-      var view = this.cm.display.view;
-      var old = sel.rangeCount && sel.getRangeAt(0);
-      if (!start) {
-        start = {node: view[0].measure.map[2], offset: 0};
-      } else if (!end) { // FIXME dangerously hacky
-        var measure = view[view.length - 1].measure;
-        var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
-        end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]};
-      }
-
-      try { var rng = range(start.node, start.offset, end.offset, end.node); }
-      catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
-      if (rng) {
-        sel.removeAllRanges();
-        sel.addRange(rng);
-        if (old && sel.anchorNode == null) sel.addRange(old);
-        else if (gecko) this.startGracePeriod();
-      }
-      this.rememberSelection();
-    },
-
-    startGracePeriod: function() {
-      var input = this;
-      clearTimeout(this.gracePeriod);
-      this.gracePeriod = setTimeout(function() {
-        input.gracePeriod = false;
-        if (input.selectionChanged())
-          input.cm.operation(function() { input.cm.curOp.selectionChanged = true; });
-      }, 20);
-    },
-
-    showMultipleSelections: function(info) {
-      removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
-      removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
-    },
-
-    rememberSelection: function() {
-      var sel = window.getSelection();
-      this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
-      this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
-    },
-
-    selectionInEditor: function() {
-      var sel = window.getSelection();
-      if (!sel.rangeCount) return false;
-      var node = sel.getRangeAt(0).commonAncestorContainer;
-      return contains(this.div, node);
-    },
-
-    focus: function() {
-      if (this.cm.options.readOnly != "nocursor") this.div.focus();
-    },
-    blur: function() { this.div.blur(); },
-    getField: function() { return this.div; },
-
-    supportsTouch: function() { return true; },
-
-    receivedFocus: function() {
-      var input = this;
-      if (this.selectionInEditor())
-        this.pollSelection();
-      else
-        runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; });
-
-      function poll() {
-        if (input.cm.state.focused) {
-          input.pollSelection();
-          input.polling.set(input.cm.options.pollInterval, poll);
-        }
-      }
-      this.polling.set(this.cm.options.pollInterval, poll);
-    },
-
-    selectionChanged: function() {
-      var sel = window.getSelection();
-      return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
-        sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset;
-    },
-
-    pollSelection: function() {
-      if (!this.composing && !this.gracePeriod && this.selectionChanged()) {
-        var sel = window.getSelection(), cm = this.cm;
-        this.rememberSelection();
-        var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
-        var head = domToPos(cm, sel.focusNode, sel.focusOffset);
-        if (anchor && head) runInOp(cm, function() {
-          setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll);
-          if (anchor.bad || head.bad) cm.curOp.selectionChanged = true;
-        });
-      }
-    },
-
-    pollContent: function() {
-      var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
-      var from = sel.from(), to = sel.to();
-      if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false;
-
-      var fromIndex;
-      if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
-        var fromLine = lineNo(display.view[0].line);
-        var fromNode = display.view[0].node;
-      } else {
-        var fromLine = lineNo(display.view[fromIndex].line);
-        var fromNode = display.view[fromIndex - 1].node.nextSibling;
-      }
-      var toIndex = findViewIndex(cm, to.line);
-      if (toIndex == display.view.length - 1) {
-        var toLine = display.viewTo - 1;
-        var toNode = display.lineDiv.lastChild;
-      } else {
-        var toLine = lineNo(display.view[toIndex + 1].line) - 1;
-        var toNode = display.view[toIndex + 1].node.previousSibling;
-      }
-
-      var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
-      var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
-      while (newText.length > 1 && oldText.length > 1) {
-        if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
-        else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; }
-        else break;
-      }
-
-      var cutFront = 0, cutEnd = 0;
-      var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length);
-      while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
-        ++cutFront;
-      var newBot = lst(newText), oldBot = lst(oldText);
-      var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
-                               oldBot.length - (oldText.length == 1 ? cutFront : 0));
-      while (cutEnd < maxCutEnd &&
-             newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
-        ++cutEnd;
-
-      newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd);
-      newText[0] = newText[0].slice(cutFront);
-
-      var chFrom = Pos(fromLine, cutFront);
-      var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0);
-      if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
-        replaceRange(cm.doc, newText, chFrom, chTo, "+input");
-        return true;
-      }
-    },
-
-    ensurePolled: function() {
-      this.forceCompositionEnd();
-    },
-    reset: function() {
-      this.forceCompositionEnd();
-    },
-    forceCompositionEnd: function() {
-      if (!this.composing || this.composing.handled) return;
-      this.applyComposition(this.composing);
-      this.composing.handled = true;
-      this.div.blur();
-      this.div.focus();
-    },
-    applyComposition: function(composing) {
-      if (isReadOnly(this.cm))
-        operation(this.cm, regChange)(this.cm)
-      else if (composing.data && composing.data != composing.startData)
-        operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel);
-    },
-
-    setUneditable: function(node) {
-      node.contentEditable = "false"
-    },
-
-    onKeyPress: function(e) {
-      e.preventDefault();
-      if (!isReadOnly(this.cm))
-        operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0);
-    },
-
-    readOnlyChanged: function(val) {
-      this.div.contentEditable = String(val != "nocursor")
-    },
-
-    onContextMenu: nothing,
-    resetPosition: nothing,
-
-    needsContentAttribute: true
-  }, ContentEditableInput.prototype);
-
-  function posToDOM(cm, pos) {
-    var view = findViewForLine(cm, pos.line);
-    if (!view || view.hidden) return null;
-    var line = getLine(cm.doc, pos.line);
-    var info = mapFromLineView(view, line, pos.line);
-
-    var order = getOrder(line), side = "left";
-    if (order) {
-      var partPos = getBidiPartAt(order, pos.ch);
-      side = partPos % 2 ? "right" : "left";
-    }
-    var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
-    result.offset = result.collapse == "right" ? result.end : result.start;
-    return result;
-  }
-
-  function badPos(pos, bad) { if (bad) pos.bad = true; return pos; }
-
-  function domToPos(cm, node, offset) {
-    var lineNode;
-    if (node == cm.display.lineDiv) {
-      lineNode = cm.display.lineDiv.childNodes[offset];
-      if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true);
-      node = null; offset = 0;
-    } else {
-      for (lineNode = node;; lineNode = lineNode.parentNode) {
-        if (!lineNode || lineNode == cm.display.lineDiv) return null;
-        if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break;
-      }
-    }
-    for (var i = 0; i < cm.display.view.length; i++) {
-      var lineView = cm.display.view[i];
-      if (lineView.node == lineNode)
-        return locateNodeInLineView(lineView, node, offset);
-    }
-  }
-
-  function locateNodeInLineView(lineView, node, offset) {
-    var wrapper = lineView.text.firstChild, bad = false;
-    if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true);
-    if (node == wrapper) {
-      bad = true;
-      node = wrapper.childNodes[offset];
-      offset = 0;
-      if (!node) {
-        var line = lineView.rest ? lst(lineView.rest) : lineView.line;
-        return badPos(Pos(lineNo(line), line.text.length), bad);
-      }
-    }
-
-    var textNode = node.nodeType == 3 ? node : null, topNode = node;
-    if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
-      textNode = node.firstChild;
-      if (offset) offset = textNode.nodeValue.length;
-    }
-    while (topNode.parentNode != wrapper) topNode = topNode.parentNode;
-    var measure = lineView.measure, maps = measure.maps;
-
-    function find(textNode, topNode, offset) {
-      for (var i = -1; i < (maps ? maps.length : 0); i++) {
-        var map = i < 0 ? measure.map : maps[i];
-        for (var j = 0; j < map.length; j += 3) {
-          var curNode = map[j + 2];
-          if (curNode == textNode || curNode == topNode) {
-            var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
-            var ch = map[j] + offset;
-            if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)];
-            return Pos(line, ch);
-          }
-        }
-      }
-    }
-    var found = find(textNode, topNode, offset);
-    if (found) return badPos(found, bad);
-
-    // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
-    for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
-      found = find(after, after.firstChild, 0);
-      if (found)
-        return badPos(Pos(found.line, found.ch - dist), bad);
-      else
-        dist += after.textContent.length;
-    }
-    for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) {
-      found = find(before, before.firstChild, -1);
-      if (found)
-        return badPos(Pos(found.line, found.ch + dist), bad);
-      else
-        dist += after.textContent.length;
-    }
-  }
-
-  function domTextBetween(cm, from, to, fromLine, toLine) {
-    var text = "", closing = false, lineSep = cm.doc.lineSeparator();
-    function recognizeMarker(id) { return function(marker) { return marker.id == id; }; }
-    function walk(node) {
-      if (node.nodeType == 1) {
-        var cmText = node.getAttribute("cm-text");
-        if (cmText != null) {
-          if (cmText == "") cmText = node.textContent.replace(/\u200b/g, "");
-          text += cmText;
-          return;
-        }
-        var markerID = node.getAttribute("cm-marker"), range;
-        if (markerID) {
-          var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
-          if (found.length && (range = found[0].find()))
-            text += getBetween(cm.doc, range.from, range.to).join(lineSep);
-          return;
-        }
-        if (node.getAttribute("contenteditable") == "false") return;
-        for (var i = 0; i < node.childNodes.length; i++)
-          walk(node.childNodes[i]);
-        if (/^(pre|div|p)$/i.test(node.nodeName))
-          closing = true;
-      } else if (node.nodeType == 3) {
-        var val = node.nodeValue;
-        if (!val) return;
-        if (closing) {
-          text += lineSep;
-          closing = false;
-        }
-        text += val;
-      }
-    }
-    for (;;) {
-      walk(from);
-      if (from == to) break;
-      from = from.nextSibling;
-    }
-    return text;
-  }
-
-  CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
-
-  // SELECTION / CURSOR
-
-  // Selection objects are immutable. A new one is created every time
-  // the selection changes. A selection is one or more non-overlapping
-  // (and non-touching) ranges, sorted, and an integer that indicates
-  // which one is the primary selection (the one that's scrolled into
-  // view, that getCursor returns, etc).
-  function Selection(ranges, primIndex) {
-    this.ranges = ranges;
-    this.primIndex = primIndex;
-  }
-
-  Selection.prototype = {
-    primary: function() { return this.ranges[this.primIndex]; },
-    equals: function(other) {
-      if (other == this) return true;
-      if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
-      for (var i = 0; i < this.ranges.length; i++) {
-        var here = this.ranges[i], there = other.ranges[i];
-        if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
-      }
-      return true;
-    },
-    deepCopy: function() {
-      for (var out = [], i = 0; i < this.ranges.length; i++)
-        out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
-      return new Selection(out, this.primIndex);
-    },
-    somethingSelected: function() {
-      for (var i = 0; i < this.ranges.length; i++)
-        if (!this.ranges[i].empty()) return true;
-      return false;
-    },
-    contains: function(pos, end) {
-      if (!end) end = pos;
-      for (var i = 0; i < this.ranges.length; i++) {
-        var range = this.ranges[i];
-        if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
-          return i;
-      }
-      return -1;
-    }
-  };
-
-  function Range(anchor, head) {
-    this.anchor = anchor; this.head = head;
-  }
-
-  Range.prototype = {
-    from: function() { return minPos(this.anchor, this.head); },
-    to: function() { return maxPos(this.anchor, this.head); },
-    empty: function() {
-      return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
-    }
-  };
-
-  // Take an unsorted, potentially overlapping set of ranges, and
-  // build a selection out of it. 'Consumes' ranges array (modifying
-  // it).
-  function normalizeSelection(ranges, primIndex) {
-    var prim = ranges[primIndex];
-    ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
-    primIndex = indexOf(ranges, prim);
-    for (var i = 1; i < ranges.length; i++) {
-      var cur = ranges[i], prev = ranges[i - 1];
-      if (cmp(prev.to(), cur.from()) >= 0) {
-        var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
-        var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
-        if (i <= primIndex) --primIndex;
-        ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
-      }
-    }
-    return new Selection(ranges, primIndex);
-  }
-
-  function simpleSelection(anchor, head) {
-    return new Selection([new Range(anchor, head || anchor)], 0);
-  }
-
-  // Most of the external API clips given positions to make sure they
-  // actually exist within the document.
-  function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
-  function clipPos(doc, pos) {
-    if (pos.line < doc.first) return Pos(doc.first, 0);
-    var last = doc.first + doc.size - 1;
-    if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
-    return clipToLen(pos, getLine(doc, pos.line).text.length);
-  }
-  function clipToLen(pos, linelen) {
-    var ch = pos.ch;
-    if (ch == null || ch > linelen) return Pos(pos.line, linelen);
-    else if (ch < 0) return Pos(pos.line, 0);
-    else return pos;
-  }
-  function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
-  function clipPosArray(doc, array) {
-    for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
-    return out;
-  }
-
-  // SELECTION UPDATES
-
-  // The 'scroll' parameter given to many of these indicated whether
-  // the new cursor position should be scrolled into view after
-  // modifying the selection.
-
-  // If shift is held or the extend flag is set, extends a range to
-  // include a given position (and optionally a second position).
-  // Otherwise, simply returns the range between the given positions.
-  // Used for cursor motion and such.
-  function extendRange(doc, range, head, other) {
-    if (doc.cm && doc.cm.display.shift || doc.extend) {
-      var anchor = range.anchor;
-      if (other) {
-        var posBefore = cmp(head, anchor) < 0;
-        if (posBefore != (cmp(other, anchor) < 0)) {
-          anchor = head;
-          head = other;
-        } else if (posBefore != (cmp(head, other) < 0)) {
-          head = other;
-        }
-      }
-      return new Range(anchor, head);
-    } else {
-      return new Range(other || head, head);
-    }
-  }
-
-  // Extend the primary selection range, discard the rest.
-  function extendSelection(doc, head, other, options) {
-    setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
-  }
-
-  // Extend all selections (pos is an array of selections with length
-  // equal the number of selections)
-  function extendSelections(doc, heads, options) {
-    for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
-      out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
-    var newSel = normalizeSelection(out, doc.sel.primIndex);
-    setSelection(doc, newSel, options);
-  }
-
-  // Updates a single range in the selection.
-  function replaceOneSelection(doc, i, range, options) {
-    var ranges = doc.sel.ranges.slice(0);
-    ranges[i] = range;
-    setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
-  }
-
-  // Reset the selection to a single range.
-  function setSimpleSelection(doc, anchor, head, options) {
-    setSelection(doc, simpleSelection(anchor, head), options);
-  }
-
-  // Give beforeSelectionChange handlers a change to influence a
-  // selection update.
-  function filterSelectionChange(doc, sel) {
-    var obj = {
-      ranges: sel.ranges,
-      update: function(ranges) {
-        this.ranges = [];
-        for (var i = 0; i < ranges.length; i++)
-          this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
-                                     clipPos(doc, ranges[i].head));
-      }
-    };
-    signal(doc, "beforeSelectionChange", doc, obj);
-    if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
-    if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
-    else return sel;
-  }
-
-  function setSelectionReplaceHistory(doc, sel, options) {
-    var done = doc.history.done, last = lst(done);
-    if (last && last.ranges) {
-      done[done.length - 1] = sel;
-      setSelectionNoUndo(doc, sel, options);
-    } else {
-      setSelection(doc, sel, options);
-    }
-  }
-
-  // Set a new selection.
-  function setSelection(doc, sel, options) {
-    setSelectionNoUndo(doc, sel, options);
-    addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
-  }
-
-  function setSelectionNoUndo(doc, sel, options) {
-    if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
-      sel = filterSelectionChange(doc, sel);
-
-    var bias = options && options.bias ||
-      (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
-    setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
-
-    if (!(options && options.scroll === false) && doc.cm)
-      ensureCursorVisible(doc.cm);
-  }
-
-  function setSelectionInner(doc, sel) {
-    if (sel.equals(doc.sel)) return;
-
-    doc.sel = sel;
-
-    if (doc.cm) {
-      doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
-      signalCursorActivity(doc.cm);
-    }
-    signalLater(doc, "cursorActivity", doc);
-  }
-
-  // Verify that the selection does not partially select any atomic
-  // marked ranges.
-  function reCheckSelection(doc) {
-    setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
-  }
-
-  // Return a selection that does not partially select any atomic
-  // ranges.
-  function skipA

<TRUNCATED>

[26/27] brooklyn-ui git commit: This closes #7

Posted by he...@apache.org.
This closes #7


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/e1646d73
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/e1646d73
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/e1646d73

Branch: refs/heads/master
Commit: e1646d733aaa0be281da891c56f999b2bb24fc9f
Parents: b7954f1 dfc2d21
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 18 09:12:08 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 18 09:12:08 2016 +0000

----------------------------------------------------------------------
 src/main/license/source-inclusions.yaml         |    3 +
 src/main/webapp/assets/css/brooklyn.css         |   21 +-
 .../webapp/assets/css/codemirror-brooklyn.css   |   14 +
 .../img/Apache-Brooklyn-Logo-200px-wide.png     |  Bin 0 -> 4256 bytes
 .../img/Apache-Brooklyn-Logo-300px-wide.png     |  Bin 0 -> 6068 bytes
 .../assets/img/Apache-Brooklyn-Logo_highres.png |  Bin 0 -> 42890 bytes
 .../img/apache-brooklyn-feather-atop-720px.png  |  Bin 0 -> 72926 bytes
 .../assets/js/addon/display/placeholder.js      |   60 -
 .../webapp/assets/js/addon/hint/anyword-hint.js |   41 -
 .../webapp/assets/js/addon/hint/show-hint.js    |  386 -
 src/main/webapp/assets/js/config.js             |   16 +-
 src/main/webapp/assets/js/lib/codemirror.js     | 8835 ------------------
 src/main/webapp/assets/js/libs/codemirror.js    | 8835 ++++++++++++++++++
 .../codemirror/addon/display/placeholder.js     |   60 +
 .../libs/codemirror/addon/hint/anyword-hint.js  |   41 +
 .../js/libs/codemirror/addon/hint/show-hint.js  |  386 +
 .../assets/js/libs/codemirror/mode/yaml/yaml.js |  117 +
 .../assets/js/libs/font-awesome/HELP-US-OUT.txt |    7 +
 .../js/libs/font-awesome/css/font-awesome.css   | 2086 +++++
 .../libs/font-awesome/css/font-awesome.min.css  |    4 +
 .../js/libs/font-awesome/fonts/FontAwesome.otf  |  Bin 0 -> 109688 bytes
 .../font-awesome/fonts/fontawesome-webfont.eot  |  Bin 0 -> 70807 bytes
 .../font-awesome/fonts/fontawesome-webfont.svg  |  655 ++
 .../font-awesome/fonts/fontawesome-webfont.ttf  |  Bin 0 -> 142072 bytes
 .../font-awesome/fonts/fontawesome-webfont.woff |  Bin 0 -> 83588 bytes
 .../fonts/fontawesome-webfont.woff2             |  Bin 0 -> 66624 bytes
 .../js/libs/font-awesome/less/animated.less     |   34 +
 .../libs/font-awesome/less/bordered-pulled.less |   25 +
 .../assets/js/libs/font-awesome/less/core.less  |   12 +
 .../js/libs/font-awesome/less/fixed-width.less  |    6 +
 .../js/libs/font-awesome/less/font-awesome.less |   17 +
 .../assets/js/libs/font-awesome/less/icons.less |  697 ++
 .../js/libs/font-awesome/less/larger.less       |   13 +
 .../assets/js/libs/font-awesome/less/list.less  |   19 +
 .../js/libs/font-awesome/less/mixins.less       |   26 +
 .../assets/js/libs/font-awesome/less/path.less  |   15 +
 .../libs/font-awesome/less/rotated-flipped.less |   20 +
 .../js/libs/font-awesome/less/stacked.less      |   20 +
 .../js/libs/font-awesome/less/variables.less    |  708 ++
 .../js/libs/font-awesome/scss/_animated.scss    |   34 +
 .../font-awesome/scss/_bordered-pulled.scss     |   25 +
 .../assets/js/libs/font-awesome/scss/_core.scss |   12 +
 .../js/libs/font-awesome/scss/_fixed-width.scss |    6 +
 .../js/libs/font-awesome/scss/_icons.scss       |  697 ++
 .../js/libs/font-awesome/scss/_larger.scss      |   13 +
 .../assets/js/libs/font-awesome/scss/_list.scss |   19 +
 .../js/libs/font-awesome/scss/_mixins.scss      |   26 +
 .../assets/js/libs/font-awesome/scss/_path.scss |   15 +
 .../font-awesome/scss/_rotated-flipped.scss     |   20 +
 .../js/libs/font-awesome/scss/_stacked.scss     |   20 +
 .../js/libs/font-awesome/scss/_variables.scss   |  708 ++
 .../js/libs/font-awesome/scss/font-awesome.scss |   17 +
 src/main/webapp/assets/js/mode/yaml/yaml.js     |  117 -
 .../brooklyn-yaml-completion-proposals.js       |  372 +
 .../js/util/code-complete/js-yaml-parser.js     |   48 +
 src/main/webapp/assets/js/view/editor.js        |   29 +-
 src/main/webapp/assets/tpl/editor/page.html     |    8 +-
 src/main/webapp/index.html                      |    1 +
 src/test/javascript/config.txt                  |    8 +-
 59 files changed, 15915 insertions(+), 9459 deletions(-)
----------------------------------------------------------------------



[09/27] brooklyn-ui git commit: app-add-wizard - remove tabs and a whole lot of code to support that, and allow "Open in Composer" for normal items, not just templates

Posted by he...@apache.org.
app-add-wizard - remove tabs and a whole lot of code to support that,
and allow "Open in Composer" for normal items, not just templates


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/9c6c06c9
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/9c6c06c9
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/9c6c06c9

Branch: refs/heads/master
Commit: 9c6c06c94212faaaf1d456a974820941ae08f353
Parents: 9d3d9bb
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 02:09:59 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 .../assets/js/view/application-add-wizard.js    | 204 ++++---------------
 .../tpl/app-add-wizard/create-entity-entry.html |  64 ------
 .../assets/tpl/app-add-wizard/create.html       |  46 +----
 .../assets/tpl/app-add-wizard/modal-wizard.html |   2 +-
 4 files changed, 42 insertions(+), 274 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/9c6c06c9/src/main/webapp/assets/js/view/application-add-wizard.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/application-add-wizard.js b/src/main/webapp/assets/js/view/application-add-wizard.js
index 62d4db2..1174c5e 100644
--- a/src/main/webapp/assets/js/view/application-add-wizard.js
+++ b/src/main/webapp/assets/js/view/application-add-wizard.js
@@ -16,17 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
 */
+
 /**
- * Builds a Twitter Bootstrap modal as the framework for a Wizard.
- * Also creates an empty Application model.
+ * Supplies a modal (wizardy) with a list of apps a user can pick.
+ * Templates (items with yaml and with a location) go to composer, 
+ * other items (java, or yaml without a location) go to next *or* open in composer. 
  */
+ 
 define([
     "underscore", "jquery", "backbone", "brooklyn-utils", "js-yaml", "codemirror",
     "model/entity", "model/application", "model/location", "model/catalog-application",
     "text!tpl/app-add-wizard/modal-wizard.html",
     "text!tpl/app-add-wizard/create.html",
     "text!tpl/app-add-wizard/create-step-template-entry.html", 
-    "text!tpl/app-add-wizard/create-entity-entry.html", 
     "text!tpl/app-add-wizard/required-config-entry.html",
     "text!tpl/app-add-wizard/edit-config-entry.html",
     "text!tpl/app-add-wizard/deploy.html",
@@ -40,7 +42,7 @@ define([
     "codemirror-addon-display-placeholder",
     "bootstrap"
 ], function (_, $, Backbone, Util, JsYaml, CodeMirror, Entity, Application, Location, CatalogApplication,
-             ModalHtml, CreateHtml, CreateStepTemplateEntryHtml, CreateEntityEntryHtml,
+             ModalHtml, CreateHtml, CreateStepTemplateEntryHtml, 
              RequiredConfigEntryHtml, EditConfigEntryHtml, DeployHtml,
              DeployVersionOptionHtml, DeployLocationRowHtml, DeployLocationOptionHtml
 ) {
@@ -112,7 +114,6 @@ define([
             this.model = {}
             this.model.spec = new Application.Spec;
             this.model.yaml = "";
-            this.model.mode = "template";  // or "yaml" or "other"
             this.currentStep = 0;
             this.steps = [
                           {
@@ -166,7 +167,7 @@ define([
             
             setVisibility(this.$("#prev_step"), (this.currentStep > 0))
 
-            this.isTemplate = false;
+            var isTemplateWithLocation = false;
             {
                 var yaml = (this.currentView && this.currentView.selectedTemplate && this.currentView.selectedTemplate.yaml);
                 if (yaml) {
@@ -185,7 +186,7 @@ define([
                             }
                           }
                         }
-                        this.isTemplate = (hasLocation ? true : false);
+                        isTemplateWithLocation = (hasLocation ? true : false);
                     } catch (e) {
                         log("Warning: could not parse yaml template of selected item")
                         log(yaml);
@@ -193,41 +194,27 @@ define([
                 }
             }
             
-            // next shown for first step, but not for yaml
-            var nextVisible = (this.currentStep < 1) && (this.model.mode != "yaml") && (!this.isTemplate);
-            setVisibility(this.$("#next_step"), nextVisible)
+            // preview (aka "Open in Composer") enabled and shown always
+            setVisibility(this.$("#preview_step"), true);
+            setEnablement(this.$("#preview_step"), true)
             
-            // preview (aka "Open in Composer") shown for step 2 or for template (but again, not yaml)
-            var previewVisible = (((this.currentStep < 1) && this.isTemplate) || (this.currentStep == 1)) && (this.model.mode != "yaml")
-            setVisibility(this.$("#preview_step"), previewVisible)
+            // next shown for first step, but not for templates
+            var nextVisible = (this.currentStep < 1) && (!this.isTemplate);
+            setVisibility(this.$("#next_step"), nextVisible);
             
             // now set next/preview enablement
-            if (nextVisible || previewVisible) {
-                var nextEnabled = true;
-                if (this.currentStep==0 && this.model.mode=="template" && currentStepObj && currentStepObj.view) {
-                    // disable if this is template selction (lozenge) view, and nothing is selected
-                    if (! currentStepObj.view.selectedTemplate)
-                        nextEnabled = false;
-                }
-                
-                if (nextVisible)
-                    setEnablement(this.$("#next_step"), nextEnabled)
-                if (previewVisible)
-                    setEnablement(this.$("#preview_step"), nextEnabled)
+            var nextEnabled = true;
+            if (this.currentStep==0 && currentStepObj && currentStepObj.view) {
+                // disable if nothing is selected in template (app lozenge list) view
+                if (! currentStepObj.view.selectedTemplate)
+                    nextEnabled = false;
             }
+                
+            if (nextVisible) setEnablement(this.$("#next_step"), nextEnabled)
             
-            // finish from config step, preview step, and from first step if yaml tab selected (and valid)
+            // finish ("deploy") is shown on the config step
             var finishVisible = (this.currentStep >= 1);
             var finishEnabled = finishVisible;
-            if (!finishEnabled && this.currentStep==0) {
-                if (this.model.mode == "yaml") {
-                    // should do better validation than non-empty
-                    finishVisible = true;
-                    if (self.editor && self.editor && self.editor.getValue()) {
-                        finishEnabled = true;
-                    }
-                }
-            }
             setVisibility(this.$("#finish_step"), finishVisible)
             setEnablement(this.$("#finish_step"), finishEnabled)
         },
@@ -238,13 +225,9 @@ define([
             $modal.fadeTo(500,0.5);
             
             var yaml;
-            if (this.model.mode == "yaml") {
-                yaml = this.model.yaml;
-            } else {
-                // Drop any "None" locations.
-                this.model.spec.pruneLocations();
-                yaml = JsYaml.safeDump(oldSpecToCamp(this.model.spec.toJSON()));
-            }
+            // Drop any "None" locations.
+            this.model.spec.pruneLocations();
+            yaml = JsYaml.safeDump(oldSpecToCamp(this.model.spec.toJSON()));
 
             $.ajax({
                 url:'/v1/applications',
@@ -304,24 +287,21 @@ define([
             }
         },
         previewStep:function () {
-            if (this.currentView.validate()) {
-                if (this.isTemplate) {
-                    // it's a yaml catalog *template* (because it includes a location); go to composer
+            // no need for validation if going to composer
+            if (this.currentStep==0) {
+                // from first step, composer should load yaml from the catalog item
+                if (this.currentView.selectedTemplate && this.currentView.selectedTemplate.id) {
                     this.redirectToEditorTabToDeployId(this.currentView.selectedTemplate.id);
                 } else {
-                    var yaml;
-                    if (this.model.mode == "yaml") {
-                        yaml = this.model.yaml;
-                    } else {
-                        // Drop any "None" locations.
-                        this.model.spec.pruneLocations();
-                        yaml = JsYaml.safeDump(oldSpecToCamp(this.model.spec.toJSON()));
-                    }
-    
-                    this.redirectToEditorTabToDeployYaml(yaml);
+                    this.redirectToEditorTabToDeployId();
                 }
             } else {
-                // call to validate should showFailure
+                // on second step we generate yaml
+                // Drop any "None" locations.
+                this.model.spec.pruneLocations();
+                var yaml = JsYaml.safeDump(oldSpecToCamp(this.model.spec.toJSON()));
+
+                this.redirectToEditorTabToDeployYaml(yaml);
             }
         },
         finishStep:function () {
@@ -351,19 +331,12 @@ define([
     ModalWizard.StepCreate = Backbone.View.extend({
         className:'modal-body',
         events:{
-            'click #add-app-entity':'addEntityBox',
-            'click .editable-entity-heading':'expandEntity',
-            'click .remove-entity-button':'removeEntityClick',
-            'click .editable-entity-button':'saveEntityClick',
             'click #remove-config':'removeConfigRow',
             'click #add-config':'addConfigRow',
             'click .template-lozenge':'templateClick',
             'keyup .text-filter input':'applyFilter',
             'change .text-filter input':'applyFilter',
             'paste .text-filter input':'applyFilter',
-            'keyup #yaml_code':'onYamlCodeChange',
-            'change #yaml_code':'onYamlCodeChange',
-            'paste #yaml_code':'onYamlCodeChange',
             'shown a[data-toggle="tab"]':'onTabChange',
             'click #templateTab #catalog-add':'switchToCatalogAdd',
             'click #templateTab #catalog-yaml':'redirectToEditorTab'
@@ -376,15 +349,11 @@ define([
 
             this.$el.html(this.template({}))
 
-            // for building from entities
-            this.addEntityBox()
-
             // TODO: Make into models, allow options to override, then pass in in test
             // with overrridden url. Can then think about fixing tests in application-add-wizard-spec.js.
             $.get('/v1/catalog/entities', {}, function (result) {
                 self.catalogEntityItems = result
                 self.catalogEntityIds = _.map(result, function(item) { return item.id })
-                self.$(".entity-type-input").typeahead().data('typeahead').source = self.catalogEntityIds
             });
             
             this.options.catalog.applications = new CatalogApplication.Collection();
@@ -393,7 +362,6 @@ define([
                     allVersions: true
                 }),
                 success: function (collection, response, options) {
-                    self.$("#appClassTab .application-type-input").typeahead().data('typeahead').source = collection.getTypes();
                     $('#catalog-applications-throbber').hide();
                     $('#catalog-applications-empty').hide();
                     if (collection.size() > 0) {
@@ -429,19 +397,6 @@ define([
                 $("li.text-filter").hide()
             }
 
-            if (tabText=="YAML") {
-                // TODO this mode no longer used
-                this.model.mode = "yaml";
-            } else if (tabText=="Template") {
-                this.model.mode = "template";
-            } else {
-                this.model.mode = "other";
-            }
-
-            if (this.options.wizard)
-                this.options.wizard.updateButtonVisibility();
-        },
-        onYamlCodeChange: function() {
             if (this.options.wizard)
                 this.options.wizard.updateButtonVisibility();
         },
@@ -450,10 +405,6 @@ define([
             $modal.modal('hide');
             window.location.href="#v1/catalog/new";
         },
-        showYamlTab: function() {
-            $("ul#app-add-wizard-create-tab").find("a[href='#yamlTab']").tab('show');
-            $("#yaml_code").focus();
-        },
         redirectToEditorTab: function() {
             this.redirectToEditorTabToDeployId();
         },
@@ -500,11 +451,6 @@ define([
                     name: $tl.data("name"),
                     yaml: $tl.data("yaml"),
                 };
-                if (this.selectedTemplate.yaml) {
-                    $("textarea#yaml_code").val(this.selectedTemplate.yaml);
-                } else {
-                    $("textarea#yaml_code").val("services:\n- type: "+this.selectedTemplate.type);
-                }
             } else {
                 this.selectedTemplate = null;
             }
@@ -512,32 +458,6 @@ define([
             if (this.options.wizard)
                 this.options.wizard.updateButtonVisibility();
         },
-        expandEntity:function (event) {
-            $(event.currentTarget).next().show('fast').delay(1000).prev().hide('slow')
-        },
-        saveEntityClick:function (event) {
-            this.saveEntity($(event.currentTarget).closest(".editable-entity-group"));
-        },
-        saveEntity:function ($entityGroup) {
-            var that = this
-            var name = $('#entity-name',$entityGroup).val()
-            var type = $('#entity-type',$entityGroup).val()
-            if (type=="" || !_.contains(that.catalogEntityIds, type)) {
-                that.showFailure("Missing or invalid type");
-                return false
-            }
-            var saveTarget = this.model.spec.get("entities")[$entityGroup.index()];
-            this.model.spec.set("type", null)
-            saveTarget.name = name
-            saveTarget.type = type
-            saveTarget.config = this.getConfigMap($entityGroup)
-
-            if (name=="") name=type;
-            if (name=="") name="<i>(new entity)</i>";
-            $('#entity-name-header',$entityGroup).html( name )
-            $('.editable-entity-body',$entityGroup).prev().show('fast').next().hide('fast')
-            return true;
-        },
         getConfigMap:function (root) {
             var map = {}
             $('.app-add-wizard-config-entry',root).each( function (index,elt) {
@@ -572,22 +492,12 @@ define([
             this.model.spec.set("type", type);
             return true;
         },
-        addEntityBox:function () {
-            var entity = new Entity.Model
-            this.model.spec.addEntity( entity )
-            this.addEntityHtml($('#entitiesAccordionish', this.$el), entity)
-        },
         addEntityHtml:function (parent, entity) {
             var $entity = _.template(CreateEntityEntryHtml, {})
             var that = this
             parent.append($entity)
             parent.children().last().find('.entity-type-input').typeahead({ source: that.catalogEntityIds })
         },
-        removeEntityClick:function (event) {
-            var $entityGroup = $(event.currentTarget).parent().parent().parent();
-            this.model.spec.removeEntityIndex($entityGroup.index())
-            $entityGroup.remove()
-        },
 
         addConfigRow:function (event) {
             var $row = _.template(EditConfigEntryHtml, {})
@@ -599,44 +509,10 @@ define([
 
         validate:function () {
             var that = this;
-            var tabName = $('#app-add-wizard-create-tab li[class="active"] a').attr('href');
-            if (tabName=='#entitiesTab') {
-                delete this.model.spec.attributes["id"]
-                var allokay = true
-                $($.find('.editable-entity-group')).each(
-                    function (i,$entityGroup) {
-                        allokay = that.saveEntity($($entityGroup)) & allokay
-                    })
-                if (!allokay) return false;
-                if (this.model.spec.get("entities") && this.model.spec.get("entities").length > 0) {
-                    this.model.spec.set("type", null);
-                    return true;
-                }
-            } else if (tabName=='#templateTab') {
-                delete this.model.spec.attributes["id"]
-                if (this.saveTemplate()) {
-                    this.model.spec.set("entities", []);
-                    return true
-                }
-            } else if (tabName=='#appClassTab') {
-                delete this.model.spec.attributes["id"]
-                if (this.saveAppClass()) {
-                    this.model.spec.set("entities", []);
-                    return true
-                }
-            } else if (tabName=='#yamlTab') {
-                if (self.editor !== null) {
-                    this.model.yaml = self.editor.getValue();
-                    if (this.model.yaml) {
-                        return true;
-                    }
-                } else {
-                    console.info("No text in the editor!");
-                }
-            } else {
-                console.info("NOT IMPLEMENTED YET")
-                // TODO - other tabs not implemented yet 
-                // do nothing, show error return false below
+            delete this.model.spec.attributes["id"]
+            if (this.saveTemplate()) {
+                this.model.spec.set("entities", []);
+                return true
             }
             this.showFailure("Invalid application type/spec");
             return false

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/9c6c06c9/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html b/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html
deleted file mode 100644
index 6f334fd..0000000
--- a/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html
+++ /dev/null
@@ -1,64 +0,0 @@
-
-<!--
-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.
--->
-
-<div class="editable-entity-group">
-    <div class="editable-entity-heading hide">
-        <span id="entity-name-header"><i>(new entity)</i></span>
-        <div style="float: right;">
-            <button class="btn btn-info btn-mini"><i class="icon-chevron-down"></i></button>
-        </div>
-    </div>
-    
-    <div class="editable-entity-body">
-        <div class="entity-info-message label-message hide">
-            <span class="label-important">ERROR</span>  Invalid entity/type definition
-        </div>
-        
-        <div style="float: right;">
-            <button class="btn btn-info btn-mini remove-entity-button">
-                <i class="icon-remove"></i> </button>
-            <button class="btn btn-info btn-mini editable-entity-button">
-                <i class="icon-chevron-up"></i> </button>
-        </div>
-        <div class="control-group">
-            <div class="controls">
-                <div class="app-add-wizard-create-entity-label">Name</div>
-                <input id="entity-name" type="text" class="input-large app-add-wizard-create-entity-input" name="name" placeholder="name">
-            </div>
-        </div>
-
-        <div class="control-group">
-            <div class="controls">
-                <div class="app-add-wizard-create-entity-label">Type</div>
-                <input id="entity-type" type="text" name="type" class="input-large app-add-wizard-create-entity-input entity-type-input" placeholder="type">
-            </div>
-        </div>
-
-        <div class="control-group">
-            <div class="app-add-wizard-create-entity-label-newline">Configuration</div>
-            <div class="controls">
-            </div>
-            <div>
-                <button id="add-config" class="btn btn-mini btn-info">
-                    Add Configuration</button>
-            </div>
-        </div>
-    </div>
-</div>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/9c6c06c9/src/main/webapp/assets/tpl/app-add-wizard/create.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/app-add-wizard/create.html b/src/main/webapp/assets/tpl/app-add-wizard/create.html
index 48a9235..e5e4406 100644
--- a/src/main/webapp/assets/tpl/app-add-wizard/create.html
+++ b/src/main/webapp/assets/tpl/app-add-wizard/create.html
@@ -29,23 +29,6 @@ under the License.
 <div id="app-add-wizard-create-body">
 
     <ul class="nav nav-tabs" id="app-add-wizard-create-tab">
-        <li class="active"><a href="#templateTab" data-toggle="tab">Catalog</a></li>
-        <!-- li><a href="#yamlTab" data-toggle="tab">YAML</a></li -->
-        
-        <li class="dropdown"><a class="dropdown-toggle" id="dropLanguage"
-            role="button" data-toggle="dropdown" href="#">Other <b class="caret"></b></a>
-            <ul id="menuLanguage" class="dropdown-menu" role="menu" aria-labelledby="dropLanguage">
-                <li><a tabindex="-1" data-toggle="tab" href="#entitiesTab">Build from Entities</a></li>
-                <li><a tabindex="-1" data-toggle="tab" href="#appClassTab">Specify App Class</a></li>
-<!-- TODO
-                <li class="divider"></li>
-                <li><a tabindex="-1" data-toggle="tab" href="#jsonTab">JSON</a></li>
-                <li><a tabindex="-1" data-toggle="tab" href="#xmlTab">XML</a></li>
-                <li><a tabindex="-1" data-toggle="tab" href="#groovyTab">Groovy</a></li>
-                <li><a tabindex="-1" data-toggle="tab" href="#uploadTab">JAR</a></li>
- -->
-            </ul>
-        </li>
        <li class="text-filter pull-right"><input type="text"/></li>
     </ul>
 
@@ -64,33 +47,6 @@ under the License.
     </div>
     <div id="create-step-template-entries"/>
   </div>
-  
-  <div class="tab-pane" id="entitiesTab">
-    <div id="entitiesAccordionish"></div>
-    <button id="add-app-entity" class="btn btn-info btn-mini" style="margin:5px;">Add Additional Entity</button>
-  </div>
-
-  <div class="tab-pane" id="appClassTab">
-        <div class="control-group">
-            <div class="app-add-wizard-create-entity-label-newline">Type</div>
-            <div class="controls app-type">
-                <input id="app-java-type" type="text" name="type" class="input-large app-add-wizard-create-entity-input application-type-input" placeholder="type">
-            </div>
-        </div>
-  </div>
-
-  <div class="tab-pane" id="jsonTab">
-    <br/><br/><i>coming soon!</i>
-  </div>
-  <div class="tab-pane" id="xmlTab">
-    <br/><br/><i>coming soon!</i>
-  </div>
-  <div class="tab-pane" id="groovyTab">
-    <br/><br/><i>coming soon!</i>
-  </div>
-  <div class="tab-pane" id="uploadTab">
-    <br/><br/><i>coming soon!</i>
-  </div>
-    
+      
  </div></div>
 </div>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/9c6c06c9/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html b/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html
index 427e100..5276ae4 100644
--- a/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html
+++ b/src/main/webapp/assets/tpl/app-add-wizard/modal-wizard.html
@@ -29,7 +29,7 @@ under the License.
 
 <div class="modal-footer">
     <button id="prev_step" type="button button-previous" class="btn btn-mini btn-info">Back</button>
-    <button id="next_step" type="button button-next" class="btn btn-mini btn-info">Next</button>
     <button id="preview_step" type="button button-preview" class="btn btn-mini btn-info">Open in Composer</button>
+    <button id="next_step" type="button button-next" class="btn btn-mini btn-info">Next</button>
     <button id="finish_step" type="button button-finish" class="btn btn-mini btn-info">Deploy</button>
 </div>


[16/27] brooklyn-ui git commit: simple but effective code completion

Posted by he...@apache.org.
simple but effective code completion

does not attempt to cover everything or do a perfect parse tree,
as that is much harder, but does simple heuristics which give a lot of help without too much work

it would be great to offer something much sounder, basing e.g. on json-schema,
but that is a lot more work as well


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/1058fa7a
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/1058fa7a
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/1058fa7a

Branch: refs/heads/master
Commit: 1058fa7a1328bb1926dc1f0f68e580dc323dd588
Parents: d19e315
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Feb 12 15:55:30 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Feb 16 02:08:31 2016 +0000

----------------------------------------------------------------------
 .../webapp/assets/css/codemirror-brooklyn.css   |  14 +
 src/main/webapp/assets/js/config.js             |   2 +
 .../brooklyn-yaml-completion-proposals.js       | 374 +++++++++++++++++++
 .../js/util/code-complete/js-yaml-parser.js     |  48 +++
 src/main/webapp/assets/js/view/editor.js        |  25 +-
 src/test/javascript/config.txt                  |   2 +
 6 files changed, 463 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/1058fa7a/src/main/webapp/assets/css/codemirror-brooklyn.css
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/css/codemirror-brooklyn.css b/src/main/webapp/assets/css/codemirror-brooklyn.css
index c293ed4..b1b2c54 100644
--- a/src/main/webapp/assets/css/codemirror-brooklyn.css
+++ b/src/main/webapp/assets/css/codemirror-brooklyn.css
@@ -27,3 +27,17 @@
 }
 .CodeMirror .CodeMirror-gutter.CodeMirror-linenumbers {
 }
+
+li.CodeMirror-hint {
+  max-width: inherit;
+  overflow: visible;
+}
+ul.CodeMirror-hints {
+  overflow: scroll;
+  max-width: 30em;
+}
+
+.CodeMirror-hints .CodeMirror-hint.summary {
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-style: italic;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/1058fa7a/src/main/webapp/assets/js/config.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/config.js b/src/main/webapp/assets/js/config.js
index 05afbb6..94d6385 100644
--- a/src/main/webapp/assets/js/config.js
+++ b/src/main/webapp/assets/js/config.js
@@ -49,6 +49,8 @@ require.config({
         "uri":"libs/URI",
         "zeroclipboard":"libs/ZeroClipboard",
         "js-yaml":"libs/js-yaml",
+        "js-yaml-parser":"util/code-complete/js-yaml-parser",
+        "brooklyn-yaml-completion-proposals":"util/code-complete/brooklyn-yaml-completion-proposals",
 
         "codemirror":"libs/codemirror",
         "codemirror-mode-yaml":"libs/codemirror/mode/yaml/yaml",

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/1058fa7a/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js b/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
new file mode 100644
index 0000000..032f0d6
--- /dev/null
+++ b/src/main/webapp/assets/js/util/code-complete/brooklyn-yaml-completion-proposals.js
@@ -0,0 +1,374 @@
+
+define([
+    "backbone", "js-yaml-parser", "underscore"
+], function (Backbone, JsYamlParser, _) {
+
+    var BrooklynYamlCompletionProposals = {};
+
+    var Catalog = Backbone.Collection.extend({
+        initialize: function(models, options) {
+            this.name = options["name"];
+            var that = this; 
+            var model = this.model.extend({
+              url: function() {
+                return "/v1/" + that.name + "/" + this.id.split(":").join("/");
+              }
+            });
+            _.bindAll(this);
+            this.model = model;
+        },
+        url: function() {
+            return "/v1/" + this.name;
+        }
+    });
+    // currently populates catalog on startup, then refreshes on each search
+    // (but only renders later)
+    // ideally should be shared model refreshed periodically in background
+    var catalogE = new Catalog(undefined, { name: "catalog/entities" });
+    var catalogA = new Catalog(undefined, { name: "catalog/applications" });
+    var catalogL = new Catalog(undefined, { name: "locations" });
+    catalogA.fetch();
+    catalogE.fetch();
+    catalogL.fetch();
+
+    function findParseNodeAt(parse, position) {
+      if (parse.start<=position && parse.end>=position) {
+        for (var ci in parse.children) {
+          var c = parse.children[ci];
+          var result = findParseNodeAt(c, position);
+          if (result) return result;
+        }
+        return parse;
+      }
+      return null;
+    }
+    
+    /** adds additional fields to a parse node:
+     *  * type: map, list, primitive, null
+     *  * role: key, value, entry, root; or primitive if we are a primitive in a primitive (due to how it is parsed) 
+     *  * key: if we are role 'value', what is our key
+     *  * index: if parent is map or list, what is our position in that as a list
+     *  and returns a list of the containing parse nodes, root first
+     */
+    function findContexts(n, position) {
+        if (!n || n.role) return;
+        
+        if (n.result === null) {
+            n.type = 'null';
+        } else if (typeof n.result === 'object') {
+            if (typeof n.result.length !== 'undefined') {
+                // ^^^ messy way to check is parent a list
+                n.type = 'list';
+            } else {
+                n.type = 'map';
+            }
+        } else {
+            n.type = 'primitive';
+        }
+        
+        if (!n.parent) {
+            n.role = 'root';
+            n.depth = 0;
+            return [n];
+        }
+        var result = findContexts(n.parent, position);
+        n.depth = n.parent.depth+1;
+        result.push(n);
+        
+        if (n.parent.type == 'map') {
+            var prev;            
+            for (var ci in n.parent.children) {
+                var c = n.parent.children[ci];
+                if (c === n || c.start > position) {
+                    n.role = (ci%2==0 ? 'key' : 'value');
+                    n.index = (ci - (ci%2))/2;
+                    if (n.role === 'value') {
+                      n.key = prev;
+                    }
+                    return result;
+                }
+                prev = c;
+            }
+            console.log("not found",n,"in",n.parent.children);
+            throw "did not find parse node in parent's children";
+        }
+        
+        if (n.parent.type == 'list') {
+            n.role = 'entry';
+            for (var ci in n.children) {
+                var c = n.parent.children[ci];
+                if (c === n || c.start > position) {
+                    n.index = c;
+                    return result;
+                }
+            }
+            console.log("not found",n,"in",n.parent.children);
+            throw "did not find parse node in parent's children";
+        }
+        
+        n.role = 'primitive';
+        return result;
+    }
+    
+    function findContainingParseNode(n, predicate) {
+        if (typeof n === 'undefined') return null;
+        if (predicate(n)) return n;
+        return findContainingParseNode(n.parent, predicate);
+    }
+    
+    function findContainingMapParseNode(n) {
+        return findContainingParseNode(n, function() { return n.type === 'map'; });
+    }
+    
+    function indentation(n) {
+      var i = n.start;
+      while (i>0 && n.doc.charAt(i-1)!='\n') i--;
+      return n.start - i;
+    }
+
+    function spaces(n) {
+      var result = '';
+      while (n>0) { result+=' '; n--; }
+      return result;
+    }
+        
+    var CatalogProposer = {
+        getRootProposals: function() {
+          return [
+              { displayText: "brooklyn.catalog:", text: "brooklyn.catalog:\n  items:\n  - " }
+            ];
+        },
+        getProposals: function(nn, position, cmPosition) {
+            var n = nn[nn.length-1];
+            var result = [];
+            
+            var itemsKey;
+            if (n.type=='list' && n.key.result=='items') itemsKey = n.key;
+            else if (n.type='entry' && nn.length>2 && nn[nn.length-2].type=='list' && nn[nn.length-2].key.result=='items') itemsKey = nn[nn.length-2].key;
+            if (itemsKey) {            
+                result = result.concat(_.map(["id","name","itemType"],
+                    function(s) { return { displayText: s, text: spaces(indentation(itemsKey)+2)+s+': ' } }));
+                result.push({displayText: "item", text: spaces(indentation(itemsKey)+2)+"item"+':\n'+spaces(indentation(n)+2) });
+                result = result.concat(_.map(["description","iconUrl"],
+                    function(s) { return { displayText: s, text: spaces(indentation(itemsKey)+2)+s+': ' } }));
+                result.push({displayText: "items", text: spaces(indentation(itemsKey)+2)+"items"+':\n'+spaces(indentation(n))+"- " });
+            }
+
+            if (n.key && n.key.result=='itemType') {
+              result.concat(['template','entity','location','policy']);
+            }
+            
+            if (n.depth==1 || (n.depth>1 && cmPosition.ch==0)) {
+                result.concat([{displayText: "version", text: "  version:\n"}, 
+                    {displayText: "items", text: "  items:\n  - \n"} ]);
+            }
+            
+            return result;
+        }
+    }
+    
+    var AppBlueprintProposer = {
+        getRootProposals: function() {
+          return [
+              { displayText: "name:", text: "name: " },
+              { displayText: "location:", text: "location:\n  " },
+              { displayText: "services:", text: "services:\n- type: " }
+            ];
+        },
+        
+        getServiceTypes: function(n) {
+            var result = [];
+            console.log(catalogE);
+            catalogE.fetch();
+            catalogA.fetch();
+            result = result.concat(_.map(catalogE.models, function(m) { return m.get('symbolicName'); })); 
+            result = result.concat(_.map(catalogA.models, function(m) { return m.get('symbolicName'); }));
+            return result; 
+        },
+        getServiceKeys: function(type) {
+            t = catalogA.get(type) || catalogE.get(type) ||
+                // look for type without ID
+                _.find(catalogA.models, function(m) { return m.get('symbolicName') == type; }) || 
+                _.find(catalogE.models, function(m) { return m.get('symbolicName') == type; }); 
+            if (!t) return [];
+            return _.map(t.get('config'), function(c) { return c.name; });
+        },
+        getServiceKeyProposals: function(type, key) {
+            t = catalogA.get(type) || catalogE.get(type) ||
+                // look for type without ID
+                _.find(catalogA.models, function(m) { return m.get('symbolicName') == type; }) || 
+                _.find(catalogE.models, function(m) { return m.get('symbolicName') == type; }); 
+            if (!t) return [];
+            var c = _.find(t.get('config'), function(c) { return c.name == key; });
+            if (!c) return [];
+            var ct = c.type;
+            if (ct.startsWith("java.lang.") || ct.startsWith("java.util.")) ct = ct.substring(10);
+            var result = [ { displayText: ct+": "+c.description, text: '', className: 'summary' } ]; 
+            if (c.possibleValues) {
+                _.each(c.possibleValues, function(v) { result.push(v.value); });
+            }
+            return result;
+        },
+    
+        getLocationTypes: function() {
+            catalogL.fetch();
+            return _.map(catalogL.models, function(m) { return m.get('name'); });
+        },    
+        
+        // TODO would be much nicer to define a yaml schema; see e.g. json-schema.org
+        // and various JS implementations
+        getProposals: function(nn, position, cmPosition) {
+            var n = nn[nn.length-1];
+            var result = [];
+//            console.log("context at position "+position, nn);
+            while (n.role === 'primitive') n = n.parent;
+            if (nn[1].key && nn[1].key.result === 'services') {
+                // in services block
+                var canAddService = true;
+                
+                if (n.depth == 3 && n.role == 'value' && n.parent.role == 'entry') {
+                    // in a block for a particular service
+                    canAddService = false;
+                    if (n.key.result === 'type') {
+                        result = result.concat(_.map(this.getServiceTypes(n.parent), function(t) { return t+'\n'; }));
+                    } else if (n.key.result === 'location') {
+                        result = result.concat(_.map(this.getLocationTypes(n.parent), function(t) { 
+                            return t+'\n'; }));
+                    
+                    } else {
+                        // no assistance for values of other keys atm; show summary if available
+                        var type = nn[2].result['type'];
+                        result = result.concat(
+                            this.getServiceKeyProposals(type, n.key.result) ||
+                                [{ displayText: 'No assistance available for key', 
+                                   className: 'summary', text: '' }]);
+                    }
+                }
+                
+                if (n.depth >= 2 && n.role == 'entry' && nn[2].result['type']) {
+                    var type = nn[2].result['type'];
+                    result = result.concat(
+                        _.map(this.getServiceKeys(type), function(keyname) {
+                            return { displayText: keyname, text: spaces(indentation(nn[2]))+keyname+": " };
+                        }));
+                }
+                
+                if (n.depth > 2) {
+                    // deep in a service, no special assistance currently offered
+                }
+                
+                if (canAddService && (position == nn[1].end || position == nn[1].end+1)) {
+                    result.push( { displayText: 'Add a service', className: 'summary', text: '\n- type: ' } );
+                }
+            }
+            if (nn[1].key && nn[1].key.result === 'location') {
+                if (n.depth <= 2) {
+                    result = result.concat(_.map(this.getLocationTypes(n.parent), function(t) { 
+                            return t+'\n'; }));
+                }
+            }
+            // TODO other blocks
+            return result;
+        }
+    }
+
+    // cmPosition is {line: N, ch: N} format
+    BrooklynYamlCompletionProposals.getCompletionProposals = function(mode, cm) {
+        var proposer = mode === 'catalog' ? CatalogProposer : AppBlueprintProposer;
+        var text = cm.getValue();
+        var cmPosition = cm.getCursor();
+        // absolute position in doc
+        var position = cm.getRange({line: 0, ch: 0}, cmPosition).length;
+         
+        var parse;
+        try {
+            parse = JsYamlParser.parse(text);
+            if (typeof parse.result == 'string') {
+                console.log("prim");
+                throw "primitive not supported, parse as empty and let completion apply";
+            }
+        } catch (e) {
+            // parse failed -- parse to beginning of line
+            try {
+                parse = JsYamlParser.parse(text.substring(0, text.length - cmPosition.ch)+spaces(cmPosition.ch));
+            } catch (e) {
+                console.log('parse failed', e);
+                return [];
+            }
+        }
+        try {
+            var result;
+            if (typeof parse === 'undefined') {
+                // editor empty -- return defaults
+                result = proposer.getRootProposals();
+            } else {
+                n = findParseNodeAt(parse, position);
+                if (!n) {
+                  // shouldn't happen... fall back to returning empty
+                  console.log("no parse node containing curpos");
+                  result = proposer.getRootProposals();
+                } else {
+                    var nn = findContexts(n, position);
+                    
+                    if (n.role === 'root') {
+                      result = proposer.getRootProposals();
+                    } else {
+                      result = proposer.getProposals(nn, position, cmPosition);
+                    }
+                }
+            }
+            var wordSoFar = '';
+            var lineSoFar = '';
+            var i=0;
+            while (position > wordSoFar.length) {
+                var c = text.charAt(position-wordSoFar.length-1);
+                if (c=='\n' || c==' ' || c=='\t') break;
+                wordSoFar = '' + c + wordSoFar;
+            }
+            while (position > lineSoFar.length) {
+                var c = text.charAt(position-lineSoFar.length-1);
+                if (c=='\n') break;
+                lineSoFar = '' + c + lineSoFar;
+            }
+            result = _.compact(_.map(result, function(proposal) {
+                var proposalObj;
+                console.log("considering",proposal,"wrt",wordSoFar,"/",lineSoFar);
+                if (typeof proposal === 'object') {
+                    proposalObj = proposal;
+                    proposal = proposalObj.text;
+                }  else {
+                    proposalObj = { text: proposal, displayText: proposal };
+                }
+                if (proposal[0]==' ') {
+                  // proposal should start with 'lineSoFar'
+                  if (proposal.lastIndexOf(lineSoFar, 0)!=0) {
+                    // also match '  - ' in lieu of '    ',
+                    // needed for catalog (for service we always add the 'type' in the previous expansion)
+                    var proposalIfListStart = proposal.replace(/( *)  /,'$1- ');
+                    if (proposalIfListStart.lastIndexOf(lineSoFar, 0)!=0) {
+                      return null;
+                    }
+                    proposalObj.text = proposalIfListStart;
+                  }
+                  proposalObj.to = cmPosition;
+                  proposalObj.from = { line: cmPosition.line, ch: 0 };
+                } else {
+                  // proposal should start with 'wordSoFar'
+                  if (proposal.lastIndexOf(wordSoFar, 0)!=0) return null;
+                  proposalObj.to = cmPosition;
+                  proposalObj.from = { line: cmPosition.line, ch: cmPosition.ch - wordSoFar.length };
+                }
+                return proposalObj;
+            }));
+//            console.log("proposals:", result);
+            return result;
+            
+        } catch (e) {
+            console.log('completion failed', e, e.stack);
+            return [];
+        }
+    }
+    
+    return BrooklynYamlCompletionProposals;
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/1058fa7a/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js b/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js
new file mode 100644
index 0000000..98092f0
--- /dev/null
+++ b/src/main/webapp/assets/js/util/code-complete/js-yaml-parser.js
@@ -0,0 +1,48 @@
+
+define([
+    "js-yaml"
+], function (jsyaml) {
+
+    'use strict';
+
+    var JsYamlParser = {};
+
+    function newYamlParseNode(doc, parent, state) {
+        return {
+            doc: doc,
+            parent: parent,
+            children: [],
+
+            start: state.position,
+        };
+    }
+
+    function closeYamlNode(node, state) {
+        node.end = state.position;
+        node.result = state.result;
+    }
+
+    /** returns a YamlParseNode containing { doc, parent, children, start, end, result } */ 
+    JsYamlParser.parse = function(input) {
+        var rootNode, node;
+        var l = function(event, state) {
+            if (event === 'open') {
+                node = newYamlParseNode(input, node, state);
+            } else if (event == 'close') {
+                closeYamlNode(node, state);
+                if (node.parent) {
+                    node.parent.children.push(node);
+                    node = node.parent;
+                } else {
+                    if (rootNode != null) throw 'doc should have only one root node';
+                    rootNode = node;
+                    node = null;
+                }
+            }
+        };
+        var result = jsyaml.safeLoad(input, {listener: l});
+        return rootNode;
+    };
+
+    return JsYamlParser;
+});

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/1058fa7a/src/main/webapp/assets/js/view/editor.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/editor.js b/src/main/webapp/assets/js/view/editor.js
index d867080..19e4378 100644
--- a/src/main/webapp/assets/js/view/editor.js
+++ b/src/main/webapp/assets/js/view/editor.js
@@ -17,7 +17,7 @@
  * under the License.
 */
 define([
-    "underscore", "jquery", "backbone", "model/catalog-application", "js-yaml", "codemirror",
+    "underscore", "jquery", "backbone", "model/catalog-application", "js-yaml", "brooklyn-yaml-completion-proposals", "codemirror",
     "text!tpl/editor/page.html",
 
     // no constructor
@@ -26,7 +26,7 @@ define([
     "jquery-ba-bbq",
     "handlebars",
     "bootstrap"
-], function (_, $, Backbone, CatalogApplication, jsYaml, CodeMirror, EditorHtml) {
+], function (_, $, Backbone, CatalogApplication, jsYaml, BrooklynCompletion, CodeMirror, EditorHtml) {
     var _DEFAULT_BLUEPRINT = 
         'name: Sample Blueprint\n'+
         'description: runs `sleep` for sixty seconds then stops triggering ON_FIRE in Brooklyn\n'+
@@ -171,12 +171,33 @@ define([
                 this.editor = CodeMirror.fromTextArea(this.$("#yaml_code")[0], {
                     lineNumbers: true,
                     viewportMargin: Infinity, /* recommended if height auto */
+                    
                     extraKeys: {"Ctrl-Space": "autocomplete"},
                     mode: {
                         name: "yaml",
                         globalVars: true
+                    },
+                    
+                    hintOptions: {
+                        completeSingle: false,
+//                        closeOnUnfocus: false,   // handy for debugging
                     }
                 });
+                var oldYamlHint = CodeMirror.hint.yaml;
+                var that = this;
+                CodeMirror.hint.yaml = function(cm) {
+                    var result = {from: cm.getCursor(), to: cm.getCursor(), list: [] };
+                    result.list = BrooklynCompletion.getCompletionProposals(that.mode, cm);
+                    
+                    //result.list = result.list.concat(otherwords.list);
+                    // could return other proposals *additionally* but better only if we found nothing else 
+                    if (!result.list) {
+                        result = CodeMirror.hint.anyword(cm);
+                    }
+                    
+                    return result;
+                };
+                
                 var that = this;
                 this.editor.on("changes", function(editor, changes) {
                     that.refreshOnMinorChange();

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/1058fa7a/src/test/javascript/config.txt
----------------------------------------------------------------------
diff --git a/src/test/javascript/config.txt b/src/test/javascript/config.txt
index 3ea2e75..5052f5e 100644
--- a/src/test/javascript/config.txt
+++ b/src/test/javascript/config.txt
@@ -42,6 +42,8 @@
         "uri":"js/libs/URI",
         "zeroclipboard":"js/libs/ZeroClipboard",
         "js-yaml":"js/libs/js-yaml",
+        "js-yaml-parser":"js/util/code-complete/js-yaml-parser",
+        "brooklyn-yaml-completion-proposals":"js/util/code-complete/brooklyn-yaml-completion-proposals",
 
         "codemirror":"js/libs/codemirror",
         "codemirror-mode-yaml":"js/libs/codemirror/mode/yaml/yaml",


[05/27] brooklyn-ui git commit: composer allows blueprints to be passed, and app-add-wizard preview button takes you to composer

Posted by he...@apache.org.
composer allows blueprints to be passed, and app-add-wizard preview button takes you to composer

previously "preview" button just reset the dialog;
this also gives slightly more interesting examples


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/2d75ed5c
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/2d75ed5c
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/2d75ed5c

Branch: refs/heads/master
Commit: 2d75ed5cdfae618af20d1a87246ea989ccca5289
Parents: 1e17eee
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 01:38:25 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 .../assets/js/model/catalog-application.js      |  1 -
 src/main/webapp/assets/js/router.js             |  8 +--
 .../assets/js/view/application-add-wizard.js    | 46 +++++++++------
 src/main/webapp/assets/js/view/catalog.js       |  3 +-
 src/main/webapp/assets/js/view/editor.js        | 60 ++++++++++++++++----
 src/main/webapp/assets/tpl/editor/page.html     |  2 +-
 6 files changed, 87 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/2d75ed5c/src/main/webapp/assets/js/model/catalog-application.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/model/catalog-application.js b/src/main/webapp/assets/js/model/catalog-application.js
index f1a15eb..43f28b4 100644
--- a/src/main/webapp/assets/js/model/catalog-application.js
+++ b/src/main/webapp/assets/js/model/catalog-application.js
@@ -51,7 +51,6 @@ define(["underscore", "backbone"], function (_, Backbone) {
         },
         getId: function(id){
             return this.find(function(model) {
-                console.info("model", model, model.get('id') === id);
                 return model.get('id') === id;
             });
         }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/2d75ed5c/src/main/webapp/assets/js/router.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/router.js b/src/main/webapp/assets/js/router.js
index 54874a9..1d6dae4 100644
--- a/src/main/webapp/assets/js/router.js
+++ b/src/main/webapp/assets/js/router.js
@@ -123,7 +123,7 @@ define([
         routes:{
             'v1/home/*trail':'homePage',
             //'v1/editor/*trail':'editorPage',
-            'v1/editor(/)(:type)(/)(:typeId)':'editorPage',
+            'v1/editor(/)(:type)(/)(:typeId)(/:content)':'editorPage',
             'v1/applications/:app/entities/*trail':'applicationsPage',
             'v1/applications/*trail':'applicationsPage',
             'v1/applications':'applicationsPage',
@@ -179,13 +179,13 @@ define([
                 }
             }, error: render});
         },
-        editorPage: function (type, typeId) {
-            console.log("editorPage", type, typeId);
+        editorPage: function (type, typeId, content) {
             var editorView = new EditorView({
                 collection: this.applications,
                 appRouter: this,
                 type: type,
-                typeId: typeId
+                typeId: typeId,
+                content: content
             });
             this.showView("#application-content", editorView);
             $(".nav1").removeClass("active");

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/2d75ed5c/src/main/webapp/assets/js/view/application-add-wizard.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/application-add-wizard.js b/src/main/webapp/assets/js/view/application-add-wizard.js
index 344d6a0..ffdee6d 100644
--- a/src/main/webapp/assets/js/view/application-add-wizard.js
+++ b/src/main/webapp/assets/js/view/application-add-wizard.js
@@ -266,6 +266,7 @@ define([
         nextStep:function () {
             if (this.currentStep == 0) {
                 if (this.currentView.validate()) {
+                    this.isTemplate = false;
                     var yaml = (this.currentView && this.currentView.selectedTemplate && this.currentView.selectedTemplate.yaml);
                     if (yaml) {
                         try {
@@ -283,16 +284,15 @@ define([
                                 }
                               }
                             }
-                            yaml = (hasLocation ? true : false);
+                            this.isTemplate = (hasLocation ? true : false);
                         } catch (e) {
                             log("Warning: could not parse yaml template")
                             log(yaml);
-                            yaml = false;
                         }
                     }
-                    if (yaml) {
-                        // it's a yaml catalog template which includes a location, show the yaml tab navigate to editor
-                        this.currentView.redirectToEditorTab(this.currentView.selectedTemplate.id);
+                    if (this.isTemplate) {
+                        // it's a yaml catalog *template* (because it includes a location); go to composer
+                        this.redirectToEditorTabToDeployId(this.currentView.selectedTemplate.id);
                     } else {
                         // it's a java catalog template or yaml template without a location, go to wizard
                         this.currentStep += 1;
@@ -307,12 +307,16 @@ define([
         },
         previewStep:function () {
             if (this.currentView.validate()) {
-                this.currentStep = 0;
-                var that = this;
-                this.renderCurrentStep(function callback(view) {
+                var yaml;
+                if (this.model.mode == "yaml") {
+                    yaml = this.model.yaml;
+                } else {
                     // Drop any "None" locations.
-                    that.model.spec.pruneLocations();
-                });
+                    this.model.spec.pruneLocations();
+                    yaml = JsYaml.safeDump(oldSpecToCamp(this.model.spec.toJSON()));
+                }
+
+                this.redirectToEditorTabToDeployYaml(yaml);
             } else {
                 // call to validate should showFailure
             }
@@ -323,7 +327,20 @@ define([
             } else {
                 // call to validate should showFailure
             }
-        }
+        },
+        
+        redirectToEditorTabToDeployId: function(catalogId){
+            this.redirectTo("/v1/editor/app/"+ (typeof catalogId === 'string' ? catalogId : '')); 
+        },
+        redirectToEditorTabToDeployYaml: function(yaml){
+            this.redirectTo("/v1/editor/app/_/"+encodeURIComponent(yaml));
+        },
+        redirectTo: function(url){
+            var $modal = $('.add-app #modal-container .modal');
+            $modal.modal('hide');
+            $modal.fadeTo(500,1);
+            Backbone.history.navigate(url, {trigger: true});
+        },
     })
     
     // Note: this does not restore values on a back click; setting type and entity type+name is easy,
@@ -432,11 +449,8 @@ define([
             $("ul#app-add-wizard-create-tab").find("a[href='#yamlTab']").tab('show');
             $("#yaml_code").focus();
         },
-        redirectToEditorTab: function(catalogId){
-            var $modal = $('.add-app #modal-container .modal');
-            $modal.modal('hide');
-            $modal.fadeTo(500,1);
-            Backbone.history.navigate("/v1/editor/app/"+ (typeof catalogId === 'string' ? catalogId : '') ,{trigger: true});
+        redirectToEditorTab: function() {
+            this.redirectToEditorTabToDeployId();
         },
         applyFilter: function(e) {
             var filter = $(e.currentTarget).val().toLowerCase()

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/2d75ed5c/src/main/webapp/assets/js/view/catalog.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/catalog.js b/src/main/webapp/assets/js/view/catalog.js
index 90e89ca..eb9effd 100644
--- a/src/main/webapp/assets/js/view/catalog.js
+++ b/src/main/webapp/assets/js/view/catalog.js
@@ -170,7 +170,8 @@ define([
                 Backbone.history.navigate("/v1/catalog/new/" + type);
                 this.$("#catalog-add-form").html(this.contextView.$el);
             }else{
-                Backbone.history.navigate('/v1/editor/catalog/'+ type, {trigger: true});
+                // go to composer
+                Backbone.history.navigate('/v1/editor/catalog/', {trigger: true});
             }
         }
     });

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/2d75ed5c/src/main/webapp/assets/js/view/editor.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/editor.js b/src/main/webapp/assets/js/view/editor.js
index 4746b33..baf534f 100644
--- a/src/main/webapp/assets/js/view/editor.js
+++ b/src/main/webapp/assets/js/view/editor.js
@@ -27,9 +27,28 @@ define([
     "handlebars",
     "bootstrap"
 ], function (_, $, Backbone, CatalogApplication, jsYaml, CodeMirror, EditorHtml) {
-    var _DEFAULT_BLUEPRINT = 'name: Empty Software Process\nlocation: localhost\nservices:\n- type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess';
-    var _DEFAULT_CATALOG = 'brooklyn.catalog:\n  version: 0.0.1\n  items:\n  - id: example\n    description: This is an example catalog application\n    ' +
-        'itemType: template\n    item:\n      name: Empty Software Process\n      services:\n      - type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess';
+    var _DEFAULT_BLUEPRINT = 
+        'name: Sample Blueprint\n'+
+        'description: runs `sleep` for sixty seconds then stops triggering ON_FIRE in Brooklyn\n'+
+        'location: localhost\n'+
+        'services:\n'+
+        '- type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess\n'+
+        '  launch.command: |\n'+
+        '    echo hello world\n'+
+        '    nohup sleep 60 &\n'+
+        '    echo $! > ${PID_FILE:-pid.txt}\n';
+    var _DEFAULT_CATALOG = 
+        'brooklyn.catalog:\n'+
+        '  version: 0.0.1\n'+
+        '  items:\n'+
+        '  - id: example\n'+
+        '    description: This is an example catalog application\n'+
+        '    itemType: template\n'+
+        '    item:\n'+
+        '      name: Sample Blueprint Template\n'+
+        '      services:\n'+
+        '      - type: <your service here>\n'+
+        '      location: <your cloud here>\n';
 
     var EditorView = Backbone.View.extend({
         tagName:"div",
@@ -60,14 +79,35 @@ define([
         refreshEditor: function() {
             var cm = this.editor;
             if (typeof(cm) !== "undefined") {
-                if(this.options.type && this.options.type === 'catalog'){
-                    cm.getDoc().setValue(_DEFAULT_CATALOG);
-                }else{
-                    //assume blueprint
-                    var item = this.options.catalog.getId(this.options.typeId);
-                    cm.getDoc().setValue((item ? item['attributes']['planYaml'] : _DEFAULT_BLUEPRINT ));
+                var itemText;
+                if (this.options.typeId === '_') {
+                    // _ indicates a literal is being supplied
+                    itemText = this.options.content;
+                } else {
+                    if (this.options.content) {
+                        console.log('ignoring content when typeId is not _; given:', this.options.type, this.options.typeId, this.options.content);
+                    } 
+                    if (this.options.typeId) {
+                        var item = this.options.catalog.getId(this.options.typeId);
+                        if (item) itemText = item['attributes']['planYaml'];
+                        if (!itemText) {
+                            itemText = '# unknown type - this is an example blueprint that would reference it\n'+
+                                'services:\n- type: '+this.options.typeId+'\n';
+                            
+                        }
+                    }
+                }
+                if (!itemText) {
+                    if (this.options.type === 'catalog') {
+                        itemText = _DEFAULT_CATALOG;
+                    } else {
+                        itemText = _DEFAULT_BLUEPRINT;
+                    }
                 }
-                cm.focus();
+                cm.getDoc().setValue(itemText);
+                //better not to focus as focussing puts the cursor at the beginning which is odd
+                //and cmd-shift-[ and tab are intercepted so user can't navigate
+                // cm.focus();
                 cm.refresh();
             }
 

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/2d75ed5c/src/main/webapp/assets/tpl/editor/page.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/editor/page.html b/src/main/webapp/assets/tpl/editor/page.html
index 44c5d9d..9a37fe0 100644
--- a/src/main/webapp/assets/tpl/editor/page.html
+++ b/src/main/webapp/assets/tpl/editor/page.html
@@ -36,7 +36,7 @@ under the License.
                         <div class="composer-toolbar">
                             <!-- the toolbar -->
                         </div>
-                        <textarea id="yaml_code" placeholder="no details available" mode="yaml" class="code-textarea" style="height:760px; width:98%"></textarea>
+                        <textarea id="yaml_code" placeholder="<enter blueprint yaml here>" mode="yaml" class="code-textarea" style="height:760px; width:98%"></textarea>
                     </div>
                 </div>
             </div>


[08/27] brooklyn-ui git commit: update js-yaml to latest (snapshot) version

Posted by he...@apache.org.
update js-yaml to latest (snapshot) version

from commit 50c82bccf70a19fd4add99542dfdf06a60280da8 (today) with parse listener enhancement https://github.com/nodeca/js-yaml/pull/249


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/1e17eeef
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/1e17eeef
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/1e17eeef

Branch: refs/heads/master
Commit: 1e17eeef6b1f7123552cccd4ec5ecd47c6d5d5c6
Parents: c2e374e
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 00:37:52 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/js/libs/js-yaml.js | 5703 ++++++++++++------------
 1 file changed, 2784 insertions(+), 2919 deletions(-)
----------------------------------------------------------------------



[13/27] brooklyn-ui git commit: move codemirror libraries to the usual places

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d19e3156/src/main/webapp/assets/js/libs/codemirror.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/codemirror.js b/src/main/webapp/assets/js/libs/codemirror.js
new file mode 100644
index 0000000..c6f9af8
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/codemirror.js
@@ -0,0 +1,8835 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+// This is CodeMirror (http://codemirror.net), a code editor
+// implemented in JavaScript on top of the browser's DOM.
+//
+// You can find some technical background for some of the code below
+// at http://marijnhaverbeke.nl/blog/#cm-internals .
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    module.exports = mod();
+  else if (typeof define == "function" && define.amd) // AMD
+    return define([], mod);
+  else // Plain browser env
+    this.CodeMirror = mod();
+})(function() {
+  "use strict";
+
+  // BROWSER SNIFFING
+
+  // Kludges for bugs and behavior differences that can't be feature
+  // detected are enabled based on userAgent etc sniffing.
+
+  var gecko = /gecko\/\d/i.test(navigator.userAgent);
+  var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
+  var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
+  var ie = ie_upto10 || ie_11up;
+  var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
+  var webkit = /WebKit\//.test(navigator.userAgent);
+  var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
+  var chrome = /Chrome\//.test(navigator.userAgent);
+  var presto = /Opera\//.test(navigator.userAgent);
+  var safari = /Apple Computer/.test(navigator.vendor);
+  var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
+  var phantom = /PhantomJS/.test(navigator.userAgent);
+
+  var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
+  // This is woefully incomplete. Suggestions for alternative methods welcome.
+  var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
+  var mac = ios || /Mac/.test(navigator.platform);
+  var windows = /win/i.test(navigator.platform);
+
+  var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
+  if (presto_version) presto_version = Number(presto_version[1]);
+  if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
+  // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
+  var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
+  var captureRightClick = gecko || (ie && ie_version >= 9);
+
+  // Optimize some code when these features are not used.
+  var sawReadOnlySpans = false, sawCollapsedSpans = false;
+
+  // EDITOR CONSTRUCTOR
+
+  // A CodeMirror instance represents an editor. This is the object
+  // that user code is usually dealing with.
+
+  function CodeMirror(place, options) {
+    if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
+
+    this.options = options = options ? copyObj(options) : {};
+    // Determine effective options based on given values and defaults.
+    copyObj(defaults, options, false);
+    setGuttersForLineNumbers(options);
+
+    var doc = options.value;
+    if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator);
+    this.doc = doc;
+
+    var input = new CodeMirror.inputStyles[options.inputStyle](this);
+    var display = this.display = new Display(place, doc, input);
+    display.wrapper.CodeMirror = this;
+    updateGutters(this);
+    themeChanged(this);
+    if (options.lineWrapping)
+      this.display.wrapper.className += " CodeMirror-wrap";
+    if (options.autofocus && !mobile) display.input.focus();
+    initScrollbars(this);
+
+    this.state = {
+      keyMaps: [],  // stores maps added by addKeyMap
+      overlays: [], // highlighting overlays, as added by addOverlay
+      modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
+      overwrite: false,
+      delayingBlurEvent: false,
+      focused: false,
+      suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
+      pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
+      selectingText: false,
+      draggingText: false,
+      highlight: new Delayed(), // stores highlight worker timeout
+      keySeq: null,  // Unfinished key sequence
+      specialChars: null
+    };
+
+    var cm = this;
+
+    // Override magic textarea content restore that IE sometimes does
+    // on our hidden textarea on reload
+    if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20);
+
+    registerEventHandlers(this);
+    ensureGlobalHandlers();
+
+    startOperation(this);
+    this.curOp.forceUpdate = true;
+    attachDoc(this, doc);
+
+    if ((options.autofocus && !mobile) || cm.hasFocus())
+      setTimeout(bind(onFocus, this), 20);
+    else
+      onBlur(this);
+
+    for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
+      optionHandlers[opt](this, options[opt], Init);
+    maybeUpdateLineNumberWidth(this);
+    if (options.finishInit) options.finishInit(this);
+    for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
+    endOperation(this);
+    // Suppress optimizelegibility in Webkit, since it breaks text
+    // measuring on line wrapping boundaries.
+    if (webkit && options.lineWrapping &&
+        getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
+      display.lineDiv.style.textRendering = "auto";
+  }
+
+  // DISPLAY CONSTRUCTOR
+
+  // The display handles the DOM integration, both for input reading
+  // and content drawing. It holds references to DOM nodes and
+  // display-related state.
+
+  function Display(place, doc, input) {
+    var d = this;
+    this.input = input;
+
+    // Covers bottom-right square when both scrollbars are present.
+    d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
+    d.scrollbarFiller.setAttribute("cm-not-content", "true");
+    // Covers bottom of gutter when coverGutterNextToScrollbar is on
+    // and h scrollbar is present.
+    d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
+    d.gutterFiller.setAttribute("cm-not-content", "true");
+    // Will contain the actual code, positioned to cover the viewport.
+    d.lineDiv = elt("div", null, "CodeMirror-code");
+    // Elements are added to these to represent selection and cursors.
+    d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
+    d.cursorDiv = elt("div", null, "CodeMirror-cursors");
+    // A visibility: hidden element used to find the size of things.
+    d.measure = elt("div", null, "CodeMirror-measure");
+    // When lines outside of the viewport are measured, they are drawn in this.
+    d.lineMeasure = elt("div", null, "CodeMirror-measure");
+    // Wraps everything that needs to exist inside the vertically-padded coordinate system
+    d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
+                      null, "position: relative; outline: none");
+    // Moved around its parent to cover visible view.
+    d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
+    // Set to the height of the document, allowing scrolling.
+    d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
+    d.sizerWidth = null;
+    // Behavior of elts with overflow: auto and padding is
+    // inconsistent across browsers. This is used to ensure the
+    // scrollable area is big enough.
+    d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
+    // Will contain the gutters, if any.
+    d.gutters = elt("div", null, "CodeMirror-gutters");
+    d.lineGutter = null;
+    // Actual scrollable element.
+    d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
+    d.scroller.setAttribute("tabIndex", "-1");
+    // The element in which the editor lives.
+    d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
+
+    // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
+    if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
+    if (!webkit && !(gecko && mobile)) d.scroller.draggable = true;
+
+    if (place) {
+      if (place.appendChild) place.appendChild(d.wrapper);
+      else place(d.wrapper);
+    }
+
+    // Current rendered range (may be bigger than the view window).
+    d.viewFrom = d.viewTo = doc.first;
+    d.reportedViewFrom = d.reportedViewTo = doc.first;
+    // Information about the rendered lines.
+    d.view = [];
+    d.renderedView = null;
+    // Holds info about a single rendered line when it was rendered
+    // for measurement, while not in view.
+    d.externalMeasured = null;
+    // Empty space (in pixels) above the view
+    d.viewOffset = 0;
+    d.lastWrapHeight = d.lastWrapWidth = 0;
+    d.updateLineNumbers = null;
+
+    d.nativeBarWidth = d.barHeight = d.barWidth = 0;
+    d.scrollbarsClipped = false;
+
+    // Used to only resize the line number gutter when necessary (when
+    // the amount of lines crosses a boundary that makes its width change)
+    d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
+    // Set to true when a non-horizontal-scrolling line widget is
+    // added. As an optimization, line widget aligning is skipped when
+    // this is false.
+    d.alignWidgets = false;
+
+    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
+
+    // Tracks the maximum line length so that the horizontal scrollbar
+    // can be kept static when scrolling.
+    d.maxLine = null;
+    d.maxLineLength = 0;
+    d.maxLineChanged = false;
+
+    // Used for measuring wheel scrolling granularity
+    d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
+
+    // True when shift is held down.
+    d.shift = false;
+
+    // Used to track whether anything happened since the context menu
+    // was opened.
+    d.selForContextMenu = null;
+
+    d.activeTouch = null;
+
+    input.init(d);
+  }
+
+  // STATE UPDATES
+
+  // Used to get the editor into a consistent state again when options change.
+
+  function loadMode(cm) {
+    cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
+    resetModeState(cm);
+  }
+
+  function resetModeState(cm) {
+    cm.doc.iter(function(line) {
+      if (line.stateAfter) line.stateAfter = null;
+      if (line.styles) line.styles = null;
+    });
+    cm.doc.frontier = cm.doc.first;
+    startWorker(cm, 100);
+    cm.state.modeGen++;
+    if (cm.curOp) regChange(cm);
+  }
+
+  function wrappingChanged(cm) {
+    if (cm.options.lineWrapping) {
+      addClass(cm.display.wrapper, "CodeMirror-wrap");
+      cm.display.sizer.style.minWidth = "";
+      cm.display.sizerWidth = null;
+    } else {
+      rmClass(cm.display.wrapper, "CodeMirror-wrap");
+      findMaxLine(cm);
+    }
+    estimateLineHeights(cm);
+    regChange(cm);
+    clearCaches(cm);
+    setTimeout(function(){updateScrollbars(cm);}, 100);
+  }
+
+  // Returns a function that estimates the height of a line, to use as
+  // first approximation until the line becomes visible (and is thus
+  // properly measurable).
+  function estimateHeight(cm) {
+    var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
+    var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
+    return function(line) {
+      if (lineIsHidden(cm.doc, line)) return 0;
+
+      var widgetsHeight = 0;
+      if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
+        if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
+      }
+
+      if (wrapping)
+        return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
+      else
+        return widgetsHeight + th;
+    };
+  }
+
+  function estimateLineHeights(cm) {
+    var doc = cm.doc, est = estimateHeight(cm);
+    doc.iter(function(line) {
+      var estHeight = est(line);
+      if (estHeight != line.height) updateLineHeight(line, estHeight);
+    });
+  }
+
+  function themeChanged(cm) {
+    cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
+      cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
+    clearCaches(cm);
+  }
+
+  function guttersChanged(cm) {
+    updateGutters(cm);
+    regChange(cm);
+    setTimeout(function(){alignHorizontally(cm);}, 20);
+  }
+
+  // Rebuild the gutter elements, ensure the margin to the left of the
+  // code matches their width.
+  function updateGutters(cm) {
+    var gutters = cm.display.gutters, specs = cm.options.gutters;
+    removeChildren(gutters);
+    for (var i = 0; i < specs.length; ++i) {
+      var gutterClass = specs[i];
+      var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
+      if (gutterClass == "CodeMirror-linenumbers") {
+        cm.display.lineGutter = gElt;
+        gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
+      }
+    }
+    gutters.style.display = i ? "" : "none";
+    updateGutterSpace(cm);
+  }
+
+  function updateGutterSpace(cm) {
+    var width = cm.display.gutters.offsetWidth;
+    cm.display.sizer.style.marginLeft = width + "px";
+  }
+
+  // Compute the character length of a line, taking into account
+  // collapsed ranges (see markText) that might hide parts, and join
+  // other lines onto it.
+  function lineLength(line) {
+    if (line.height == 0) return 0;
+    var len = line.text.length, merged, cur = line;
+    while (merged = collapsedSpanAtStart(cur)) {
+      var found = merged.find(0, true);
+      cur = found.from.line;
+      len += found.from.ch - found.to.ch;
+    }
+    cur = line;
+    while (merged = collapsedSpanAtEnd(cur)) {
+      var found = merged.find(0, true);
+      len -= cur.text.length - found.from.ch;
+      cur = found.to.line;
+      len += cur.text.length - found.to.ch;
+    }
+    return len;
+  }
+
+  // Find the longest line in the document.
+  function findMaxLine(cm) {
+    var d = cm.display, doc = cm.doc;
+    d.maxLine = getLine(doc, doc.first);
+    d.maxLineLength = lineLength(d.maxLine);
+    d.maxLineChanged = true;
+    doc.iter(function(line) {
+      var len = lineLength(line);
+      if (len > d.maxLineLength) {
+        d.maxLineLength = len;
+        d.maxLine = line;
+      }
+    });
+  }
+
+  // Make sure the gutters options contains the element
+  // "CodeMirror-linenumbers" when the lineNumbers option is true.
+  function setGuttersForLineNumbers(options) {
+    var found = indexOf(options.gutters, "CodeMirror-linenumbers");
+    if (found == -1 && options.lineNumbers) {
+      options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
+    } else if (found > -1 && !options.lineNumbers) {
+      options.gutters = options.gutters.slice(0);
+      options.gutters.splice(found, 1);
+    }
+  }
+
+  // SCROLLBARS
+
+  // Prepare DOM reads needed to update the scrollbars. Done in one
+  // shot to minimize update/measure roundtrips.
+  function measureForScrollbars(cm) {
+    var d = cm.display, gutterW = d.gutters.offsetWidth;
+    var docH = Math.round(cm.doc.height + paddingVert(cm.display));
+    return {
+      clientHeight: d.scroller.clientHeight,
+      viewHeight: d.wrapper.clientHeight,
+      scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
+      viewWidth: d.wrapper.clientWidth,
+      barLeft: cm.options.fixedGutter ? gutterW : 0,
+      docHeight: docH,
+      scrollHeight: docH + scrollGap(cm) + d.barHeight,
+      nativeBarWidth: d.nativeBarWidth,
+      gutterWidth: gutterW
+    };
+  }
+
+  function NativeScrollbars(place, scroll, cm) {
+    this.cm = cm;
+    var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
+    var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
+    place(vert); place(horiz);
+
+    on(vert, "scroll", function() {
+      if (vert.clientHeight) scroll(vert.scrollTop, "vertical");
+    });
+    on(horiz, "scroll", function() {
+      if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
+    });
+
+    this.checkedOverlay = false;
+    // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
+    if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
+  }
+
+  NativeScrollbars.prototype = copyObj({
+    update: function(measure) {
+      var needsH = measure.scrollWidth > measure.clientWidth + 1;
+      var needsV = measure.scrollHeight > measure.clientHeight + 1;
+      var sWidth = measure.nativeBarWidth;
+
+      if (needsV) {
+        this.vert.style.display = "block";
+        this.vert.style.bottom = needsH ? sWidth + "px" : "0";
+        var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
+        // A bug in IE8 can cause this value to be negative, so guard it.
+        this.vert.firstChild.style.height =
+          Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
+      } else {
+        this.vert.style.display = "";
+        this.vert.firstChild.style.height = "0";
+      }
+
+      if (needsH) {
+        this.horiz.style.display = "block";
+        this.horiz.style.right = needsV ? sWidth + "px" : "0";
+        this.horiz.style.left = measure.barLeft + "px";
+        var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
+        this.horiz.firstChild.style.width =
+          (measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
+      } else {
+        this.horiz.style.display = "";
+        this.horiz.firstChild.style.width = "0";
+      }
+
+      if (!this.checkedOverlay && measure.clientHeight > 0) {
+        if (sWidth == 0) this.overlayHack();
+        this.checkedOverlay = true;
+      }
+
+      return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
+    },
+    setScrollLeft: function(pos) {
+      if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
+    },
+    setScrollTop: function(pos) {
+      if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
+    },
+    overlayHack: function() {
+      var w = mac && !mac_geMountainLion ? "12px" : "18px";
+      this.horiz.style.minHeight = this.vert.style.minWidth = w;
+      var self = this;
+      var barMouseDown = function(e) {
+        if (e_target(e) != self.vert && e_target(e) != self.horiz)
+          operation(self.cm, onMouseDown)(e);
+      };
+      on(this.vert, "mousedown", barMouseDown);
+      on(this.horiz, "mousedown", barMouseDown);
+    },
+    clear: function() {
+      var parent = this.horiz.parentNode;
+      parent.removeChild(this.horiz);
+      parent.removeChild(this.vert);
+    }
+  }, NativeScrollbars.prototype);
+
+  function NullScrollbars() {}
+
+  NullScrollbars.prototype = copyObj({
+    update: function() { return {bottom: 0, right: 0}; },
+    setScrollLeft: function() {},
+    setScrollTop: function() {},
+    clear: function() {}
+  }, NullScrollbars.prototype);
+
+  CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
+
+  function initScrollbars(cm) {
+    if (cm.display.scrollbars) {
+      cm.display.scrollbars.clear();
+      if (cm.display.scrollbars.addClass)
+        rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);
+    }
+
+    cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {
+      cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
+      // Prevent clicks in the scrollbars from killing focus
+      on(node, "mousedown", function() {
+        if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0);
+      });
+      node.setAttribute("cm-not-content", "true");
+    }, function(pos, axis) {
+      if (axis == "horizontal") setScrollLeft(cm, pos);
+      else setScrollTop(cm, pos);
+    }, cm);
+    if (cm.display.scrollbars.addClass)
+      addClass(cm.display.wrapper, cm.display.scrollbars.addClass);
+  }
+
+  function updateScrollbars(cm, measure) {
+    if (!measure) measure = measureForScrollbars(cm);
+    var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
+    updateScrollbarsInner(cm, measure);
+    for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
+      if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
+        updateHeightsInViewport(cm);
+      updateScrollbarsInner(cm, measureForScrollbars(cm));
+      startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
+    }
+  }
+
+  // Re-synchronize the fake scrollbars with the actual size of the
+  // content.
+  function updateScrollbarsInner(cm, measure) {
+    var d = cm.display;
+    var sizes = d.scrollbars.update(measure);
+
+    d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
+    d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
+
+    if (sizes.right && sizes.bottom) {
+      d.scrollbarFiller.style.display = "block";
+      d.scrollbarFiller.style.height = sizes.bottom + "px";
+      d.scrollbarFiller.style.width = sizes.right + "px";
+    } else d.scrollbarFiller.style.display = "";
+    if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
+      d.gutterFiller.style.display = "block";
+      d.gutterFiller.style.height = sizes.bottom + "px";
+      d.gutterFiller.style.width = measure.gutterWidth + "px";
+    } else d.gutterFiller.style.display = "";
+  }
+
+  // Compute the lines that are visible in a given viewport (defaults
+  // the the current scroll position). viewport may contain top,
+  // height, and ensure (see op.scrollToPos) properties.
+  function visibleLines(display, doc, viewport) {
+    var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
+    top = Math.floor(top - paddingTop(display));
+    var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
+
+    var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
+    // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
+    // forces those lines into the viewport (if possible).
+    if (viewport && viewport.ensure) {
+      var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
+      if (ensureFrom < from) {
+        from = ensureFrom;
+        to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
+      } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
+        from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
+        to = ensureTo;
+      }
+    }
+    return {from: from, to: Math.max(to, from + 1)};
+  }
+
+  // LINE NUMBERS
+
+  // Re-align line numbers and gutter marks to compensate for
+  // horizontal scrolling.
+  function alignHorizontally(cm) {
+    var display = cm.display, view = display.view;
+    if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
+    var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
+    var gutterW = display.gutters.offsetWidth, left = comp + "px";
+    for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
+      if (cm.options.fixedGutter && view[i].gutter)
+        view[i].gutter.style.left = left;
+      var align = view[i].alignable;
+      if (align) for (var j = 0; j < align.length; j++)
+        align[j].style.left = left;
+    }
+    if (cm.options.fixedGutter)
+      display.gutters.style.left = (comp + gutterW) + "px";
+  }
+
+  // Used to ensure that the line number gutter is still the right
+  // size for the current document size. Returns true when an update
+  // is needed.
+  function maybeUpdateLineNumberWidth(cm) {
+    if (!cm.options.lineNumbers) return false;
+    var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
+    if (last.length != display.lineNumChars) {
+      var test = display.measure.appendChild(elt("div", [elt("div", last)],
+                                                 "CodeMirror-linenumber CodeMirror-gutter-elt"));
+      var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
+      display.lineGutter.style.width = "";
+      display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
+      display.lineNumWidth = display.lineNumInnerWidth + padding;
+      display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
+      display.lineGutter.style.width = display.lineNumWidth + "px";
+      updateGutterSpace(cm);
+      return true;
+    }
+    return false;
+  }
+
+  function lineNumberFor(options, i) {
+    return String(options.lineNumberFormatter(i + options.firstLineNumber));
+  }
+
+  // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
+  // but using getBoundingClientRect to get a sub-pixel-accurate
+  // result.
+  function compensateForHScroll(display) {
+    return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
+  }
+
+  // DISPLAY DRAWING
+
+  function DisplayUpdate(cm, viewport, force) {
+    var display = cm.display;
+
+    this.viewport = viewport;
+    // Store some values that we'll need later (but don't want to force a relayout for)
+    this.visible = visibleLines(display, cm.doc, viewport);
+    this.editorIsHidden = !display.wrapper.offsetWidth;
+    this.wrapperHeight = display.wrapper.clientHeight;
+    this.wrapperWidth = display.wrapper.clientWidth;
+    this.oldDisplayWidth = displayWidth(cm);
+    this.force = force;
+    this.dims = getDimensions(cm);
+    this.events = [];
+  }
+
+  DisplayUpdate.prototype.signal = function(emitter, type) {
+    if (hasHandler(emitter, type))
+      this.events.push(arguments);
+  };
+  DisplayUpdate.prototype.finish = function() {
+    for (var i = 0; i < this.events.length; i++)
+      signal.apply(null, this.events[i]);
+  };
+
+  function maybeClipScrollbars(cm) {
+    var display = cm.display;
+    if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
+      display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
+      display.heightForcer.style.height = scrollGap(cm) + "px";
+      display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
+      display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
+      display.scrollbarsClipped = true;
+    }
+  }
+
+  // Does the actual updating of the line display. Bails out
+  // (returning false) when there is nothing to be done and forced is
+  // false.
+  function updateDisplayIfNeeded(cm, update) {
+    var display = cm.display, doc = cm.doc;
+
+    if (update.editorIsHidden) {
+      resetView(cm);
+      return false;
+    }
+
+    // Bail out if the visible area is already rendered and nothing changed.
+    if (!update.force &&
+        update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
+        (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
+        display.renderedView == display.view && countDirtyView(cm) == 0)
+      return false;
+
+    if (maybeUpdateLineNumberWidth(cm)) {
+      resetView(cm);
+      update.dims = getDimensions(cm);
+    }
+
+    // Compute a suitable new viewport (from & to)
+    var end = doc.first + doc.size;
+    var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
+    var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
+    if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
+    if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
+    if (sawCollapsedSpans) {
+      from = visualLineNo(cm.doc, from);
+      to = visualLineEndNo(cm.doc, to);
+    }
+
+    var different = from != display.viewFrom || to != display.viewTo ||
+      display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
+    adjustView(cm, from, to);
+
+    display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
+    // Position the mover div to align with the current scroll position
+    cm.display.mover.style.top = display.viewOffset + "px";
+
+    var toUpdate = countDirtyView(cm);
+    if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
+        (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
+      return false;
+
+    // For big changes, we hide the enclosing element during the
+    // update, since that speeds up the operations on most browsers.
+    var focused = activeElt();
+    if (toUpdate > 4) display.lineDiv.style.display = "none";
+    patchDisplay(cm, display.updateLineNumbers, update.dims);
+    if (toUpdate > 4) display.lineDiv.style.display = "";
+    display.renderedView = display.view;
+    // There might have been a widget with a focused element that got
+    // hidden or updated, if so re-focus it.
+    if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
+
+    // Prevent selection and cursors from interfering with the scroll
+    // width and height.
+    removeChildren(display.cursorDiv);
+    removeChildren(display.selectionDiv);
+    display.gutters.style.height = display.sizer.style.minHeight = 0;
+
+    if (different) {
+      display.lastWrapHeight = update.wrapperHeight;
+      display.lastWrapWidth = update.wrapperWidth;
+      startWorker(cm, 400);
+    }
+
+    display.updateLineNumbers = null;
+
+    return true;
+  }
+
+  function postUpdateDisplay(cm, update) {
+    var viewport = update.viewport;
+    for (var first = true;; first = false) {
+      if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
+        // Clip forced viewport to actual scrollable area.
+        if (viewport && viewport.top != null)
+          viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
+        // Updated line heights might result in the drawn area not
+        // actually covering the viewport. Keep looping until it does.
+        update.visible = visibleLines(cm.display, cm.doc, viewport);
+        if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
+          break;
+      }
+      if (!updateDisplayIfNeeded(cm, update)) break;
+      updateHeightsInViewport(cm);
+      var barMeasure = measureForScrollbars(cm);
+      updateSelection(cm);
+      setDocumentHeight(cm, barMeasure);
+      updateScrollbars(cm, barMeasure);
+    }
+
+    update.signal(cm, "update", cm);
+    if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
+      update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
+      cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
+    }
+  }
+
+  function updateDisplaySimple(cm, viewport) {
+    var update = new DisplayUpdate(cm, viewport);
+    if (updateDisplayIfNeeded(cm, update)) {
+      updateHeightsInViewport(cm);
+      postUpdateDisplay(cm, update);
+      var barMeasure = measureForScrollbars(cm);
+      updateSelection(cm);
+      setDocumentHeight(cm, barMeasure);
+      updateScrollbars(cm, barMeasure);
+      update.finish();
+    }
+  }
+
+  function setDocumentHeight(cm, measure) {
+    cm.display.sizer.style.minHeight = measure.docHeight + "px";
+    var total = measure.docHeight + cm.display.barHeight;
+    cm.display.heightForcer.style.top = total + "px";
+    cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px";
+  }
+
+  // Read the actual heights of the rendered lines, and update their
+  // stored heights to match.
+  function updateHeightsInViewport(cm) {
+    var display = cm.display;
+    var prevBottom = display.lineDiv.offsetTop;
+    for (var i = 0; i < display.view.length; i++) {
+      var cur = display.view[i], height;
+      if (cur.hidden) continue;
+      if (ie && ie_version < 8) {
+        var bot = cur.node.offsetTop + cur.node.offsetHeight;
+        height = bot - prevBottom;
+        prevBottom = bot;
+      } else {
+        var box = cur.node.getBoundingClientRect();
+        height = box.bottom - box.top;
+      }
+      var diff = cur.line.height - height;
+      if (height < 2) height = textHeight(display);
+      if (diff > .001 || diff < -.001) {
+        updateLineHeight(cur.line, height);
+        updateWidgetHeight(cur.line);
+        if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
+          updateWidgetHeight(cur.rest[j]);
+      }
+    }
+  }
+
+  // Read and store the height of line widgets associated with the
+  // given line.
+  function updateWidgetHeight(line) {
+    if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
+      line.widgets[i].height = line.widgets[i].node.offsetHeight;
+  }
+
+  // Do a bulk-read of the DOM positions and sizes needed to draw the
+  // view, so that we don't interleave reading and writing to the DOM.
+  function getDimensions(cm) {
+    var d = cm.display, left = {}, width = {};
+    var gutterLeft = d.gutters.clientLeft;
+    for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
+      left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
+      width[cm.options.gutters[i]] = n.clientWidth;
+    }
+    return {fixedPos: compensateForHScroll(d),
+            gutterTotalWidth: d.gutters.offsetWidth,
+            gutterLeft: left,
+            gutterWidth: width,
+            wrapperWidth: d.wrapper.clientWidth};
+  }
+
+  // Sync the actual display DOM structure with display.view, removing
+  // nodes for lines that are no longer in view, and creating the ones
+  // that are not there yet, and updating the ones that are out of
+  // date.
+  function patchDisplay(cm, updateNumbersFrom, dims) {
+    var display = cm.display, lineNumbers = cm.options.lineNumbers;
+    var container = display.lineDiv, cur = container.firstChild;
+
+    function rm(node) {
+      var next = node.nextSibling;
+      // Works around a throw-scroll bug in OS X Webkit
+      if (webkit && mac && cm.display.currentWheelTarget == node)
+        node.style.display = "none";
+      else
+        node.parentNode.removeChild(node);
+      return next;
+    }
+
+    var view = display.view, lineN = display.viewFrom;
+    // Loop over the elements in the view, syncing cur (the DOM nodes
+    // in display.lineDiv) with the view as we go.
+    for (var i = 0; i < view.length; i++) {
+      var lineView = view[i];
+      if (lineView.hidden) {
+      } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
+        var node = buildLineElement(cm, lineView, lineN, dims);
+        container.insertBefore(node, cur);
+      } else { // Already drawn
+        while (cur != lineView.node) cur = rm(cur);
+        var updateNumber = lineNumbers && updateNumbersFrom != null &&
+          updateNumbersFrom <= lineN && lineView.lineNumber;
+        if (lineView.changes) {
+          if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
+          updateLineForChanges(cm, lineView, lineN, dims);
+        }
+        if (updateNumber) {
+          removeChildren(lineView.lineNumber);
+          lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
+        }
+        cur = lineView.node.nextSibling;
+      }
+      lineN += lineView.size;
+    }
+    while (cur) cur = rm(cur);
+  }
+
+  // When an aspect of a line changes, a string is added to
+  // lineView.changes. This updates the relevant part of the line's
+  // DOM structure.
+  function updateLineForChanges(cm, lineView, lineN, dims) {
+    for (var j = 0; j < lineView.changes.length; j++) {
+      var type = lineView.changes[j];
+      if (type == "text") updateLineText(cm, lineView);
+      else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
+      else if (type == "class") updateLineClasses(lineView);
+      else if (type == "widget") updateLineWidgets(cm, lineView, dims);
+    }
+    lineView.changes = null;
+  }
+
+  // Lines with gutter elements, widgets or a background class need to
+  // be wrapped, and have the extra elements added to the wrapper div
+  function ensureLineWrapped(lineView) {
+    if (lineView.node == lineView.text) {
+      lineView.node = elt("div", null, null, "position: relative");
+      if (lineView.text.parentNode)
+        lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
+      lineView.node.appendChild(lineView.text);
+      if (ie && ie_version < 8) lineView.node.style.zIndex = 2;
+    }
+    return lineView.node;
+  }
+
+  function updateLineBackground(lineView) {
+    var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
+    if (cls) cls += " CodeMirror-linebackground";
+    if (lineView.background) {
+      if (cls) lineView.background.className = cls;
+      else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
+    } else if (cls) {
+      var wrap = ensureLineWrapped(lineView);
+      lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
+    }
+  }
+
+  // Wrapper around buildLineContent which will reuse the structure
+  // in display.externalMeasured when possible.
+  function getLineContent(cm, lineView) {
+    var ext = cm.display.externalMeasured;
+    if (ext && ext.line == lineView.line) {
+      cm.display.externalMeasured = null;
+      lineView.measure = ext.measure;
+      return ext.built;
+    }
+    return buildLineContent(cm, lineView);
+  }
+
+  // Redraw the line's text. Interacts with the background and text
+  // classes because the mode may output tokens that influence these
+  // classes.
+  function updateLineText(cm, lineView) {
+    var cls = lineView.text.className;
+    var built = getLineContent(cm, lineView);
+    if (lineView.text == lineView.node) lineView.node = built.pre;
+    lineView.text.parentNode.replaceChild(built.pre, lineView.text);
+    lineView.text = built.pre;
+    if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
+      lineView.bgClass = built.bgClass;
+      lineView.textClass = built.textClass;
+      updateLineClasses(lineView);
+    } else if (cls) {
+      lineView.text.className = cls;
+    }
+  }
+
+  function updateLineClasses(lineView) {
+    updateLineBackground(lineView);
+    if (lineView.line.wrapClass)
+      ensureLineWrapped(lineView).className = lineView.line.wrapClass;
+    else if (lineView.node != lineView.text)
+      lineView.node.className = "";
+    var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
+    lineView.text.className = textClass || "";
+  }
+
+  function updateLineGutter(cm, lineView, lineN, dims) {
+    if (lineView.gutter) {
+      lineView.node.removeChild(lineView.gutter);
+      lineView.gutter = null;
+    }
+    if (lineView.gutterBackground) {
+      lineView.node.removeChild(lineView.gutterBackground);
+      lineView.gutterBackground = null;
+    }
+    if (lineView.line.gutterClass) {
+      var wrap = ensureLineWrapped(lineView);
+      lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
+                                      "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
+                                      "px; width: " + dims.gutterTotalWidth + "px");
+      wrap.insertBefore(lineView.gutterBackground, lineView.text);
+    }
+    var markers = lineView.line.gutterMarkers;
+    if (cm.options.lineNumbers || markers) {
+      var wrap = ensureLineWrapped(lineView);
+      var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
+                                             (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px");
+      cm.display.input.setUneditable(gutterWrap);
+      wrap.insertBefore(gutterWrap, lineView.text);
+      if (lineView.line.gutterClass)
+        gutterWrap.className += " " + lineView.line.gutterClass;
+      if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
+        lineView.lineNumber = gutterWrap.appendChild(
+          elt("div", lineNumberFor(cm.options, lineN),
+              "CodeMirror-linenumber CodeMirror-gutter-elt",
+              "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
+              + cm.display.lineNumInnerWidth + "px"));
+      if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
+        var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
+        if (found)
+          gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
+                                     dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
+      }
+    }
+  }
+
+  function updateLineWidgets(cm, lineView, dims) {
+    if (lineView.alignable) lineView.alignable = null;
+    for (var node = lineView.node.firstChild, next; node; node = next) {
+      var next = node.nextSibling;
+      if (node.className == "CodeMirror-linewidget")
+        lineView.node.removeChild(node);
+    }
+    insertLineWidgets(cm, lineView, dims);
+  }
+
+  // Build a line's DOM representation from scratch
+  function buildLineElement(cm, lineView, lineN, dims) {
+    var built = getLineContent(cm, lineView);
+    lineView.text = lineView.node = built.pre;
+    if (built.bgClass) lineView.bgClass = built.bgClass;
+    if (built.textClass) lineView.textClass = built.textClass;
+
+    updateLineClasses(lineView);
+    updateLineGutter(cm, lineView, lineN, dims);
+    insertLineWidgets(cm, lineView, dims);
+    return lineView.node;
+  }
+
+  // A lineView may contain multiple logical lines (when merged by
+  // collapsed spans). The widgets for all of them need to be drawn.
+  function insertLineWidgets(cm, lineView, dims) {
+    insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
+    if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
+      insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false);
+  }
+
+  function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
+    if (!line.widgets) return;
+    var wrap = ensureLineWrapped(lineView);
+    for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
+      var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
+      if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true");
+      positionLineWidget(widget, node, lineView, dims);
+      cm.display.input.setUneditable(node);
+      if (allowAbove && widget.above)
+        wrap.insertBefore(node, lineView.gutter || lineView.text);
+      else
+        wrap.appendChild(node);
+      signalLater(widget, "redraw");
+    }
+  }
+
+  function positionLineWidget(widget, node, lineView, dims) {
+    if (widget.noHScroll) {
+      (lineView.alignable || (lineView.alignable = [])).push(node);
+      var width = dims.wrapperWidth;
+      node.style.left = dims.fixedPos + "px";
+      if (!widget.coverGutter) {
+        width -= dims.gutterTotalWidth;
+        node.style.paddingLeft = dims.gutterTotalWidth + "px";
+      }
+      node.style.width = width + "px";
+    }
+    if (widget.coverGutter) {
+      node.style.zIndex = 5;
+      node.style.position = "relative";
+      if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
+    }
+  }
+
+  // POSITION OBJECT
+
+  // A Pos instance represents a position within the text.
+  var Pos = CodeMirror.Pos = function(line, ch) {
+    if (!(this instanceof Pos)) return new Pos(line, ch);
+    this.line = line; this.ch = ch;
+  };
+
+  // Compare two positions, return 0 if they are the same, a negative
+  // number when a is less, and a positive number otherwise.
+  var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
+
+  function copyPos(x) {return Pos(x.line, x.ch);}
+  function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
+  function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
+
+  // INPUT HANDLING
+
+  function ensureFocus(cm) {
+    if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
+  }
+
+  function isReadOnly(cm) {
+    return cm.options.readOnly || cm.doc.cantEdit;
+  }
+
+  // This will be set to an array of strings when copying, so that,
+  // when pasting, we know what kind of selections the copied text
+  // was made out of.
+  var lastCopied = null;
+
+  function applyTextInput(cm, inserted, deleted, sel, origin) {
+    var doc = cm.doc;
+    cm.display.shift = false;
+    if (!sel) sel = doc.sel;
+
+    var paste = cm.state.pasteIncoming || origin == "paste";
+    var textLines = doc.splitLines(inserted), multiPaste = null;
+    // When pasing N lines into N selections, insert one line per selection
+    if (paste && sel.ranges.length > 1) {
+      if (lastCopied && lastCopied.join("\n") == inserted) {
+        if (sel.ranges.length % lastCopied.length == 0) {
+          multiPaste = [];
+          for (var i = 0; i < lastCopied.length; i++)
+            multiPaste.push(doc.splitLines(lastCopied[i]));
+        }
+      } else if (textLines.length == sel.ranges.length) {
+        multiPaste = map(textLines, function(l) { return [l]; });
+      }
+    }
+
+    // Normal behavior is to insert the new text into every selection
+    for (var i = sel.ranges.length - 1; i >= 0; i--) {
+      var range = sel.ranges[i];
+      var from = range.from(), to = range.to();
+      if (range.empty()) {
+        if (deleted && deleted > 0) // Handle deletion
+          from = Pos(from.line, from.ch - deleted);
+        else if (cm.state.overwrite && !paste) // Handle overwrite
+          to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
+      }
+      var updateInput = cm.curOp.updateInput;
+      var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
+                         origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
+      makeChange(cm.doc, changeEvent);
+      signalLater(cm, "inputRead", cm, changeEvent);
+    }
+    if (inserted && !paste)
+      triggerElectric(cm, inserted);
+
+    ensureCursorVisible(cm);
+    cm.curOp.updateInput = updateInput;
+    cm.curOp.typing = true;
+    cm.state.pasteIncoming = cm.state.cutIncoming = false;
+  }
+
+  function handlePaste(e, cm) {
+    var pasted = e.clipboardData && e.clipboardData.getData("text/plain");
+    if (pasted) {
+      e.preventDefault();
+      if (!isReadOnly(cm) && !cm.options.disableInput)
+        runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); });
+      return true;
+    }
+  }
+
+  function triggerElectric(cm, inserted) {
+    // When an 'electric' character is inserted, immediately trigger a reindent
+    if (!cm.options.electricChars || !cm.options.smartIndent) return;
+    var sel = cm.doc.sel;
+
+    for (var i = sel.ranges.length - 1; i >= 0; i--) {
+      var range = sel.ranges[i];
+      if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue;
+      var mode = cm.getModeAt(range.head);
+      var indented = false;
+      if (mode.electricChars) {
+        for (var j = 0; j < mode.electricChars.length; j++)
+          if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
+            indented = indentLine(cm, range.head.line, "smart");
+            break;
+          }
+      } else if (mode.electricInput) {
+        if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
+          indented = indentLine(cm, range.head.line, "smart");
+      }
+      if (indented) signalLater(cm, "electricInput", cm, range.head.line);
+    }
+  }
+
+  function copyableRanges(cm) {
+    var text = [], ranges = [];
+    for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
+      var line = cm.doc.sel.ranges[i].head.line;
+      var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
+      ranges.push(lineRange);
+      text.push(cm.getRange(lineRange.anchor, lineRange.head));
+    }
+    return {text: text, ranges: ranges};
+  }
+
+  function disableBrowserMagic(field) {
+    field.setAttribute("autocorrect", "off");
+    field.setAttribute("autocapitalize", "off");
+    field.setAttribute("spellcheck", "false");
+  }
+
+  // TEXTAREA INPUT STYLE
+
+  function TextareaInput(cm) {
+    this.cm = cm;
+    // See input.poll and input.reset
+    this.prevInput = "";
+
+    // Flag that indicates whether we expect input to appear real soon
+    // now (after some event like 'keypress' or 'input') and are
+    // polling intensively.
+    this.pollingFast = false;
+    // Self-resetting timeout for the poller
+    this.polling = new Delayed();
+    // Tracks when input.reset has punted to just putting a short
+    // string into the textarea instead of the full selection.
+    this.inaccurateSelection = false;
+    // Used to work around IE issue with selection being forgotten when focus moves away from textarea
+    this.hasSelection = false;
+    this.composing = null;
+  };
+
+  function hiddenTextarea() {
+    var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
+    var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
+    // The textarea is kept positioned near the cursor to prevent the
+    // fact that it'll be scrolled into view on input from scrolling
+    // our fake cursor out of view. On webkit, when wrap=off, paste is
+    // very slow. So make the area wide instead.
+    if (webkit) te.style.width = "1000px";
+    else te.setAttribute("wrap", "off");
+    // If border: 0; -- iOS fails to open keyboard (issue #1287)
+    if (ios) te.style.border = "1px solid black";
+    disableBrowserMagic(te);
+    return div;
+  }
+
+  TextareaInput.prototype = copyObj({
+    init: function(display) {
+      var input = this, cm = this.cm;
+
+      // Wraps and hides input textarea
+      var div = this.wrapper = hiddenTextarea();
+      // The semihidden textarea that is focused when the editor is
+      // focused, and receives input.
+      var te = this.textarea = div.firstChild;
+      display.wrapper.insertBefore(div, display.wrapper.firstChild);
+
+      // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
+      if (ios) te.style.width = "0px";
+
+      on(te, "input", function() {
+        if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null;
+        input.poll();
+      });
+
+      on(te, "paste", function(e) {
+        if (handlePaste(e, cm)) return true;
+
+        cm.state.pasteIncoming = true;
+        input.fastPoll();
+      });
+
+      function prepareCopyCut(e) {
+        if (cm.somethingSelected()) {
+          lastCopied = cm.getSelections();
+          if (input.inaccurateSelection) {
+            input.prevInput = "";
+            input.inaccurateSelection = false;
+            te.value = lastCopied.join("\n");
+            selectInput(te);
+          }
+        } else if (!cm.options.lineWiseCopyCut) {
+          return;
+        } else {
+          var ranges = copyableRanges(cm);
+          lastCopied = ranges.text;
+          if (e.type == "cut") {
+            cm.setSelections(ranges.ranges, null, sel_dontScroll);
+          } else {
+            input.prevInput = "";
+            te.value = ranges.text.join("\n");
+            selectInput(te);
+          }
+        }
+        if (e.type == "cut") cm.state.cutIncoming = true;
+      }
+      on(te, "cut", prepareCopyCut);
+      on(te, "copy", prepareCopyCut);
+
+      on(display.scroller, "paste", function(e) {
+        if (eventInWidget(display, e)) return;
+        cm.state.pasteIncoming = true;
+        input.focus();
+      });
+
+      // Prevent normal selection in the editor (we handle our own)
+      on(display.lineSpace, "selectstart", function(e) {
+        if (!eventInWidget(display, e)) e_preventDefault(e);
+      });
+
+      on(te, "compositionstart", function() {
+        var start = cm.getCursor("from");
+        if (input.composing) input.composing.range.clear()
+        input.composing = {
+          start: start,
+          range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
+        };
+      });
+      on(te, "compositionend", function() {
+        if (input.composing) {
+          input.poll();
+          input.composing.range.clear();
+          input.composing = null;
+        }
+      });
+    },
+
+    prepareSelection: function() {
+      // Redraw the selection and/or cursor
+      var cm = this.cm, display = cm.display, doc = cm.doc;
+      var result = prepareSelection(cm);
+
+      // Move the hidden textarea near the cursor to prevent scrolling artifacts
+      if (cm.options.moveInputWithCursor) {
+        var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
+        var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
+        result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
+                                            headPos.top + lineOff.top - wrapOff.top));
+        result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
+                                             headPos.left + lineOff.left - wrapOff.left));
+      }
+
+      return result;
+    },
+
+    showSelection: function(drawn) {
+      var cm = this.cm, display = cm.display;
+      removeChildrenAndAdd(display.cursorDiv, drawn.cursors);
+      removeChildrenAndAdd(display.selectionDiv, drawn.selection);
+      if (drawn.teTop != null) {
+        this.wrapper.style.top = drawn.teTop + "px";
+        this.wrapper.style.left = drawn.teLeft + "px";
+      }
+    },
+
+    // Reset the input to correspond to the selection (or to be empty,
+    // when not typing and nothing is selected)
+    reset: function(typing) {
+      if (this.contextMenuPending) return;
+      var minimal, selected, cm = this.cm, doc = cm.doc;
+      if (cm.somethingSelected()) {
+        this.prevInput = "";
+        var range = doc.sel.primary();
+        minimal = hasCopyEvent &&
+          (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
+        var content = minimal ? "-" : selected || cm.getSelection();
+        this.textarea.value = content;
+        if (cm.state.focused) selectInput(this.textarea);
+        if (ie && ie_version >= 9) this.hasSelection = content;
+      } else if (!typing) {
+        this.prevInput = this.textarea.value = "";
+        if (ie && ie_version >= 9) this.hasSelection = null;
+      }
+      this.inaccurateSelection = minimal;
+    },
+
+    getField: function() { return this.textarea; },
+
+    supportsTouch: function() { return false; },
+
+    focus: function() {
+      if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
+        try { this.textarea.focus(); }
+        catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
+      }
+    },
+
+    blur: function() { this.textarea.blur(); },
+
+    resetPosition: function() {
+      this.wrapper.style.top = this.wrapper.style.left = 0;
+    },
+
+    receivedFocus: function() { this.slowPoll(); },
+
+    // Poll for input changes, using the normal rate of polling. This
+    // runs as long as the editor is focused.
+    slowPoll: function() {
+      var input = this;
+      if (input.pollingFast) return;
+      input.polling.set(this.cm.options.pollInterval, function() {
+        input.poll();
+        if (input.cm.state.focused) input.slowPoll();
+      });
+    },
+
+    // When an event has just come in that is likely to add or change
+    // something in the input textarea, we poll faster, to ensure that
+    // the change appears on the screen quickly.
+    fastPoll: function() {
+      var missed = false, input = this;
+      input.pollingFast = true;
+      function p() {
+        var changed = input.poll();
+        if (!changed && !missed) {missed = true; input.polling.set(60, p);}
+        else {input.pollingFast = false; input.slowPoll();}
+      }
+      input.polling.set(20, p);
+    },
+
+    // Read input from the textarea, and update the document to match.
+    // When something is selected, it is present in the textarea, and
+    // selected (unless it is huge, in which case a placeholder is
+    // used). When nothing is selected, the cursor sits after previously
+    // seen text (can be empty), which is stored in prevInput (we must
+    // not reset the textarea when typing, because that breaks IME).
+    poll: function() {
+      var cm = this.cm, input = this.textarea, prevInput = this.prevInput;
+      // Since this is called a *lot*, try to bail out as cheaply as
+      // possible when it is clear that nothing happened. hasSelection
+      // will be the case when there is a lot of text in the textarea,
+      // in which case reading its value would be expensive.
+      if (this.contextMenuPending || !cm.state.focused ||
+          (hasSelection(input) && !prevInput && !this.composing) ||
+          isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)
+        return false;
+
+      var text = input.value;
+      // If nothing changed, bail.
+      if (text == prevInput && !cm.somethingSelected()) return false;
+      // Work around nonsensical selection resetting in IE9/10, and
+      // inexplicable appearance of private area unicode characters on
+      // some key combos in Mac (#2689).
+      if (ie && ie_version >= 9 && this.hasSelection === text ||
+          mac && /[\uf700-\uf7ff]/.test(text)) {
+        cm.display.input.reset();
+        return false;
+      }
+
+      if (cm.doc.sel == cm.display.selForContextMenu) {
+        var first = text.charCodeAt(0);
+        if (first == 0x200b && !prevInput) prevInput = "\u200b";
+        if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); }
+      }
+      // Find the part of the input that is actually new
+      var same = 0, l = Math.min(prevInput.length, text.length);
+      while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
+
+      var self = this;
+      runInOp(cm, function() {
+        applyTextInput(cm, text.slice(same), prevInput.length - same,
+                       null, self.composing ? "*compose" : null);
+
+        // Don't leave long text in the textarea, since it makes further polling slow
+        if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = "";
+        else self.prevInput = text;
+
+        if (self.composing) {
+          self.composing.range.clear();
+          self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"),
+                                             {className: "CodeMirror-composing"});
+        }
+      });
+      return true;
+    },
+
+    ensurePolled: function() {
+      if (this.pollingFast && this.poll()) this.pollingFast = false;
+    },
+
+    onKeyPress: function() {
+      if (ie && ie_version >= 9) this.hasSelection = null;
+      this.fastPoll();
+    },
+
+    onContextMenu: function(e) {
+      var input = this, cm = input.cm, display = cm.display, te = input.textarea;
+      var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
+      if (!pos || presto) return; // Opera is difficult.
+
+      // Reset the current text selection only if the click is done outside of the selection
+      // and 'resetSelectionOnContextMenu' option is true.
+      var reset = cm.options.resetSelectionOnContextMenu;
+      if (reset && cm.doc.sel.contains(pos) == -1)
+        operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
+
+      var oldCSS = te.style.cssText;
+      input.wrapper.style.position = "absolute";
+      te.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
+        "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
+        (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
+        "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
+      if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
+      display.input.focus();
+      if (webkit) window.scrollTo(null, oldScrollY);
+      display.input.reset();
+      // Adds "Select all" to context menu in FF
+      if (!cm.somethingSelected()) te.value = input.prevInput = " ";
+      input.contextMenuPending = true;
+      display.selForContextMenu = cm.doc.sel;
+      clearTimeout(display.detectingSelectAll);
+
+      // Select-all will be greyed out if there's nothing to select, so
+      // this adds a zero-width space so that we can later check whether
+      // it got selected.
+      function prepareSelectAllHack() {
+        if (te.selectionStart != null) {
+          var selected = cm.somethingSelected();
+          var extval = "\u200b" + (selected ? te.value : "");
+          te.value = "\u21da"; // Used to catch context-menu undo
+          te.value = extval;
+          input.prevInput = selected ? "" : "\u200b";
+          te.selectionStart = 1; te.selectionEnd = extval.length;
+          // Re-set this, in case some other handler touched the
+          // selection in the meantime.
+          display.selForContextMenu = cm.doc.sel;
+        }
+      }
+      function rehide() {
+        input.contextMenuPending = false;
+        input.wrapper.style.position = "relative";
+        te.style.cssText = oldCSS;
+        if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);
+
+        // Try to detect the user choosing select-all
+        if (te.selectionStart != null) {
+          if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
+          var i = 0, poll = function() {
+            if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
+                te.selectionEnd > 0 && input.prevInput == "\u200b")
+              operation(cm, commands.selectAll)(cm);
+            else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
+            else display.input.reset();
+          };
+          display.detectingSelectAll = setTimeout(poll, 200);
+        }
+      }
+
+      if (ie && ie_version >= 9) prepareSelectAllHack();
+      if (captureRightClick) {
+        e_stop(e);
+        var mouseup = function() {
+          off(window, "mouseup", mouseup);
+          setTimeout(rehide, 20);
+        };
+        on(window, "mouseup", mouseup);
+      } else {
+        setTimeout(rehide, 50);
+      }
+    },
+
+    readOnlyChanged: function(val) {
+      if (!val) this.reset();
+    },
+
+    setUneditable: nothing,
+
+    needsContentAttribute: false
+  }, TextareaInput.prototype);
+
+  // CONTENTEDITABLE INPUT STYLE
+
+  function ContentEditableInput(cm) {
+    this.cm = cm;
+    this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
+    this.polling = new Delayed();
+    this.gracePeriod = false;
+  }
+
+  ContentEditableInput.prototype = copyObj({
+    init: function(display) {
+      var input = this, cm = input.cm;
+      var div = input.div = display.lineDiv;
+      disableBrowserMagic(div);
+
+      on(div, "paste", function(e) { handlePaste(e, cm); })
+
+      on(div, "compositionstart", function(e) {
+        var data = e.data;
+        input.composing = {sel: cm.doc.sel, data: data, startData: data};
+        if (!data) return;
+        var prim = cm.doc.sel.primary();
+        var line = cm.getLine(prim.head.line);
+        var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length));
+        if (found > -1 && found <= prim.head.ch)
+          input.composing.sel = simpleSelection(Pos(prim.head.line, found),
+                                                Pos(prim.head.line, found + data.length));
+      });
+      on(div, "compositionupdate", function(e) {
+        input.composing.data = e.data;
+      });
+      on(div, "compositionend", function(e) {
+        var ours = input.composing;
+        if (!ours) return;
+        if (e.data != ours.startData && !/\u200b/.test(e.data))
+          ours.data = e.data;
+        // Need a small delay to prevent other code (input event,
+        // selection polling) from doing damage when fired right after
+        // compositionend.
+        setTimeout(function() {
+          if (!ours.handled)
+            input.applyComposition(ours);
+          if (input.composing == ours)
+            input.composing = null;
+        }, 50);
+      });
+
+      on(div, "touchstart", function() {
+        input.forceCompositionEnd();
+      });
+
+      on(div, "input", function() {
+        if (input.composing) return;
+        if (isReadOnly(cm) || !input.pollContent())
+          runInOp(input.cm, function() {regChange(cm);});
+      });
+
+      function onCopyCut(e) {
+        if (cm.somethingSelected()) {
+          lastCopied = cm.getSelections();
+          if (e.type == "cut") cm.replaceSelection("", null, "cut");
+        } else if (!cm.options.lineWiseCopyCut) {
+          return;
+        } else {
+          var ranges = copyableRanges(cm);
+          lastCopied = ranges.text;
+          if (e.type == "cut") {
+            cm.operation(function() {
+              cm.setSelections(ranges.ranges, 0, sel_dontScroll);
+              cm.replaceSelection("", null, "cut");
+            });
+          }
+        }
+        // iOS exposes the clipboard API, but seems to discard content inserted into it
+        if (e.clipboardData && !ios) {
+          e.preventDefault();
+          e.clipboardData.clearData();
+          e.clipboardData.setData("text/plain", lastCopied.join("\n"));
+        } else {
+          // Old-fashioned briefly-focus-a-textarea hack
+          var kludge = hiddenTextarea(), te = kludge.firstChild;
+          cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
+          te.value = lastCopied.join("\n");
+          var hadFocus = document.activeElement;
+          selectInput(te);
+          setTimeout(function() {
+            cm.display.lineSpace.removeChild(kludge);
+            hadFocus.focus();
+          }, 50);
+        }
+      }
+      on(div, "copy", onCopyCut);
+      on(div, "cut", onCopyCut);
+    },
+
+    prepareSelection: function() {
+      var result = prepareSelection(this.cm, false);
+      result.focus = this.cm.state.focused;
+      return result;
+    },
+
+    showSelection: function(info) {
+      if (!info || !this.cm.display.view.length) return;
+      if (info.focus) this.showPrimarySelection();
+      this.showMultipleSelections(info);
+    },
+
+    showPrimarySelection: function() {
+      var sel = window.getSelection(), prim = this.cm.doc.sel.primary();
+      var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset);
+      var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset);
+      if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
+          cmp(minPos(curAnchor, curFocus), prim.from()) == 0 &&
+          cmp(maxPos(curAnchor, curFocus), prim.to()) == 0)
+        return;
+
+      var start = posToDOM(this.cm, prim.from());
+      var end = posToDOM(this.cm, prim.to());
+      if (!start && !end) return;
+
+      var view = this.cm.display.view;
+      var old = sel.rangeCount && sel.getRangeAt(0);
+      if (!start) {
+        start = {node: view[0].measure.map[2], offset: 0};
+      } else if (!end) { // FIXME dangerously hacky
+        var measure = view[view.length - 1].measure;
+        var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
+        end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]};
+      }
+
+      try { var rng = range(start.node, start.offset, end.offset, end.node); }
+      catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
+      if (rng) {
+        sel.removeAllRanges();
+        sel.addRange(rng);
+        if (old && sel.anchorNode == null) sel.addRange(old);
+        else if (gecko) this.startGracePeriod();
+      }
+      this.rememberSelection();
+    },
+
+    startGracePeriod: function() {
+      var input = this;
+      clearTimeout(this.gracePeriod);
+      this.gracePeriod = setTimeout(function() {
+        input.gracePeriod = false;
+        if (input.selectionChanged())
+          input.cm.operation(function() { input.cm.curOp.selectionChanged = true; });
+      }, 20);
+    },
+
+    showMultipleSelections: function(info) {
+      removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
+      removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
+    },
+
+    rememberSelection: function() {
+      var sel = window.getSelection();
+      this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
+      this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
+    },
+
+    selectionInEditor: function() {
+      var sel = window.getSelection();
+      if (!sel.rangeCount) return false;
+      var node = sel.getRangeAt(0).commonAncestorContainer;
+      return contains(this.div, node);
+    },
+
+    focus: function() {
+      if (this.cm.options.readOnly != "nocursor") this.div.focus();
+    },
+    blur: function() { this.div.blur(); },
+    getField: function() { return this.div; },
+
+    supportsTouch: function() { return true; },
+
+    receivedFocus: function() {
+      var input = this;
+      if (this.selectionInEditor())
+        this.pollSelection();
+      else
+        runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; });
+
+      function poll() {
+        if (input.cm.state.focused) {
+          input.pollSelection();
+          input.polling.set(input.cm.options.pollInterval, poll);
+        }
+      }
+      this.polling.set(this.cm.options.pollInterval, poll);
+    },
+
+    selectionChanged: function() {
+      var sel = window.getSelection();
+      return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
+        sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset;
+    },
+
+    pollSelection: function() {
+      if (!this.composing && !this.gracePeriod && this.selectionChanged()) {
+        var sel = window.getSelection(), cm = this.cm;
+        this.rememberSelection();
+        var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
+        var head = domToPos(cm, sel.focusNode, sel.focusOffset);
+        if (anchor && head) runInOp(cm, function() {
+          setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll);
+          if (anchor.bad || head.bad) cm.curOp.selectionChanged = true;
+        });
+      }
+    },
+
+    pollContent: function() {
+      var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
+      var from = sel.from(), to = sel.to();
+      if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false;
+
+      var fromIndex;
+      if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
+        var fromLine = lineNo(display.view[0].line);
+        var fromNode = display.view[0].node;
+      } else {
+        var fromLine = lineNo(display.view[fromIndex].line);
+        var fromNode = display.view[fromIndex - 1].node.nextSibling;
+      }
+      var toIndex = findViewIndex(cm, to.line);
+      if (toIndex == display.view.length - 1) {
+        var toLine = display.viewTo - 1;
+        var toNode = display.lineDiv.lastChild;
+      } else {
+        var toLine = lineNo(display.view[toIndex + 1].line) - 1;
+        var toNode = display.view[toIndex + 1].node.previousSibling;
+      }
+
+      var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
+      var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
+      while (newText.length > 1 && oldText.length > 1) {
+        if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
+        else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; }
+        else break;
+      }
+
+      var cutFront = 0, cutEnd = 0;
+      var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length);
+      while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
+        ++cutFront;
+      var newBot = lst(newText), oldBot = lst(oldText);
+      var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
+                               oldBot.length - (oldText.length == 1 ? cutFront : 0));
+      while (cutEnd < maxCutEnd &&
+             newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
+        ++cutEnd;
+
+      newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd);
+      newText[0] = newText[0].slice(cutFront);
+
+      var chFrom = Pos(fromLine, cutFront);
+      var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0);
+      if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
+        replaceRange(cm.doc, newText, chFrom, chTo, "+input");
+        return true;
+      }
+    },
+
+    ensurePolled: function() {
+      this.forceCompositionEnd();
+    },
+    reset: function() {
+      this.forceCompositionEnd();
+    },
+    forceCompositionEnd: function() {
+      if (!this.composing || this.composing.handled) return;
+      this.applyComposition(this.composing);
+      this.composing.handled = true;
+      this.div.blur();
+      this.div.focus();
+    },
+    applyComposition: function(composing) {
+      if (isReadOnly(this.cm))
+        operation(this.cm, regChange)(this.cm)
+      else if (composing.data && composing.data != composing.startData)
+        operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel);
+    },
+
+    setUneditable: function(node) {
+      node.contentEditable = "false"
+    },
+
+    onKeyPress: function(e) {
+      e.preventDefault();
+      if (!isReadOnly(this.cm))
+        operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0);
+    },
+
+    readOnlyChanged: function(val) {
+      this.div.contentEditable = String(val != "nocursor")
+    },
+
+    onContextMenu: nothing,
+    resetPosition: nothing,
+
+    needsContentAttribute: true
+  }, ContentEditableInput.prototype);
+
+  function posToDOM(cm, pos) {
+    var view = findViewForLine(cm, pos.line);
+    if (!view || view.hidden) return null;
+    var line = getLine(cm.doc, pos.line);
+    var info = mapFromLineView(view, line, pos.line);
+
+    var order = getOrder(line), side = "left";
+    if (order) {
+      var partPos = getBidiPartAt(order, pos.ch);
+      side = partPos % 2 ? "right" : "left";
+    }
+    var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
+    result.offset = result.collapse == "right" ? result.end : result.start;
+    return result;
+  }
+
+  function badPos(pos, bad) { if (bad) pos.bad = true; return pos; }
+
+  function domToPos(cm, node, offset) {
+    var lineNode;
+    if (node == cm.display.lineDiv) {
+      lineNode = cm.display.lineDiv.childNodes[offset];
+      if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true);
+      node = null; offset = 0;
+    } else {
+      for (lineNode = node;; lineNode = lineNode.parentNode) {
+        if (!lineNode || lineNode == cm.display.lineDiv) return null;
+        if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break;
+      }
+    }
+    for (var i = 0; i < cm.display.view.length; i++) {
+      var lineView = cm.display.view[i];
+      if (lineView.node == lineNode)
+        return locateNodeInLineView(lineView, node, offset);
+    }
+  }
+
+  function locateNodeInLineView(lineView, node, offset) {
+    var wrapper = lineView.text.firstChild, bad = false;
+    if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true);
+    if (node == wrapper) {
+      bad = true;
+      node = wrapper.childNodes[offset];
+      offset = 0;
+      if (!node) {
+        var line = lineView.rest ? lst(lineView.rest) : lineView.line;
+        return badPos(Pos(lineNo(line), line.text.length), bad);
+      }
+    }
+
+    var textNode = node.nodeType == 3 ? node : null, topNode = node;
+    if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
+      textNode = node.firstChild;
+      if (offset) offset = textNode.nodeValue.length;
+    }
+    while (topNode.parentNode != wrapper) topNode = topNode.parentNode;
+    var measure = lineView.measure, maps = measure.maps;
+
+    function find(textNode, topNode, offset) {
+      for (var i = -1; i < (maps ? maps.length : 0); i++) {
+        var map = i < 0 ? measure.map : maps[i];
+        for (var j = 0; j < map.length; j += 3) {
+          var curNode = map[j + 2];
+          if (curNode == textNode || curNode == topNode) {
+            var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
+            var ch = map[j] + offset;
+            if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)];
+            return Pos(line, ch);
+          }
+        }
+      }
+    }
+    var found = find(textNode, topNode, offset);
+    if (found) return badPos(found, bad);
+
+    // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
+    for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
+      found = find(after, after.firstChild, 0);
+      if (found)
+        return badPos(Pos(found.line, found.ch - dist), bad);
+      else
+        dist += after.textContent.length;
+    }
+    for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) {
+      found = find(before, before.firstChild, -1);
+      if (found)
+        return badPos(Pos(found.line, found.ch + dist), bad);
+      else
+        dist += after.textContent.length;
+    }
+  }
+
+  function domTextBetween(cm, from, to, fromLine, toLine) {
+    var text = "", closing = false, lineSep = cm.doc.lineSeparator();
+    function recognizeMarker(id) { return function(marker) { return marker.id == id; }; }
+    function walk(node) {
+      if (node.nodeType == 1) {
+        var cmText = node.getAttribute("cm-text");
+        if (cmText != null) {
+          if (cmText == "") cmText = node.textContent.replace(/\u200b/g, "");
+          text += cmText;
+          return;
+        }
+        var markerID = node.getAttribute("cm-marker"), range;
+        if (markerID) {
+          var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
+          if (found.length && (range = found[0].find()))
+            text += getBetween(cm.doc, range.from, range.to).join(lineSep);
+          return;
+        }
+        if (node.getAttribute("contenteditable") == "false") return;
+        for (var i = 0; i < node.childNodes.length; i++)
+          walk(node.childNodes[i]);
+        if (/^(pre|div|p)$/i.test(node.nodeName))
+          closing = true;
+      } else if (node.nodeType == 3) {
+        var val = node.nodeValue;
+        if (!val) return;
+        if (closing) {
+          text += lineSep;
+          closing = false;
+        }
+        text += val;
+      }
+    }
+    for (;;) {
+      walk(from);
+      if (from == to) break;
+      from = from.nextSibling;
+    }
+    return text;
+  }
+
+  CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
+
+  // SELECTION / CURSOR
+
+  // Selection objects are immutable. A new one is created every time
+  // the selection changes. A selection is one or more non-overlapping
+  // (and non-touching) ranges, sorted, and an integer that indicates
+  // which one is the primary selection (the one that's scrolled into
+  // view, that getCursor returns, etc).
+  function Selection(ranges, primIndex) {
+    this.ranges = ranges;
+    this.primIndex = primIndex;
+  }
+
+  Selection.prototype = {
+    primary: function() { return this.ranges[this.primIndex]; },
+    equals: function(other) {
+      if (other == this) return true;
+      if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
+      for (var i = 0; i < this.ranges.length; i++) {
+        var here = this.ranges[i], there = other.ranges[i];
+        if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
+      }
+      return true;
+    },
+    deepCopy: function() {
+      for (var out = [], i = 0; i < this.ranges.length; i++)
+        out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
+      return new Selection(out, this.primIndex);
+    },
+    somethingSelected: function() {
+      for (var i = 0; i < this.ranges.length; i++)
+        if (!this.ranges[i].empty()) return true;
+      return false;
+    },
+    contains: function(pos, end) {
+      if (!end) end = pos;
+      for (var i = 0; i < this.ranges.length; i++) {
+        var range = this.ranges[i];
+        if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
+          return i;
+      }
+      return -1;
+    }
+  };
+
+  function Range(anchor, head) {
+    this.anchor = anchor; this.head = head;
+  }
+
+  Range.prototype = {
+    from: function() { return minPos(this.anchor, this.head); },
+    to: function() { return maxPos(this.anchor, this.head); },
+    empty: function() {
+      return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
+    }
+  };
+
+  // Take an unsorted, potentially overlapping set of ranges, and
+  // build a selection out of it. 'Consumes' ranges array (modifying
+  // it).
+  function normalizeSelection(ranges, primIndex) {
+    var prim = ranges[primIndex];
+    ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
+    primIndex = indexOf(ranges, prim);
+    for (var i = 1; i < ranges.length; i++) {
+      var cur = ranges[i], prev = ranges[i - 1];
+      if (cmp(prev.to(), cur.from()) >= 0) {
+        var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
+        var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
+        if (i <= primIndex) --primIndex;
+        ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
+      }
+    }
+    return new Selection(ranges, primIndex);
+  }
+
+  function simpleSelection(anchor, head) {
+    return new Selection([new Range(anchor, head || anchor)], 0);
+  }
+
+  // Most of the external API clips given positions to make sure they
+  // actually exist within the document.
+  function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
+  function clipPos(doc, pos) {
+    if (pos.line < doc.first) return Pos(doc.first, 0);
+    var last = doc.first + doc.size - 1;
+    if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
+    return clipToLen(pos, getLine(doc, pos.line).text.length);
+  }
+  function clipToLen(pos, linelen) {
+    var ch = pos.ch;
+    if (ch == null || ch > linelen) return Pos(pos.line, linelen);
+    else if (ch < 0) return Pos(pos.line, 0);
+    else return pos;
+  }
+  function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
+  function clipPosArray(doc, array) {
+    for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
+    return out;
+  }
+
+  // SELECTION UPDATES
+
+  // The 'scroll' parameter given to many of these indicated whether
+  // the new cursor position should be scrolled into view after
+  // modifying the selection.
+
+  // If shift is held or the extend flag is set, extends a range to
+  // include a given position (and optionally a second position).
+  // Otherwise, simply returns the range between the given positions.
+  // Used for cursor motion and such.
+  function extendRange(doc, range, head, other) {
+    if (doc.cm && doc.cm.display.shift || doc.extend) {
+      var anchor = range.anchor;
+      if (other) {
+        var posBefore = cmp(head, anchor) < 0;
+        if (posBefore != (cmp(other, anchor) < 0)) {
+          anchor = head;
+          head = other;
+        } else if (posBefore != (cmp(head, other) < 0)) {
+          head = other;
+        }
+      }
+      return new Range(anchor, head);
+    } else {
+      return new Range(other || head, head);
+    }
+  }
+
+  // Extend the primary selection range, discard the rest.
+  function extendSelection(doc, head, other, options) {
+    setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
+  }
+
+  // Extend all selections (pos is an array of selections with length
+  // equal the number of selections)
+  function extendSelections(doc, heads, options) {
+    for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
+      out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
+    var newSel = normalizeSelection(out, doc.sel.primIndex);
+    setSelection(doc, newSel, options);
+  }
+
+  // Updates a single range in the selection.
+  function replaceOneSelection(doc, i, range, options) {
+    var ranges = doc.sel.ranges.slice(0);
+    ranges[i] = range;
+    setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
+  }
+
+  // Reset the selection to a single range.
+  function setSimpleSelection(doc, anchor, head, options) {
+    setSelection(doc, simpleSelection(anchor, head), options);
+  }
+
+  // Give beforeSelectionChange handlers a change to influence a
+  // selection update.
+  function filterSelectionChange(doc, sel) {
+    var obj = {
+      ranges: sel.ranges,
+      update: function(ranges) {
+        this.ranges = [];
+        for (var i = 0; i < ranges.length; i++)
+          this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
+                                     clipPos(doc, ranges[i].head));
+      }
+    };
+    signal(doc, "beforeSelectionChange", doc, obj);
+    if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
+    if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
+    else return sel;
+  }
+
+  function setSelectionReplaceHistory(doc, sel, options) {
+    var done = doc.history.done, last = lst(done);
+    if (last && last.ranges) {
+      done[done.length - 1] = sel;
+      setSelectionNoUndo(doc, sel, options);
+    } else {
+      setSelection(doc, sel, options);
+    }
+  }
+
+  // Set a new selection.
+  function setSelection(doc, sel, options) {
+    setSelectionNoUndo(doc, sel, options);
+    addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
+  }
+
+  function setSelectionNoUndo(doc, sel, options) {
+    if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
+      sel = filterSelectionChange(doc, sel);
+
+    var bias = options && options.bias ||
+      (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
+    setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
+
+    if (!(options && options.scroll === false) && doc.cm)
+      ensureCursorVisible(doc.cm);
+  }
+
+  function setSelectionInner(doc, sel) {
+    if (sel.equals(doc.sel)) return;
+
+    doc.sel = sel;
+
+    if (doc.cm) {
+      doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
+      signalCursorActivity(doc.cm);
+    }
+    signalLater(doc, "cursorActivity", doc);
+  }
+
+  // Verify that the selection does not partially select any atomic
+  // marked ranges.
+  function reCheckSelection(doc) {
+    setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
+  }
+
+  // Return a selection that does not partially select any atomic
+  // ranges.
+  function skipA

<TRUNCATED>

[03/27] brooklyn-ui git commit: composer is aware whether it is catalog or blueprint mode

Posted by he...@apache.org.
composer is aware whether it is catalog or blueprint mode


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/61201998
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/61201998
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/61201998

Branch: refs/heads/master
Commit: 61201998b3b8177d62461e433052c94208adbcac
Parents: 0554b07
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 14:09:18 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/js/view/editor.js    | 24 +++++++++++++++++++++++-
 src/main/webapp/assets/tpl/editor/page.html |  9 +++++----
 2 files changed, 28 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/61201998/src/main/webapp/assets/js/view/editor.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/editor.js b/src/main/webapp/assets/js/view/editor.js
index baf534f..fa893fc 100644
--- a/src/main/webapp/assets/js/view/editor.js
+++ b/src/main/webapp/assets/js/view/editor.js
@@ -49,6 +49,10 @@ define([
         '      services:\n'+
         '      - type: <your service here>\n'+
         '      location: <your cloud here>\n';
+        
+    // is the user working on an app blueprint or a catalog item
+    var MODE_APP = "app";
+    var MODE_CATALOG = "catalog";
 
     var EditorView = Backbone.View.extend({
         tagName:"div",
@@ -63,6 +67,14 @@ define([
 
         initialize:function () {
             var vm = this;
+            if (!this.options.type || this.options.type === MODE_APP) {
+                this.setMode(MODE_APP);
+            } else if (this.options.type === MODE_CATALOG) {
+                this.setMode(MODE_CATALOG);
+            } else {
+                console.log("unknown mode '"+this.option.type+"'; using '"+MODE_APP+"'");
+                this.setMode(MODE_APP);
+            }
             this.options.catalog = new CatalogApplication.Collection();
             this.options.catalog.fetch({
                 data: $.param({allVersions: true}),
@@ -71,11 +83,21 @@ define([
                 }
             });
         },
+        setMode: function(mode) {
+            if (this.mode === mode) return;
+            this.mode = mode;
+            this.refresh();
+        },
         render:function (eventName) {
             this.$el.html(_.template(EditorHtml, {}));
             this.loadEditor();
+            this.refresh();
             return this;
         },
+        refresh: function() {
+            $("#button-run", this.$el).html(this.mode==MODE_CATALOG ? "Add to Catalog" : "Deploy");
+            $("#button-delete", this.$el).html("Clear");
+        },
         refreshEditor: function() {
             var cm = this.editor;
             if (typeof(cm) !== "undefined") {
@@ -138,7 +160,7 @@ define([
         },
         runBlueprint: function() {
             if (this.validate()){
-                if(this.editor.getValue().slice(0,16) === 'brooklyn.catalog'){
+                if (this.mode === MODE_CATALOG) {
                     this.submitCatalog();
                 }else{
                     this.submitApplication();

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/61201998/src/main/webapp/assets/tpl/editor/page.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/editor/page.html b/src/main/webapp/assets/tpl/editor/page.html
index 9a37fe0..727b4d4 100644
--- a/src/main/webapp/assets/tpl/editor/page.html
+++ b/src/main/webapp/assets/tpl/editor/page.html
@@ -20,10 +20,11 @@ under the License.
     <div class="row row-fluid">
         <div class="span12 composer" id="composer">
             <div class="navbar_top">
-                <h3>YAML Composer</h3>
-                <div class="apps-tree-toolbar">
-                    <button id="button-run" class="btn btn-success btn-sm">Create</button>
-                    <button id="button-delete" class="btn btn-danger btn-sm">Reset</button>
+                <h3 style="margin-top: 6px;">Blueprint Composer</h3>
+                <div class="apps-tree-toolbar" style="margin-top: -24px !important;">
+                    <!-- will be renamed -->
+                    <button id="button-run" class="btn btn-success btn-sm">Run</button>
+                    <button id="button-delete" class="btn btn-danger btn-sm">Clear</button>
                 </div>
             </div>
             <div class="navbar_main_wrapper">


[04/27] brooklyn-ui git commit: can go from catalog item to open in composer

Posted by he...@apache.org.
can go from catalog item to open in composer


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/0554b079
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/0554b079
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/0554b079

Branch: refs/heads/master
Commit: 0554b0796f9886d99f50a98ef8246d8e5c8a3e55
Parents: f49de1c
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 03:05:41 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 17:44:11 2016 +0000

----------------------------------------------------------------------
 src/main/webapp/assets/js/view/catalog.js              | 6 ++++++
 src/main/webapp/assets/tpl/catalog/details-entity.html | 1 +
 2 files changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0554b079/src/main/webapp/assets/js/view/catalog.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/catalog.js b/src/main/webapp/assets/js/view/catalog.js
index eb9effd..5c3e2ce 100644
--- a/src/main/webapp/assets/js/view/catalog.js
+++ b/src/main/webapp/assets/js/view/catalog.js
@@ -43,6 +43,7 @@ define([
     var CatalogItemDetailsView = Backbone.View.extend({
 
         events: {
+            "click .composer": "composeItem",
             "click .delete": "deleteItem"
         },
 
@@ -109,6 +110,11 @@ define([
             return this;
         },
 
+        composeItem: function(event) {
+            // TODO could make this a catalog item
+            Backbone.history.navigate("/v1/editor/app/"+ encodeURIComponent($(event.currentTarget).data("name")),
+                {trigger: true});
+        },
         deleteItem: function(event) {
             // Could use wait flag to block removal of model from collection
             // until server confirms deletion and success handler to perform

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/0554b079/src/main/webapp/assets/tpl/catalog/details-entity.html
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/tpl/catalog/details-entity.html b/src/main/webapp/assets/tpl/catalog/details-entity.html
index 2e43fe5..02f3fe9 100644
--- a/src/main/webapp/assets/tpl/catalog/details-entity.html
+++ b/src/main/webapp/assets/tpl/catalog/details-entity.html
@@ -20,6 +20,7 @@ under the License.
 <div class="catalog-details">
 
     <div class="float-right">
+        <button data-name="<%= model.id %>" class="btn composer">Open in Composer</button>
         <button data-name="<%= model.id %>" class="btn btn-danger delete">Delete</button>
     </div>
 


[18/27] brooklyn-ui git commit: add font awesome

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.ttf
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.ttf b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.ttf
new file mode 100644
index 0000000..26dea79
Binary files /dev/null and b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.ttf differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.woff
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.woff b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.woff
new file mode 100644
index 0000000..dc35ce3
Binary files /dev/null and b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.woff differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.woff2
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.woff2 b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.woff2
new file mode 100644
index 0000000..500e517
Binary files /dev/null and b/src/main/webapp/assets/js/libs/font-awesome/fonts/fontawesome-webfont.woff2 differ

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/animated.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/animated.less b/src/main/webapp/assets/js/libs/font-awesome/less/animated.less
new file mode 100644
index 0000000..66ad52a
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/animated.less
@@ -0,0 +1,34 @@
+// Animated Icons
+// --------------------------
+
+.@{fa-css-prefix}-spin {
+  -webkit-animation: fa-spin 2s infinite linear;
+          animation: fa-spin 2s infinite linear;
+}
+
+.@{fa-css-prefix}-pulse {
+  -webkit-animation: fa-spin 1s infinite steps(8);
+          animation: fa-spin 1s infinite steps(8);
+}
+
+@-webkit-keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+            transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+            transform: rotate(359deg);
+  }
+}
+
+@keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+            transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+            transform: rotate(359deg);
+  }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/bordered-pulled.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/bordered-pulled.less b/src/main/webapp/assets/js/libs/font-awesome/less/bordered-pulled.less
new file mode 100644
index 0000000..f1c8ad7
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/bordered-pulled.less
@@ -0,0 +1,25 @@
+// Bordered & Pulled
+// -------------------------
+
+.@{fa-css-prefix}-border {
+  padding: .2em .25em .15em;
+  border: solid .08em @fa-border-color;
+  border-radius: .1em;
+}
+
+.@{fa-css-prefix}-pull-left { float: left; }
+.@{fa-css-prefix}-pull-right { float: right; }
+
+.@{fa-css-prefix} {
+  &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
+  &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
+}
+
+/* Deprecated as of 4.4.0 */
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.@{fa-css-prefix} {
+  &.pull-left { margin-right: .3em; }
+  &.pull-right { margin-left: .3em; }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/core.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/core.less b/src/main/webapp/assets/js/libs/font-awesome/less/core.less
new file mode 100644
index 0000000..c577ac8
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/core.less
@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.@{fa-css-prefix} {
+  display: inline-block;
+  font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
+  font-size: inherit; // can't have font-size inherit on line above, so need to override
+  text-rendering: auto; // optimizelegibility throws things off #1094
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/fixed-width.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/fixed-width.less b/src/main/webapp/assets/js/libs/font-awesome/less/fixed-width.less
new file mode 100644
index 0000000..110289f
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/fixed-width.less
@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.@{fa-css-prefix}-fw {
+  width: (18em / 14);
+  text-align: center;
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/font-awesome.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/font-awesome.less b/src/main/webapp/assets/js/libs/font-awesome/less/font-awesome.less
new file mode 100644
index 0000000..c35d3ee
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/font-awesome.less
@@ -0,0 +1,17 @@
+/*!
+ *  Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables.less";
+@import "mixins.less";
+@import "path.less";
+@import "core.less";
+@import "larger.less";
+@import "fixed-width.less";
+@import "list.less";
+@import "bordered-pulled.less";
+@import "animated.less";
+@import "rotated-flipped.less";
+@import "stacked.less";
+@import "icons.less";

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/icons.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/icons.less b/src/main/webapp/assets/js/libs/font-awesome/less/icons.less
new file mode 100644
index 0000000..ca60abd
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/icons.less
@@ -0,0 +1,697 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+   readers do not read off random characters that represent icons */
+
+.@{fa-css-prefix}-glass:before { content: @fa-var-glass; }
+.@{fa-css-prefix}-music:before { content: @fa-var-music; }
+.@{fa-css-prefix}-search:before { content: @fa-var-search; }
+.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; }
+.@{fa-css-prefix}-heart:before { content: @fa-var-heart; }
+.@{fa-css-prefix}-star:before { content: @fa-var-star; }
+.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; }
+.@{fa-css-prefix}-user:before { content: @fa-var-user; }
+.@{fa-css-prefix}-film:before { content: @fa-var-film; }
+.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; }
+.@{fa-css-prefix}-th:before { content: @fa-var-th; }
+.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }
+.@{fa-css-prefix}-check:before { content: @fa-var-check; }
+.@{fa-css-prefix}-remove:before,
+.@{fa-css-prefix}-close:before,
+.@{fa-css-prefix}-times:before { content: @fa-var-times; }
+.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }
+.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }
+.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; }
+.@{fa-css-prefix}-signal:before { content: @fa-var-signal; }
+.@{fa-css-prefix}-gear:before,
+.@{fa-css-prefix}-cog:before { content: @fa-var-cog; }
+.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; }
+.@{fa-css-prefix}-home:before { content: @fa-var-home; }
+.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; }
+.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; }
+.@{fa-css-prefix}-road:before { content: @fa-var-road; }
+.@{fa-css-prefix}-download:before { content: @fa-var-download; }
+.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; }
+.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; }
+.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; }
+.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; }
+.@{fa-css-prefix}-rotate-right:before,
+.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; }
+.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; }
+.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }
+.@{fa-css-prefix}-lock:before { content: @fa-var-lock; }
+.@{fa-css-prefix}-flag:before { content: @fa-var-flag; }
+.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; }
+.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; }
+.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; }
+.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; }
+.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; }
+.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; }
+.@{fa-css-prefix}-tag:before { content: @fa-var-tag; }
+.@{fa-css-prefix}-tags:before { content: @fa-var-tags; }
+.@{fa-css-prefix}-book:before { content: @fa-var-book; }
+.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; }
+.@{fa-css-prefix}-print:before { content: @fa-var-print; }
+.@{fa-css-prefix}-camera:before { content: @fa-var-camera; }
+.@{fa-css-prefix}-font:before { content: @fa-var-font; }
+.@{fa-css-prefix}-bold:before { content: @fa-var-bold; }
+.@{fa-css-prefix}-italic:before { content: @fa-var-italic; }
+.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; }
+.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; }
+.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }
+.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; }
+.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; }
+.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; }
+.@{fa-css-prefix}-list:before { content: @fa-var-list; }
+.@{fa-css-prefix}-dedent:before,
+.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; }
+.@{fa-css-prefix}-indent:before { content: @fa-var-indent; }
+.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; }
+.@{fa-css-prefix}-photo:before,
+.@{fa-css-prefix}-image:before,
+.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; }
+.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; }
+.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; }
+.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; }
+.@{fa-css-prefix}-tint:before { content: @fa-var-tint; }
+.@{fa-css-prefix}-edit:before,
+.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; }
+.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; }
+.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; }
+.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; }
+.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; }
+.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; }
+.@{fa-css-prefix}-backward:before { content: @fa-var-backward; }
+.@{fa-css-prefix}-play:before { content: @fa-var-play; }
+.@{fa-css-prefix}-pause:before { content: @fa-var-pause; }
+.@{fa-css-prefix}-stop:before { content: @fa-var-stop; }
+.@{fa-css-prefix}-forward:before { content: @fa-var-forward; }
+.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; }
+.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; }
+.@{fa-css-prefix}-eject:before { content: @fa-var-eject; }
+.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; }
+.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; }
+.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; }
+.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; }
+.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }
+.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }
+.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }
+.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }
+.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; }
+.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; }
+.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; }
+.@{fa-css-prefix}-ban:before { content: @fa-var-ban; }
+.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; }
+.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; }
+.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; }
+.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; }
+.@{fa-css-prefix}-mail-forward:before,
+.@{fa-css-prefix}-share:before { content: @fa-var-share; }
+.@{fa-css-prefix}-expand:before { content: @fa-var-expand; }
+.@{fa-css-prefix}-compress:before { content: @fa-var-compress; }
+.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }
+.@{fa-css-prefix}-minus:before { content: @fa-var-minus; }
+.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; }
+.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; }
+.@{fa-css-prefix}-gift:before { content: @fa-var-gift; }
+.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; }
+.@{fa-css-prefix}-fire:before { content: @fa-var-fire; }
+.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }
+.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; }
+.@{fa-css-prefix}-warning:before,
+.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; }
+.@{fa-css-prefix}-plane:before { content: @fa-var-plane; }
+.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; }
+.@{fa-css-prefix}-random:before { content: @fa-var-random; }
+.@{fa-css-prefix}-comment:before { content: @fa-var-comment; }
+.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; }
+.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; }
+.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; }
+.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; }
+.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; }
+.@{fa-css-prefix}-folder:before { content: @fa-var-folder; }
+.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }
+.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }
+.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }
+.@{fa-css-prefix}-bar-chart-o:before,
+.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; }
+.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }
+.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }
+.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }
+.@{fa-css-prefix}-key:before { content: @fa-var-key; }
+.@{fa-css-prefix}-gears:before,
+.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }
+.@{fa-css-prefix}-comments:before { content: @fa-var-comments; }
+.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; }
+.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; }
+.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; }
+.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; }
+.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }
+.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; }
+.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; }
+.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; }
+.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; }
+.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; }
+.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; }
+.@{fa-css-prefix}-upload:before { content: @fa-var-upload; }
+.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; }
+.@{fa-css-prefix}-phone:before { content: @fa-var-phone; }
+.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }
+.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }
+.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }
+.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }
+.@{fa-css-prefix}-facebook-f:before,
+.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }
+.@{fa-css-prefix}-github:before { content: @fa-var-github; }
+.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }
+.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }
+.@{fa-css-prefix}-feed:before,
+.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }
+.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }
+.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }
+.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }
+.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; }
+.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; }
+.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; }
+.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; }
+.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; }
+.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; }
+.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; }
+.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; }
+.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; }
+.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }
+.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; }
+.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }
+.@{fa-css-prefix}-filter:before { content: @fa-var-filter; }
+.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; }
+.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; }
+.@{fa-css-prefix}-group:before,
+.@{fa-css-prefix}-users:before { content: @fa-var-users; }
+.@{fa-css-prefix}-chain:before,
+.@{fa-css-prefix}-link:before { content: @fa-var-link; }
+.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }
+.@{fa-css-prefix}-flask:before { content: @fa-var-flask; }
+.@{fa-css-prefix}-cut:before,
+.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; }
+.@{fa-css-prefix}-copy:before,
+.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; }
+.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; }
+.@{fa-css-prefix}-save:before,
+.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; }
+.@{fa-css-prefix}-square:before { content: @fa-var-square; }
+.@{fa-css-prefix}-navicon:before,
+.@{fa-css-prefix}-reorder:before,
+.@{fa-css-prefix}-bars:before { content: @fa-var-bars; }
+.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }
+.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; }
+.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; }
+.@{fa-css-prefix}-underline:before { content: @fa-var-underline; }
+.@{fa-css-prefix}-table:before { content: @fa-var-table; }
+.@{fa-css-prefix}-magic:before { content: @fa-var-magic; }
+.@{fa-css-prefix}-truck:before { content: @fa-var-truck; }
+.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; }
+.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; }
+.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; }
+.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; }
+.@{fa-css-prefix}-money:before { content: @fa-var-money; }
+.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; }
+.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; }
+.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; }
+.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; }
+.@{fa-css-prefix}-columns:before { content: @fa-var-columns; }
+.@{fa-css-prefix}-unsorted:before,
+.@{fa-css-prefix}-sort:before { content: @fa-var-sort; }
+.@{fa-css-prefix}-sort-down:before,
+.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; }
+.@{fa-css-prefix}-sort-up:before,
+.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; }
+.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }
+.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; }
+.@{fa-css-prefix}-rotate-left:before,
+.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }
+.@{fa-css-prefix}-legal:before,
+.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; }
+.@{fa-css-prefix}-dashboard:before,
+.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; }
+.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; }
+.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; }
+.@{fa-css-prefix}-flash:before,
+.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; }
+.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; }
+.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; }
+.@{fa-css-prefix}-paste:before,
+.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; }
+.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; }
+.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; }
+.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; }
+.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; }
+.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; }
+.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; }
+.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; }
+.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; }
+.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; }
+.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; }
+.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; }
+.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; }
+.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; }
+.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; }
+.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; }
+.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; }
+.@{fa-css-prefix}-beer:before { content: @fa-var-beer; }
+.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; }
+.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; }
+.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; }
+.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; }
+.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; }
+.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; }
+.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; }
+.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; }
+.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; }
+.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; }
+.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }
+.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }
+.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; }
+.@{fa-css-prefix}-mobile-phone:before,
+.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; }
+.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; }
+.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }
+.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; }
+.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; }
+.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }
+.@{fa-css-prefix}-mail-reply:before,
+.@{fa-css-prefix}-reply:before { content: @fa-var-reply; }
+.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; }
+.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; }
+.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; }
+.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; }
+.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; }
+.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; }
+.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; }
+.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; }
+.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; }
+.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; }
+.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; }
+.@{fa-css-prefix}-code:before { content: @fa-var-code; }
+.@{fa-css-prefix}-mail-reply-all:before,
+.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; }
+.@{fa-css-prefix}-star-half-empty:before,
+.@{fa-css-prefix}-star-half-full:before,
+.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; }
+.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; }
+.@{fa-css-prefix}-crop:before { content: @fa-var-crop; }
+.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; }
+.@{fa-css-prefix}-unlink:before,
+.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; }
+.@{fa-css-prefix}-question:before { content: @fa-var-question; }
+.@{fa-css-prefix}-info:before { content: @fa-var-info; }
+.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; }
+.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; }
+.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; }
+.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; }
+.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; }
+.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; }
+.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; }
+.@{fa-css-prefix}-shield:before { content: @fa-var-shield; }
+.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; }
+.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; }
+.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }
+.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; }
+.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; }
+.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; }
+.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; }
+.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; }
+.@{fa-css-prefix}-html5:before { content: @fa-var-html5; }
+.@{fa-css-prefix}-css3:before { content: @fa-var-css3; }
+.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; }
+.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; }
+.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; }
+.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; }
+.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; }
+.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; }
+.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; }
+.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; }
+.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; }
+.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; }
+.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; }
+.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; }
+.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; }
+.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; }
+.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; }
+.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; }
+.@{fa-css-prefix}-compass:before { content: @fa-var-compass; }
+.@{fa-css-prefix}-toggle-down:before,
+.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; }
+.@{fa-css-prefix}-toggle-up:before,
+.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; }
+.@{fa-css-prefix}-toggle-right:before,
+.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; }
+.@{fa-css-prefix}-euro:before,
+.@{fa-css-prefix}-eur:before { content: @fa-var-eur; }
+.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; }
+.@{fa-css-prefix}-dollar:before,
+.@{fa-css-prefix}-usd:before { content: @fa-var-usd; }
+.@{fa-css-prefix}-rupee:before,
+.@{fa-css-prefix}-inr:before { content: @fa-var-inr; }
+.@{fa-css-prefix}-cny:before,
+.@{fa-css-prefix}-rmb:before,
+.@{fa-css-prefix}-yen:before,
+.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; }
+.@{fa-css-prefix}-ruble:before,
+.@{fa-css-prefix}-rouble:before,
+.@{fa-css-prefix}-rub:before { content: @fa-var-rub; }
+.@{fa-css-prefix}-won:before,
+.@{fa-css-prefix}-krw:before { content: @fa-var-krw; }
+.@{fa-css-prefix}-bitcoin:before,
+.@{fa-css-prefix}-btc:before { content: @fa-var-btc; }
+.@{fa-css-prefix}-file:before { content: @fa-var-file; }
+.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; }
+.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; }
+.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; }
+.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; }
+.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; }
+.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; }
+.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; }
+.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; }
+.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; }
+.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; }
+.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; }
+.@{fa-css-prefix}-xing:before { content: @fa-var-xing; }
+.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; }
+.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; }
+.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; }
+.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; }
+.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }
+.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; }
+.@{fa-css-prefix}-adn:before { content: @fa-var-adn; }
+.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; }
+.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; }
+.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; }
+.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; }
+.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; }
+.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; }
+.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; }
+.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; }
+.@{fa-css-prefix}-apple:before { content: @fa-var-apple; }
+.@{fa-css-prefix}-windows:before { content: @fa-var-windows; }
+.@{fa-css-prefix}-android:before { content: @fa-var-android; }
+.@{fa-css-prefix}-linux:before { content: @fa-var-linux; }
+.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; }
+.@{fa-css-prefix}-skype:before { content: @fa-var-skype; }
+.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; }
+.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }
+.@{fa-css-prefix}-female:before { content: @fa-var-female; }
+.@{fa-css-prefix}-male:before { content: @fa-var-male; }
+.@{fa-css-prefix}-gittip:before,
+.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; }
+.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }
+.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }
+.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }
+.@{fa-css-prefix}-bug:before { content: @fa-var-bug; }
+.@{fa-css-prefix}-vk:before { content: @fa-var-vk; }
+.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; }
+.@{fa-css-prefix}-renren:before { content: @fa-var-renren; }
+.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; }
+.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; }
+.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; }
+.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; }
+.@{fa-css-prefix}-toggle-left:before,
+.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; }
+.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; }
+.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; }
+.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; }
+.@{fa-css-prefix}-turkish-lira:before,
+.@{fa-css-prefix}-try:before { content: @fa-var-try; }
+.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; }
+.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; }
+.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }
+.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; }
+.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; }
+.@{fa-css-prefix}-openid:before { content: @fa-var-openid; }
+.@{fa-css-prefix}-institution:before,
+.@{fa-css-prefix}-bank:before,
+.@{fa-css-prefix}-university:before { content: @fa-var-university; }
+.@{fa-css-prefix}-mortar-board:before,
+.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }
+.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; }
+.@{fa-css-prefix}-google:before { content: @fa-var-google; }
+.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; }
+.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; }
+.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; }
+.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }
+.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }
+.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }
+.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }
+.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }
+.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }
+.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; }
+.@{fa-css-prefix}-language:before { content: @fa-var-language; }
+.@{fa-css-prefix}-fax:before { content: @fa-var-fax; }
+.@{fa-css-prefix}-building:before { content: @fa-var-building; }
+.@{fa-css-prefix}-child:before { content: @fa-var-child; }
+.@{fa-css-prefix}-paw:before { content: @fa-var-paw; }
+.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; }
+.@{fa-css-prefix}-cube:before { content: @fa-var-cube; }
+.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; }
+.@{fa-css-prefix}-behance:before { content: @fa-var-behance; }
+.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; }
+.@{fa-css-prefix}-steam:before { content: @fa-var-steam; }
+.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; }
+.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; }
+.@{fa-css-prefix}-automobile:before,
+.@{fa-css-prefix}-car:before { content: @fa-var-car; }
+.@{fa-css-prefix}-cab:before,
+.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; }
+.@{fa-css-prefix}-tree:before { content: @fa-var-tree; }
+.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; }
+.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; }
+.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; }
+.@{fa-css-prefix}-database:before { content: @fa-var-database; }
+.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; }
+.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; }
+.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; }
+.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; }
+.@{fa-css-prefix}-file-photo-o:before,
+.@{fa-css-prefix}-file-picture-o:before,
+.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; }
+.@{fa-css-prefix}-file-zip-o:before,
+.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; }
+.@{fa-css-prefix}-file-sound-o:before,
+.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; }
+.@{fa-css-prefix}-file-movie-o:before,
+.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; }
+.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; }
+.@{fa-css-prefix}-vine:before { content: @fa-var-vine; }
+.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }
+.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }
+.@{fa-css-prefix}-life-bouy:before,
+.@{fa-css-prefix}-life-buoy:before,
+.@{fa-css-prefix}-life-saver:before,
+.@{fa-css-prefix}-support:before,
+.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }
+.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; }
+.@{fa-css-prefix}-ra:before,
+.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; }
+.@{fa-css-prefix}-ge:before,
+.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }
+.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }
+.@{fa-css-prefix}-git:before { content: @fa-var-git; }
+.@{fa-css-prefix}-y-combinator-square:before,
+.@{fa-css-prefix}-yc-square:before,
+.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }
+.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }
+.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }
+.@{fa-css-prefix}-wechat:before,
+.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; }
+.@{fa-css-prefix}-send:before,
+.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; }
+.@{fa-css-prefix}-send-o:before,
+.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; }
+.@{fa-css-prefix}-history:before { content: @fa-var-history; }
+.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; }
+.@{fa-css-prefix}-header:before { content: @fa-var-header; }
+.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; }
+.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; }
+.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }
+.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }
+.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }
+.@{fa-css-prefix}-soccer-ball-o:before,
+.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; }
+.@{fa-css-prefix}-tty:before { content: @fa-var-tty; }
+.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; }
+.@{fa-css-prefix}-plug:before { content: @fa-var-plug; }
+.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; }
+.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; }
+.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; }
+.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; }
+.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; }
+.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; }
+.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; }
+.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; }
+.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }
+.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }
+.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }
+.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }
+.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }
+.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }
+.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; }
+.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; }
+.@{fa-css-prefix}-trash:before { content: @fa-var-trash; }
+.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; }
+.@{fa-css-prefix}-at:before { content: @fa-var-at; }
+.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; }
+.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; }
+.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; }
+.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; }
+.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; }
+.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; }
+.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; }
+.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; }
+.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; }
+.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; }
+.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; }
+.@{fa-css-prefix}-bus:before { content: @fa-var-bus; }
+.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; }
+.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; }
+.@{fa-css-prefix}-cc:before { content: @fa-var-cc; }
+.@{fa-css-prefix}-shekel:before,
+.@{fa-css-prefix}-sheqel:before,
+.@{fa-css-prefix}-ils:before { content: @fa-var-ils; }
+.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; }
+.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; }
+.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; }
+.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; }
+.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; }
+.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; }
+.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; }
+.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; }
+.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; }
+.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; }
+.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; }
+.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; }
+.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; }
+.@{fa-css-prefix}-ship:before { content: @fa-var-ship; }
+.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; }
+.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; }
+.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; }
+.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; }
+.@{fa-css-prefix}-venus:before { content: @fa-var-venus; }
+.@{fa-css-prefix}-mars:before { content: @fa-var-mars; }
+.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; }
+.@{fa-css-prefix}-intersex:before,
+.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; }
+.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; }
+.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; }
+.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; }
+.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; }
+.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; }
+.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; }
+.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; }
+.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; }
+.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; }
+.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; }
+.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; }
+.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; }
+.@{fa-css-prefix}-server:before { content: @fa-var-server; }
+.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; }
+.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; }
+.@{fa-css-prefix}-hotel:before,
+.@{fa-css-prefix}-bed:before { content: @fa-var-bed; }
+.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; }
+.@{fa-css-prefix}-train:before { content: @fa-var-train; }
+.@{fa-css-prefix}-subway:before { content: @fa-var-subway; }
+.@{fa-css-prefix}-medium:before { content: @fa-var-medium; }
+.@{fa-css-prefix}-yc:before,
+.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; }
+.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; }
+.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; }
+.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; }
+.@{fa-css-prefix}-battery-4:before,
+.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; }
+.@{fa-css-prefix}-battery-3:before,
+.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; }
+.@{fa-css-prefix}-battery-2:before,
+.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; }
+.@{fa-css-prefix}-battery-1:before,
+.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; }
+.@{fa-css-prefix}-battery-0:before,
+.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; }
+.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; }
+.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; }
+.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; }
+.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; }
+.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; }
+.@{fa-css-prefix}-sticky-note-o:before { content: @fa-var-sticky-note-o; }
+.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }
+.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }
+.@{fa-css-prefix}-clone:before { content: @fa-var-clone; }
+.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; }
+.@{fa-css-prefix}-hourglass-o:before { content: @fa-var-hourglass-o; }
+.@{fa-css-prefix}-hourglass-1:before,
+.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; }
+.@{fa-css-prefix}-hourglass-2:before,
+.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; }
+.@{fa-css-prefix}-hourglass-3:before,
+.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; }
+.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; }
+.@{fa-css-prefix}-hand-grab-o:before,
+.@{fa-css-prefix}-hand-rock-o:before { content: @fa-var-hand-rock-o; }
+.@{fa-css-prefix}-hand-stop-o:before,
+.@{fa-css-prefix}-hand-paper-o:before { content: @fa-var-hand-paper-o; }
+.@{fa-css-prefix}-hand-scissors-o:before { content: @fa-var-hand-scissors-o; }
+.@{fa-css-prefix}-hand-lizard-o:before { content: @fa-var-hand-lizard-o; }
+.@{fa-css-prefix}-hand-spock-o:before { content: @fa-var-hand-spock-o; }
+.@{fa-css-prefix}-hand-pointer-o:before { content: @fa-var-hand-pointer-o; }
+.@{fa-css-prefix}-hand-peace-o:before { content: @fa-var-hand-peace-o; }
+.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; }
+.@{fa-css-prefix}-registered:before { content: @fa-var-registered; }
+.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; }
+.@{fa-css-prefix}-gg:before { content: @fa-var-gg; }
+.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; }
+.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; }
+.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; }
+.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; }
+.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; }
+.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; }
+.@{fa-css-prefix}-safari:before { content: @fa-var-safari; }
+.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; }
+.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; }
+.@{fa-css-prefix}-opera:before { content: @fa-var-opera; }
+.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; }
+.@{fa-css-prefix}-tv:before,
+.@{fa-css-prefix}-television:before { content: @fa-var-television; }
+.@{fa-css-prefix}-contao:before { content: @fa-var-contao; }
+.@{fa-css-prefix}-500px:before { content: @fa-var-500px; }
+.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; }
+.@{fa-css-prefix}-calendar-plus-o:before { content: @fa-var-calendar-plus-o; }
+.@{fa-css-prefix}-calendar-minus-o:before { content: @fa-var-calendar-minus-o; }
+.@{fa-css-prefix}-calendar-times-o:before { content: @fa-var-calendar-times-o; }
+.@{fa-css-prefix}-calendar-check-o:before { content: @fa-var-calendar-check-o; }
+.@{fa-css-prefix}-industry:before { content: @fa-var-industry; }
+.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; }
+.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; }
+.@{fa-css-prefix}-map-o:before { content: @fa-var-map-o; }
+.@{fa-css-prefix}-map:before { content: @fa-var-map; }
+.@{fa-css-prefix}-commenting:before { content: @fa-var-commenting; }
+.@{fa-css-prefix}-commenting-o:before { content: @fa-var-commenting-o; }
+.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; }
+.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; }
+.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; }
+.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; }
+.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; }
+.@{fa-css-prefix}-edge:before { content: @fa-var-edge; }
+.@{fa-css-prefix}-credit-card-alt:before { content: @fa-var-credit-card-alt; }
+.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; }
+.@{fa-css-prefix}-modx:before { content: @fa-var-modx; }
+.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; }
+.@{fa-css-prefix}-usb:before { content: @fa-var-usb; }
+.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; }
+.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; }
+.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; }
+.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; }
+.@{fa-css-prefix}-pause-circle-o:before { content: @fa-var-pause-circle-o; }
+.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; }
+.@{fa-css-prefix}-stop-circle-o:before { content: @fa-var-stop-circle-o; }
+.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; }
+.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; }
+.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; }
+.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; }
+.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; }
+.@{fa-css-prefix}-percent:before { content: @fa-var-percent; }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/larger.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/larger.less b/src/main/webapp/assets/js/libs/font-awesome/less/larger.less
new file mode 100644
index 0000000..c9d6467
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/larger.less
@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.@{fa-css-prefix}-lg {
+  font-size: (4em / 3);
+  line-height: (3em / 4);
+  vertical-align: -15%;
+}
+.@{fa-css-prefix}-2x { font-size: 2em; }
+.@{fa-css-prefix}-3x { font-size: 3em; }
+.@{fa-css-prefix}-4x { font-size: 4em; }
+.@{fa-css-prefix}-5x { font-size: 5em; }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/list.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/list.less b/src/main/webapp/assets/js/libs/font-awesome/less/list.less
new file mode 100644
index 0000000..0b44038
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/list.less
@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.@{fa-css-prefix}-ul {
+  padding-left: 0;
+  margin-left: @fa-li-width;
+  list-style-type: none;
+  > li { position: relative; }
+}
+.@{fa-css-prefix}-li {
+  position: absolute;
+  left: -@fa-li-width;
+  width: @fa-li-width;
+  top: (2em / 14);
+  text-align: center;
+  &.@{fa-css-prefix}-lg {
+    left: (-@fa-li-width + (4em / 14));
+  }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/mixins.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/mixins.less b/src/main/webapp/assets/js/libs/font-awesome/less/mixins.less
new file mode 100644
index 0000000..d5a43a1
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/mixins.less
@@ -0,0 +1,26 @@
+// Mixins
+// --------------------------
+
+.fa-icon() {
+  display: inline-block;
+  font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
+  font-size: inherit; // can't have font-size inherit on line above, so need to override
+  text-rendering: auto; // optimizelegibility throws things off #1094
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+}
+
+.fa-icon-rotate(@degrees, @rotation) {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation);
+  -webkit-transform: rotate(@degrees);
+      -ms-transform: rotate(@degrees);
+          transform: rotate(@degrees);
+}
+
+.fa-icon-flip(@horiz, @vert, @rotation) {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1);
+  -webkit-transform: scale(@horiz, @vert);
+      -ms-transform: scale(@horiz, @vert);
+          transform: scale(@horiz, @vert);
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/path.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/path.less b/src/main/webapp/assets/js/libs/font-awesome/less/path.less
new file mode 100644
index 0000000..9211e66
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/path.less
@@ -0,0 +1,15 @@
+/* FONT PATH
+ * -------------------------- */
+
+@font-face {
+  font-family: 'FontAwesome';
+  src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
+  src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
+    url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
+    url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
+    url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
+    url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
+//  src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
+  font-weight: normal;
+  font-style: normal;
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/rotated-flipped.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/rotated-flipped.less b/src/main/webapp/assets/js/libs/font-awesome/less/rotated-flipped.less
new file mode 100644
index 0000000..f6ba814
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/rotated-flipped.less
@@ -0,0 +1,20 @@
+// Rotated & Flipped Icons
+// -------------------------
+
+.@{fa-css-prefix}-rotate-90  { .fa-icon-rotate(90deg, 1);  }
+.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
+.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
+
+.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
+.@{fa-css-prefix}-flip-vertical   { .fa-icon-flip(1, -1, 2); }
+
+// Hook for IE8-9
+// -------------------------
+
+:root .@{fa-css-prefix}-rotate-90,
+:root .@{fa-css-prefix}-rotate-180,
+:root .@{fa-css-prefix}-rotate-270,
+:root .@{fa-css-prefix}-flip-horizontal,
+:root .@{fa-css-prefix}-flip-vertical {
+  filter: none;
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/stacked.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/stacked.less b/src/main/webapp/assets/js/libs/font-awesome/less/stacked.less
new file mode 100644
index 0000000..fc53fb0
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/stacked.less
@@ -0,0 +1,20 @@
+// Stacked Icons
+// -------------------------
+
+.@{fa-css-prefix}-stack {
+  position: relative;
+  display: inline-block;
+  width: 2em;
+  height: 2em;
+  line-height: 2em;
+  vertical-align: middle;
+}
+.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
+  position: absolute;
+  left: 0;
+  width: 100%;
+  text-align: center;
+}
+.@{fa-css-prefix}-stack-1x { line-height: inherit; }
+.@{fa-css-prefix}-stack-2x { font-size: 2em; }
+.@{fa-css-prefix}-inverse { color: @fa-inverse; }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/less/variables.less
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/less/variables.less b/src/main/webapp/assets/js/libs/font-awesome/less/variables.less
new file mode 100644
index 0000000..37c4b80
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/less/variables.less
@@ -0,0 +1,708 @@
+// Variables
+// --------------------------
+
+@fa-font-path:        "../fonts";
+@fa-font-size-base:   14px;
+@fa-line-height-base: 1;
+//@fa-font-path:        "//netdna.bootstrapcdn.com/font-awesome/4.5.0/fonts"; // for referencing Bootstrap CDN font files directly
+@fa-css-prefix:       fa;
+@fa-version:          "4.5.0";
+@fa-border-color:     #eee;
+@fa-inverse:          #fff;
+@fa-li-width:         (30em / 14);
+
+@fa-var-500px: "\f26e";
+@fa-var-adjust: "\f042";
+@fa-var-adn: "\f170";
+@fa-var-align-center: "\f037";
+@fa-var-align-justify: "\f039";
+@fa-var-align-left: "\f036";
+@fa-var-align-right: "\f038";
+@fa-var-amazon: "\f270";
+@fa-var-ambulance: "\f0f9";
+@fa-var-anchor: "\f13d";
+@fa-var-android: "\f17b";
+@fa-var-angellist: "\f209";
+@fa-var-angle-double-down: "\f103";
+@fa-var-angle-double-left: "\f100";
+@fa-var-angle-double-right: "\f101";
+@fa-var-angle-double-up: "\f102";
+@fa-var-angle-down: "\f107";
+@fa-var-angle-left: "\f104";
+@fa-var-angle-right: "\f105";
+@fa-var-angle-up: "\f106";
+@fa-var-apple: "\f179";
+@fa-var-archive: "\f187";
+@fa-var-area-chart: "\f1fe";
+@fa-var-arrow-circle-down: "\f0ab";
+@fa-var-arrow-circle-left: "\f0a8";
+@fa-var-arrow-circle-o-down: "\f01a";
+@fa-var-arrow-circle-o-left: "\f190";
+@fa-var-arrow-circle-o-right: "\f18e";
+@fa-var-arrow-circle-o-up: "\f01b";
+@fa-var-arrow-circle-right: "\f0a9";
+@fa-var-arrow-circle-up: "\f0aa";
+@fa-var-arrow-down: "\f063";
+@fa-var-arrow-left: "\f060";
+@fa-var-arrow-right: "\f061";
+@fa-var-arrow-up: "\f062";
+@fa-var-arrows: "\f047";
+@fa-var-arrows-alt: "\f0b2";
+@fa-var-arrows-h: "\f07e";
+@fa-var-arrows-v: "\f07d";
+@fa-var-asterisk: "\f069";
+@fa-var-at: "\f1fa";
+@fa-var-automobile: "\f1b9";
+@fa-var-backward: "\f04a";
+@fa-var-balance-scale: "\f24e";
+@fa-var-ban: "\f05e";
+@fa-var-bank: "\f19c";
+@fa-var-bar-chart: "\f080";
+@fa-var-bar-chart-o: "\f080";
+@fa-var-barcode: "\f02a";
+@fa-var-bars: "\f0c9";
+@fa-var-battery-0: "\f244";
+@fa-var-battery-1: "\f243";
+@fa-var-battery-2: "\f242";
+@fa-var-battery-3: "\f241";
+@fa-var-battery-4: "\f240";
+@fa-var-battery-empty: "\f244";
+@fa-var-battery-full: "\f240";
+@fa-var-battery-half: "\f242";
+@fa-var-battery-quarter: "\f243";
+@fa-var-battery-three-quarters: "\f241";
+@fa-var-bed: "\f236";
+@fa-var-beer: "\f0fc";
+@fa-var-behance: "\f1b4";
+@fa-var-behance-square: "\f1b5";
+@fa-var-bell: "\f0f3";
+@fa-var-bell-o: "\f0a2";
+@fa-var-bell-slash: "\f1f6";
+@fa-var-bell-slash-o: "\f1f7";
+@fa-var-bicycle: "\f206";
+@fa-var-binoculars: "\f1e5";
+@fa-var-birthday-cake: "\f1fd";
+@fa-var-bitbucket: "\f171";
+@fa-var-bitbucket-square: "\f172";
+@fa-var-bitcoin: "\f15a";
+@fa-var-black-tie: "\f27e";
+@fa-var-bluetooth: "\f293";
+@fa-var-bluetooth-b: "\f294";
+@fa-var-bold: "\f032";
+@fa-var-bolt: "\f0e7";
+@fa-var-bomb: "\f1e2";
+@fa-var-book: "\f02d";
+@fa-var-bookmark: "\f02e";
+@fa-var-bookmark-o: "\f097";
+@fa-var-briefcase: "\f0b1";
+@fa-var-btc: "\f15a";
+@fa-var-bug: "\f188";
+@fa-var-building: "\f1ad";
+@fa-var-building-o: "\f0f7";
+@fa-var-bullhorn: "\f0a1";
+@fa-var-bullseye: "\f140";
+@fa-var-bus: "\f207";
+@fa-var-buysellads: "\f20d";
+@fa-var-cab: "\f1ba";
+@fa-var-calculator: "\f1ec";
+@fa-var-calendar: "\f073";
+@fa-var-calendar-check-o: "\f274";
+@fa-var-calendar-minus-o: "\f272";
+@fa-var-calendar-o: "\f133";
+@fa-var-calendar-plus-o: "\f271";
+@fa-var-calendar-times-o: "\f273";
+@fa-var-camera: "\f030";
+@fa-var-camera-retro: "\f083";
+@fa-var-car: "\f1b9";
+@fa-var-caret-down: "\f0d7";
+@fa-var-caret-left: "\f0d9";
+@fa-var-caret-right: "\f0da";
+@fa-var-caret-square-o-down: "\f150";
+@fa-var-caret-square-o-left: "\f191";
+@fa-var-caret-square-o-right: "\f152";
+@fa-var-caret-square-o-up: "\f151";
+@fa-var-caret-up: "\f0d8";
+@fa-var-cart-arrow-down: "\f218";
+@fa-var-cart-plus: "\f217";
+@fa-var-cc: "\f20a";
+@fa-var-cc-amex: "\f1f3";
+@fa-var-cc-diners-club: "\f24c";
+@fa-var-cc-discover: "\f1f2";
+@fa-var-cc-jcb: "\f24b";
+@fa-var-cc-mastercard: "\f1f1";
+@fa-var-cc-paypal: "\f1f4";
+@fa-var-cc-stripe: "\f1f5";
+@fa-var-cc-visa: "\f1f0";
+@fa-var-certificate: "\f0a3";
+@fa-var-chain: "\f0c1";
+@fa-var-chain-broken: "\f127";
+@fa-var-check: "\f00c";
+@fa-var-check-circle: "\f058";
+@fa-var-check-circle-o: "\f05d";
+@fa-var-check-square: "\f14a";
+@fa-var-check-square-o: "\f046";
+@fa-var-chevron-circle-down: "\f13a";
+@fa-var-chevron-circle-left: "\f137";
+@fa-var-chevron-circle-right: "\f138";
+@fa-var-chevron-circle-up: "\f139";
+@fa-var-chevron-down: "\f078";
+@fa-var-chevron-left: "\f053";
+@fa-var-chevron-right: "\f054";
+@fa-var-chevron-up: "\f077";
+@fa-var-child: "\f1ae";
+@fa-var-chrome: "\f268";
+@fa-var-circle: "\f111";
+@fa-var-circle-o: "\f10c";
+@fa-var-circle-o-notch: "\f1ce";
+@fa-var-circle-thin: "\f1db";
+@fa-var-clipboard: "\f0ea";
+@fa-var-clock-o: "\f017";
+@fa-var-clone: "\f24d";
+@fa-var-close: "\f00d";
+@fa-var-cloud: "\f0c2";
+@fa-var-cloud-download: "\f0ed";
+@fa-var-cloud-upload: "\f0ee";
+@fa-var-cny: "\f157";
+@fa-var-code: "\f121";
+@fa-var-code-fork: "\f126";
+@fa-var-codepen: "\f1cb";
+@fa-var-codiepie: "\f284";
+@fa-var-coffee: "\f0f4";
+@fa-var-cog: "\f013";
+@fa-var-cogs: "\f085";
+@fa-var-columns: "\f0db";
+@fa-var-comment: "\f075";
+@fa-var-comment-o: "\f0e5";
+@fa-var-commenting: "\f27a";
+@fa-var-commenting-o: "\f27b";
+@fa-var-comments: "\f086";
+@fa-var-comments-o: "\f0e6";
+@fa-var-compass: "\f14e";
+@fa-var-compress: "\f066";
+@fa-var-connectdevelop: "\f20e";
+@fa-var-contao: "\f26d";
+@fa-var-copy: "\f0c5";
+@fa-var-copyright: "\f1f9";
+@fa-var-creative-commons: "\f25e";
+@fa-var-credit-card: "\f09d";
+@fa-var-credit-card-alt: "\f283";
+@fa-var-crop: "\f125";
+@fa-var-crosshairs: "\f05b";
+@fa-var-css3: "\f13c";
+@fa-var-cube: "\f1b2";
+@fa-var-cubes: "\f1b3";
+@fa-var-cut: "\f0c4";
+@fa-var-cutlery: "\f0f5";
+@fa-var-dashboard: "\f0e4";
+@fa-var-dashcube: "\f210";
+@fa-var-database: "\f1c0";
+@fa-var-dedent: "\f03b";
+@fa-var-delicious: "\f1a5";
+@fa-var-desktop: "\f108";
+@fa-var-deviantart: "\f1bd";
+@fa-var-diamond: "\f219";
+@fa-var-digg: "\f1a6";
+@fa-var-dollar: "\f155";
+@fa-var-dot-circle-o: "\f192";
+@fa-var-download: "\f019";
+@fa-var-dribbble: "\f17d";
+@fa-var-dropbox: "\f16b";
+@fa-var-drupal: "\f1a9";
+@fa-var-edge: "\f282";
+@fa-var-edit: "\f044";
+@fa-var-eject: "\f052";
+@fa-var-ellipsis-h: "\f141";
+@fa-var-ellipsis-v: "\f142";
+@fa-var-empire: "\f1d1";
+@fa-var-envelope: "\f0e0";
+@fa-var-envelope-o: "\f003";
+@fa-var-envelope-square: "\f199";
+@fa-var-eraser: "\f12d";
+@fa-var-eur: "\f153";
+@fa-var-euro: "\f153";
+@fa-var-exchange: "\f0ec";
+@fa-var-exclamation: "\f12a";
+@fa-var-exclamation-circle: "\f06a";
+@fa-var-exclamation-triangle: "\f071";
+@fa-var-expand: "\f065";
+@fa-var-expeditedssl: "\f23e";
+@fa-var-external-link: "\f08e";
+@fa-var-external-link-square: "\f14c";
+@fa-var-eye: "\f06e";
+@fa-var-eye-slash: "\f070";
+@fa-var-eyedropper: "\f1fb";
+@fa-var-facebook: "\f09a";
+@fa-var-facebook-f: "\f09a";
+@fa-var-facebook-official: "\f230";
+@fa-var-facebook-square: "\f082";
+@fa-var-fast-backward: "\f049";
+@fa-var-fast-forward: "\f050";
+@fa-var-fax: "\f1ac";
+@fa-var-feed: "\f09e";
+@fa-var-female: "\f182";
+@fa-var-fighter-jet: "\f0fb";
+@fa-var-file: "\f15b";
+@fa-var-file-archive-o: "\f1c6";
+@fa-var-file-audio-o: "\f1c7";
+@fa-var-file-code-o: "\f1c9";
+@fa-var-file-excel-o: "\f1c3";
+@fa-var-file-image-o: "\f1c5";
+@fa-var-file-movie-o: "\f1c8";
+@fa-var-file-o: "\f016";
+@fa-var-file-pdf-o: "\f1c1";
+@fa-var-file-photo-o: "\f1c5";
+@fa-var-file-picture-o: "\f1c5";
+@fa-var-file-powerpoint-o: "\f1c4";
+@fa-var-file-sound-o: "\f1c7";
+@fa-var-file-text: "\f15c";
+@fa-var-file-text-o: "\f0f6";
+@fa-var-file-video-o: "\f1c8";
+@fa-var-file-word-o: "\f1c2";
+@fa-var-file-zip-o: "\f1c6";
+@fa-var-files-o: "\f0c5";
+@fa-var-film: "\f008";
+@fa-var-filter: "\f0b0";
+@fa-var-fire: "\f06d";
+@fa-var-fire-extinguisher: "\f134";
+@fa-var-firefox: "\f269";
+@fa-var-flag: "\f024";
+@fa-var-flag-checkered: "\f11e";
+@fa-var-flag-o: "\f11d";
+@fa-var-flash: "\f0e7";
+@fa-var-flask: "\f0c3";
+@fa-var-flickr: "\f16e";
+@fa-var-floppy-o: "\f0c7";
+@fa-var-folder: "\f07b";
+@fa-var-folder-o: "\f114";
+@fa-var-folder-open: "\f07c";
+@fa-var-folder-open-o: "\f115";
+@fa-var-font: "\f031";
+@fa-var-fonticons: "\f280";
+@fa-var-fort-awesome: "\f286";
+@fa-var-forumbee: "\f211";
+@fa-var-forward: "\f04e";
+@fa-var-foursquare: "\f180";
+@fa-var-frown-o: "\f119";
+@fa-var-futbol-o: "\f1e3";
+@fa-var-gamepad: "\f11b";
+@fa-var-gavel: "\f0e3";
+@fa-var-gbp: "\f154";
+@fa-var-ge: "\f1d1";
+@fa-var-gear: "\f013";
+@fa-var-gears: "\f085";
+@fa-var-genderless: "\f22d";
+@fa-var-get-pocket: "\f265";
+@fa-var-gg: "\f260";
+@fa-var-gg-circle: "\f261";
+@fa-var-gift: "\f06b";
+@fa-var-git: "\f1d3";
+@fa-var-git-square: "\f1d2";
+@fa-var-github: "\f09b";
+@fa-var-github-alt: "\f113";
+@fa-var-github-square: "\f092";
+@fa-var-gittip: "\f184";
+@fa-var-glass: "\f000";
+@fa-var-globe: "\f0ac";
+@fa-var-google: "\f1a0";
+@fa-var-google-plus: "\f0d5";
+@fa-var-google-plus-square: "\f0d4";
+@fa-var-google-wallet: "\f1ee";
+@fa-var-graduation-cap: "\f19d";
+@fa-var-gratipay: "\f184";
+@fa-var-group: "\f0c0";
+@fa-var-h-square: "\f0fd";
+@fa-var-hacker-news: "\f1d4";
+@fa-var-hand-grab-o: "\f255";
+@fa-var-hand-lizard-o: "\f258";
+@fa-var-hand-o-down: "\f0a7";
+@fa-var-hand-o-left: "\f0a5";
+@fa-var-hand-o-right: "\f0a4";
+@fa-var-hand-o-up: "\f0a6";
+@fa-var-hand-paper-o: "\f256";
+@fa-var-hand-peace-o: "\f25b";
+@fa-var-hand-pointer-o: "\f25a";
+@fa-var-hand-rock-o: "\f255";
+@fa-var-hand-scissors-o: "\f257";
+@fa-var-hand-spock-o: "\f259";
+@fa-var-hand-stop-o: "\f256";
+@fa-var-hashtag: "\f292";
+@fa-var-hdd-o: "\f0a0";
+@fa-var-header: "\f1dc";
+@fa-var-headphones: "\f025";
+@fa-var-heart: "\f004";
+@fa-var-heart-o: "\f08a";
+@fa-var-heartbeat: "\f21e";
+@fa-var-history: "\f1da";
+@fa-var-home: "\f015";
+@fa-var-hospital-o: "\f0f8";
+@fa-var-hotel: "\f236";
+@fa-var-hourglass: "\f254";
+@fa-var-hourglass-1: "\f251";
+@fa-var-hourglass-2: "\f252";
+@fa-var-hourglass-3: "\f253";
+@fa-var-hourglass-end: "\f253";
+@fa-var-hourglass-half: "\f252";
+@fa-var-hourglass-o: "\f250";
+@fa-var-hourglass-start: "\f251";
+@fa-var-houzz: "\f27c";
+@fa-var-html5: "\f13b";
+@fa-var-i-cursor: "\f246";
+@fa-var-ils: "\f20b";
+@fa-var-image: "\f03e";
+@fa-var-inbox: "\f01c";
+@fa-var-indent: "\f03c";
+@fa-var-industry: "\f275";
+@fa-var-info: "\f129";
+@fa-var-info-circle: "\f05a";
+@fa-var-inr: "\f156";
+@fa-var-instagram: "\f16d";
+@fa-var-institution: "\f19c";
+@fa-var-internet-explorer: "\f26b";
+@fa-var-intersex: "\f224";
+@fa-var-ioxhost: "\f208";
+@fa-var-italic: "\f033";
+@fa-var-joomla: "\f1aa";
+@fa-var-jpy: "\f157";
+@fa-var-jsfiddle: "\f1cc";
+@fa-var-key: "\f084";
+@fa-var-keyboard-o: "\f11c";
+@fa-var-krw: "\f159";
+@fa-var-language: "\f1ab";
+@fa-var-laptop: "\f109";
+@fa-var-lastfm: "\f202";
+@fa-var-lastfm-square: "\f203";
+@fa-var-leaf: "\f06c";
+@fa-var-leanpub: "\f212";
+@fa-var-legal: "\f0e3";
+@fa-var-lemon-o: "\f094";
+@fa-var-level-down: "\f149";
+@fa-var-level-up: "\f148";
+@fa-var-life-bouy: "\f1cd";
+@fa-var-life-buoy: "\f1cd";
+@fa-var-life-ring: "\f1cd";
+@fa-var-life-saver: "\f1cd";
+@fa-var-lightbulb-o: "\f0eb";
+@fa-var-line-chart: "\f201";
+@fa-var-link: "\f0c1";
+@fa-var-linkedin: "\f0e1";
+@fa-var-linkedin-square: "\f08c";
+@fa-var-linux: "\f17c";
+@fa-var-list: "\f03a";
+@fa-var-list-alt: "\f022";
+@fa-var-list-ol: "\f0cb";
+@fa-var-list-ul: "\f0ca";
+@fa-var-location-arrow: "\f124";
+@fa-var-lock: "\f023";
+@fa-var-long-arrow-down: "\f175";
+@fa-var-long-arrow-left: "\f177";
+@fa-var-long-arrow-right: "\f178";
+@fa-var-long-arrow-up: "\f176";
+@fa-var-magic: "\f0d0";
+@fa-var-magnet: "\f076";
+@fa-var-mail-forward: "\f064";
+@fa-var-mail-reply: "\f112";
+@fa-var-mail-reply-all: "\f122";
+@fa-var-male: "\f183";
+@fa-var-map: "\f279";
+@fa-var-map-marker: "\f041";
+@fa-var-map-o: "\f278";
+@fa-var-map-pin: "\f276";
+@fa-var-map-signs: "\f277";
+@fa-var-mars: "\f222";
+@fa-var-mars-double: "\f227";
+@fa-var-mars-stroke: "\f229";
+@fa-var-mars-stroke-h: "\f22b";
+@fa-var-mars-stroke-v: "\f22a";
+@fa-var-maxcdn: "\f136";
+@fa-var-meanpath: "\f20c";
+@fa-var-medium: "\f23a";
+@fa-var-medkit: "\f0fa";
+@fa-var-meh-o: "\f11a";
+@fa-var-mercury: "\f223";
+@fa-var-microphone: "\f130";
+@fa-var-microphone-slash: "\f131";
+@fa-var-minus: "\f068";
+@fa-var-minus-circle: "\f056";
+@fa-var-minus-square: "\f146";
+@fa-var-minus-square-o: "\f147";
+@fa-var-mixcloud: "\f289";
+@fa-var-mobile: "\f10b";
+@fa-var-mobile-phone: "\f10b";
+@fa-var-modx: "\f285";
+@fa-var-money: "\f0d6";
+@fa-var-moon-o: "\f186";
+@fa-var-mortar-board: "\f19d";
+@fa-var-motorcycle: "\f21c";
+@fa-var-mouse-pointer: "\f245";
+@fa-var-music: "\f001";
+@fa-var-navicon: "\f0c9";
+@fa-var-neuter: "\f22c";
+@fa-var-newspaper-o: "\f1ea";
+@fa-var-object-group: "\f247";
+@fa-var-object-ungroup: "\f248";
+@fa-var-odnoklassniki: "\f263";
+@fa-var-odnoklassniki-square: "\f264";
+@fa-var-opencart: "\f23d";
+@fa-var-openid: "\f19b";
+@fa-var-opera: "\f26a";
+@fa-var-optin-monster: "\f23c";
+@fa-var-outdent: "\f03b";
+@fa-var-pagelines: "\f18c";
+@fa-var-paint-brush: "\f1fc";
+@fa-var-paper-plane: "\f1d8";
+@fa-var-paper-plane-o: "\f1d9";
+@fa-var-paperclip: "\f0c6";
+@fa-var-paragraph: "\f1dd";
+@fa-var-paste: "\f0ea";
+@fa-var-pause: "\f04c";
+@fa-var-pause-circle: "\f28b";
+@fa-var-pause-circle-o: "\f28c";
+@fa-var-paw: "\f1b0";
+@fa-var-paypal: "\f1ed";
+@fa-var-pencil: "\f040";
+@fa-var-pencil-square: "\f14b";
+@fa-var-pencil-square-o: "\f044";
+@fa-var-percent: "\f295";
+@fa-var-phone: "\f095";
+@fa-var-phone-square: "\f098";
+@fa-var-photo: "\f03e";
+@fa-var-picture-o: "\f03e";
+@fa-var-pie-chart: "\f200";
+@fa-var-pied-piper: "\f1a7";
+@fa-var-pied-piper-alt: "\f1a8";
+@fa-var-pinterest: "\f0d2";
+@fa-var-pinterest-p: "\f231";
+@fa-var-pinterest-square: "\f0d3";
+@fa-var-plane: "\f072";
+@fa-var-play: "\f04b";
+@fa-var-play-circle: "\f144";
+@fa-var-play-circle-o: "\f01d";
+@fa-var-plug: "\f1e6";
+@fa-var-plus: "\f067";
+@fa-var-plus-circle: "\f055";
+@fa-var-plus-square: "\f0fe";
+@fa-var-plus-square-o: "\f196";
+@fa-var-power-off: "\f011";
+@fa-var-print: "\f02f";
+@fa-var-product-hunt: "\f288";
+@fa-var-puzzle-piece: "\f12e";
+@fa-var-qq: "\f1d6";
+@fa-var-qrcode: "\f029";
+@fa-var-question: "\f128";
+@fa-var-question-circle: "\f059";
+@fa-var-quote-left: "\f10d";
+@fa-var-quote-right: "\f10e";
+@fa-var-ra: "\f1d0";
+@fa-var-random: "\f074";
+@fa-var-rebel: "\f1d0";
+@fa-var-recycle: "\f1b8";
+@fa-var-reddit: "\f1a1";
+@fa-var-reddit-alien: "\f281";
+@fa-var-reddit-square: "\f1a2";
+@fa-var-refresh: "\f021";
+@fa-var-registered: "\f25d";
+@fa-var-remove: "\f00d";
+@fa-var-renren: "\f18b";
+@fa-var-reorder: "\f0c9";
+@fa-var-repeat: "\f01e";
+@fa-var-reply: "\f112";
+@fa-var-reply-all: "\f122";
+@fa-var-retweet: "\f079";
+@fa-var-rmb: "\f157";
+@fa-var-road: "\f018";
+@fa-var-rocket: "\f135";
+@fa-var-rotate-left: "\f0e2";
+@fa-var-rotate-right: "\f01e";
+@fa-var-rouble: "\f158";
+@fa-var-rss: "\f09e";
+@fa-var-rss-square: "\f143";
+@fa-var-rub: "\f158";
+@fa-var-ruble: "\f158";
+@fa-var-rupee: "\f156";
+@fa-var-safari: "\f267";
+@fa-var-save: "\f0c7";
+@fa-var-scissors: "\f0c4";
+@fa-var-scribd: "\f28a";
+@fa-var-search: "\f002";
+@fa-var-search-minus: "\f010";
+@fa-var-search-plus: "\f00e";
+@fa-var-sellsy: "\f213";
+@fa-var-send: "\f1d8";
+@fa-var-send-o: "\f1d9";
+@fa-var-server: "\f233";
+@fa-var-share: "\f064";
+@fa-var-share-alt: "\f1e0";
+@fa-var-share-alt-square: "\f1e1";
+@fa-var-share-square: "\f14d";
+@fa-var-share-square-o: "\f045";
+@fa-var-shekel: "\f20b";
+@fa-var-sheqel: "\f20b";
+@fa-var-shield: "\f132";
+@fa-var-ship: "\f21a";
+@fa-var-shirtsinbulk: "\f214";
+@fa-var-shopping-bag: "\f290";
+@fa-var-shopping-basket: "\f291";
+@fa-var-shopping-cart: "\f07a";
+@fa-var-sign-in: "\f090";
+@fa-var-sign-out: "\f08b";
+@fa-var-signal: "\f012";
+@fa-var-simplybuilt: "\f215";
+@fa-var-sitemap: "\f0e8";
+@fa-var-skyatlas: "\f216";
+@fa-var-skype: "\f17e";
+@fa-var-slack: "\f198";
+@fa-var-sliders: "\f1de";
+@fa-var-slideshare: "\f1e7";
+@fa-var-smile-o: "\f118";
+@fa-var-soccer-ball-o: "\f1e3";
+@fa-var-sort: "\f0dc";
+@fa-var-sort-alpha-asc: "\f15d";
+@fa-var-sort-alpha-desc: "\f15e";
+@fa-var-sort-amount-asc: "\f160";
+@fa-var-sort-amount-desc: "\f161";
+@fa-var-sort-asc: "\f0de";
+@fa-var-sort-desc: "\f0dd";
+@fa-var-sort-down: "\f0dd";
+@fa-var-sort-numeric-asc: "\f162";
+@fa-var-sort-numeric-desc: "\f163";
+@fa-var-sort-up: "\f0de";
+@fa-var-soundcloud: "\f1be";
+@fa-var-space-shuttle: "\f197";
+@fa-var-spinner: "\f110";
+@fa-var-spoon: "\f1b1";
+@fa-var-spotify: "\f1bc";
+@fa-var-square: "\f0c8";
+@fa-var-square-o: "\f096";
+@fa-var-stack-exchange: "\f18d";
+@fa-var-stack-overflow: "\f16c";
+@fa-var-star: "\f005";
+@fa-var-star-half: "\f089";
+@fa-var-star-half-empty: "\f123";
+@fa-var-star-half-full: "\f123";
+@fa-var-star-half-o: "\f123";
+@fa-var-star-o: "\f006";
+@fa-var-steam: "\f1b6";
+@fa-var-steam-square: "\f1b7";
+@fa-var-step-backward: "\f048";
+@fa-var-step-forward: "\f051";
+@fa-var-stethoscope: "\f0f1";
+@fa-var-sticky-note: "\f249";
+@fa-var-sticky-note-o: "\f24a";
+@fa-var-stop: "\f04d";
+@fa-var-stop-circle: "\f28d";
+@fa-var-stop-circle-o: "\f28e";
+@fa-var-street-view: "\f21d";
+@fa-var-strikethrough: "\f0cc";
+@fa-var-stumbleupon: "\f1a4";
+@fa-var-stumbleupon-circle: "\f1a3";
+@fa-var-subscript: "\f12c";
+@fa-var-subway: "\f239";
+@fa-var-suitcase: "\f0f2";
+@fa-var-sun-o: "\f185";
+@fa-var-superscript: "\f12b";
+@fa-var-support: "\f1cd";
+@fa-var-table: "\f0ce";
+@fa-var-tablet: "\f10a";
+@fa-var-tachometer: "\f0e4";
+@fa-var-tag: "\f02b";
+@fa-var-tags: "\f02c";
+@fa-var-tasks: "\f0ae";
+@fa-var-taxi: "\f1ba";
+@fa-var-television: "\f26c";
+@fa-var-tencent-weibo: "\f1d5";
+@fa-var-terminal: "\f120";
+@fa-var-text-height: "\f034";
+@fa-var-text-width: "\f035";
+@fa-var-th: "\f00a";
+@fa-var-th-large: "\f009";
+@fa-var-th-list: "\f00b";
+@fa-var-thumb-tack: "\f08d";
+@fa-var-thumbs-down: "\f165";
+@fa-var-thumbs-o-down: "\f088";
+@fa-var-thumbs-o-up: "\f087";
+@fa-var-thumbs-up: "\f164";
+@fa-var-ticket: "\f145";
+@fa-var-times: "\f00d";
+@fa-var-times-circle: "\f057";
+@fa-var-times-circle-o: "\f05c";
+@fa-var-tint: "\f043";
+@fa-var-toggle-down: "\f150";
+@fa-var-toggle-left: "\f191";
+@fa-var-toggle-off: "\f204";
+@fa-var-toggle-on: "\f205";
+@fa-var-toggle-right: "\f152";
+@fa-var-toggle-up: "\f151";
+@fa-var-trademark: "\f25c";
+@fa-var-train: "\f238";
+@fa-var-transgender: "\f224";
+@fa-var-transgender-alt: "\f225";
+@fa-var-trash: "\f1f8";
+@fa-var-trash-o: "\f014";
+@fa-var-tree: "\f1bb";
+@fa-var-trello: "\f181";
+@fa-var-tripadvisor: "\f262";
+@fa-var-trophy: "\f091";
+@fa-var-truck: "\f0d1";
+@fa-var-try: "\f195";
+@fa-var-tty: "\f1e4";
+@fa-var-tumblr: "\f173";
+@fa-var-tumblr-square: "\f174";
+@fa-var-turkish-lira: "\f195";
+@fa-var-tv: "\f26c";
+@fa-var-twitch: "\f1e8";
+@fa-var-twitter: "\f099";
+@fa-var-twitter-square: "\f081";
+@fa-var-umbrella: "\f0e9";
+@fa-var-underline: "\f0cd";
+@fa-var-undo: "\f0e2";
+@fa-var-university: "\f19c";
+@fa-var-unlink: "\f127";
+@fa-var-unlock: "\f09c";
+@fa-var-unlock-alt: "\f13e";
+@fa-var-unsorted: "\f0dc";
+@fa-var-upload: "\f093";
+@fa-var-usb: "\f287";
+@fa-var-usd: "\f155";
+@fa-var-user: "\f007";
+@fa-var-user-md: "\f0f0";
+@fa-var-user-plus: "\f234";
+@fa-var-user-secret: "\f21b";
+@fa-var-user-times: "\f235";
+@fa-var-users: "\f0c0";
+@fa-var-venus: "\f221";
+@fa-var-venus-double: "\f226";
+@fa-var-venus-mars: "\f228";
+@fa-var-viacoin: "\f237";
+@fa-var-video-camera: "\f03d";
+@fa-var-vimeo: "\f27d";
+@fa-var-vimeo-square: "\f194";
+@fa-var-vine: "\f1ca";
+@fa-var-vk: "\f189";
+@fa-var-volume-down: "\f027";
+@fa-var-volume-off: "\f026";
+@fa-var-volume-up: "\f028";
+@fa-var-warning: "\f071";
+@fa-var-wechat: "\f1d7";
+@fa-var-weibo: "\f18a";
+@fa-var-weixin: "\f1d7";
+@fa-var-whatsapp: "\f232";
+@fa-var-wheelchair: "\f193";
+@fa-var-wifi: "\f1eb";
+@fa-var-wikipedia-w: "\f266";
+@fa-var-windows: "\f17a";
+@fa-var-won: "\f159";
+@fa-var-wordpress: "\f19a";
+@fa-var-wrench: "\f0ad";
+@fa-var-xing: "\f168";
+@fa-var-xing-square: "\f169";
+@fa-var-y-combinator: "\f23b";
+@fa-var-y-combinator-square: "\f1d4";
+@fa-var-yahoo: "\f19e";
+@fa-var-yc: "\f23b";
+@fa-var-yc-square: "\f1d4";
+@fa-var-yelp: "\f1e9";
+@fa-var-yen: "\f157";
+@fa-var-youtube: "\f167";
+@fa-var-youtube-play: "\f16a";
+@fa-var-youtube-square: "\f166";
+

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_animated.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_animated.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_animated.scss
new file mode 100644
index 0000000..8a020db
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_animated.scss
@@ -0,0 +1,34 @@
+// Spinning Icons
+// --------------------------
+
+.#{$fa-css-prefix}-spin {
+  -webkit-animation: fa-spin 2s infinite linear;
+          animation: fa-spin 2s infinite linear;
+}
+
+.#{$fa-css-prefix}-pulse {
+  -webkit-animation: fa-spin 1s infinite steps(8);
+          animation: fa-spin 1s infinite steps(8);
+}
+
+@-webkit-keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+            transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+            transform: rotate(359deg);
+  }
+}
+
+@keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+            transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+            transform: rotate(359deg);
+  }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_bordered-pulled.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_bordered-pulled.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_bordered-pulled.scss
new file mode 100644
index 0000000..d4b85a0
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_bordered-pulled.scss
@@ -0,0 +1,25 @@
+// Bordered & Pulled
+// -------------------------
+
+.#{$fa-css-prefix}-border {
+  padding: .2em .25em .15em;
+  border: solid .08em $fa-border-color;
+  border-radius: .1em;
+}
+
+.#{$fa-css-prefix}-pull-left { float: left; }
+.#{$fa-css-prefix}-pull-right { float: right; }
+
+.#{$fa-css-prefix} {
+  &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
+  &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
+}
+
+/* Deprecated as of 4.4.0 */
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.#{$fa-css-prefix} {
+  &.pull-left { margin-right: .3em; }
+  &.pull-right { margin-left: .3em; }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_core.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_core.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_core.scss
new file mode 100644
index 0000000..7425ef8
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_core.scss
@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.#{$fa-css-prefix} {
+  display: inline-block;
+  font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
+  font-size: inherit; // can't have font-size inherit on line above, so need to override
+  text-rendering: auto; // optimizelegibility throws things off #1094
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/631292f7/src/main/webapp/assets/js/libs/font-awesome/scss/_fixed-width.scss
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/libs/font-awesome/scss/_fixed-width.scss b/src/main/webapp/assets/js/libs/font-awesome/scss/_fixed-width.scss
new file mode 100644
index 0000000..b221c98
--- /dev/null
+++ b/src/main/webapp/assets/js/libs/font-awesome/scss/_fixed-width.scss
@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.#{$fa-css-prefix}-fw {
+  width: (18em / 14);
+  text-align: center;
+}


[11/27] brooklyn-ui git commit: minor bug fixes

Posted by he...@apache.org.
minor bug fixes


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/438132fc
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/438132fc
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/438132fc

Branch: refs/heads/master
Commit: 438132fcf49e7c97fafc6c334cfcdbe00a40cea7
Parents: 4cd4fea
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Feb 11 18:03:26 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 11 18:03:26 2016 +0000

----------------------------------------------------------------------
 .../assets/js/view/application-add-wizard.js    | 41 ++++++++++----------
 src/main/webapp/assets/js/view/editor.js        |  3 --
 2 files changed, 21 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/438132fc/src/main/webapp/assets/js/view/application-add-wizard.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/application-add-wizard.js b/src/main/webapp/assets/js/view/application-add-wizard.js
index 1436eea..f57023a 100644
--- a/src/main/webapp/assets/js/view/application-add-wizard.js
+++ b/src/main/webapp/assets/js/view/application-add-wizard.js
@@ -97,6 +97,20 @@ define([
             return value;
         }
     }
+
+    function redirectToEditorTabToDeployId(catalogId){
+        redirectTo("/v1/editor/app/"+ (typeof catalogId === 'string' ? catalogId : '')); 
+    }
+    function redirectToEditorTabToDeployYaml(yaml){
+        redirectTo("/v1/editor/app/_/"+encodeURIComponent(yaml));
+    }
+    function redirectTo(url){
+        var $modal = $('.add-app #modal-container .modal');
+        $modal.modal('hide');
+        $modal.fadeTo(500,1);
+        Backbone.history.navigate(url, {trigger: true});
+    }
+        
     
     var ModalWizard = Backbone.View.extend({
         tagName:'div',
@@ -206,7 +220,8 @@ define([
             var nextEnabled = true;
             if (this.currentStep==0 && currentStepObj && currentStepObj.view) {
                 // disable if nothing is selected in template (app lozenge list) view
-                if (! currentStepObj.view.selectedTemplate)
+                // or if it is a template with a location
+                if (!currentStepObj.view.selectedTemplate || isTemplateWithLocation)
                     nextEnabled = false;
             }
                 
@@ -291,9 +306,9 @@ define([
             if (this.currentStep==0) {
                 // from first step, composer should load yaml from the catalog item
                 if (this.currentView.selectedTemplate && this.currentView.selectedTemplate.id) {
-                    this.redirectToEditorTabToDeployId(this.currentView.selectedTemplate.id);
+                    redirectToEditorTabToDeployId(this.currentView.selectedTemplate.id);
                 } else {
-                    this.redirectToEditorTabToDeployId();
+                    redirectToEditorTabToDeployId();
                 }
             } else {
                 // on second step we generate yaml
@@ -301,7 +316,7 @@ define([
                 this.model.spec.pruneLocations();
                 var yaml = JsYaml.safeDump(oldSpecToCamp(this.model.spec.toJSON()));
 
-                this.redirectToEditorTabToDeployYaml(yaml);
+                redirectToEditorTabToDeployYaml(yaml);
             }
         },
         finishStep:function () {
@@ -311,19 +326,6 @@ define([
                 // call to validate should showFailure
             }
         },
-        
-        redirectToEditorTabToDeployId: function(catalogId){
-            this.redirectTo("/v1/editor/app/"+ (typeof catalogId === 'string' ? catalogId : '')); 
-        },
-        redirectToEditorTabToDeployYaml: function(yaml){
-            this.redirectTo("/v1/editor/app/_/"+encodeURIComponent(yaml));
-        },
-        redirectTo: function(url){
-            var $modal = $('.add-app #modal-container .modal');
-            $modal.modal('hide');
-            $modal.fadeTo(500,1);
-            Backbone.history.navigate(url, {trigger: true});
-        },
     })
     
     // Note: this does not restore values on a back click; setting type and entity type+name is easy,
@@ -368,7 +370,6 @@ define([
                         self.addTemplateLozenges();
                     } else {
                         $('#catalog-applications-empty').show();
-                        self.showYamlTab();
                     }
                 }
             });
@@ -405,8 +406,8 @@ define([
             $modal.modal('hide');
             window.location.href="#v1/catalog/new";
         },
-        redirectToEditorTab: function() {
-            this.redirectToEditorTabToDeployId();
+        redirectToEditorTab: function () {
+            redirectToEditorTabToDeployId();
         },
         applyFilter: function(e) {
             var filter = $(e.currentTarget).val().toLowerCase()

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/438132fc/src/main/webapp/assets/js/view/editor.js
----------------------------------------------------------------------
diff --git a/src/main/webapp/assets/js/view/editor.js b/src/main/webapp/assets/js/view/editor.js
index f9ce5b6..d867080 100644
--- a/src/main/webapp/assets/js/view/editor.js
+++ b/src/main/webapp/assets/js/view/editor.js
@@ -179,7 +179,6 @@ define([
                 });
                 var that = this;
                 this.editor.on("changes", function(editor, changes) {
-                    console.log("editor changed", editor, changes);
                     that.refreshOnMinorChange();
                 });
             }
@@ -209,7 +208,6 @@ define([
             var yaml = this.editor.getValue();
             try{
                 var parsed = this.parse(true);
-                console.log('parse', parsed);
                 if (parsed.problem) throw parsed.problem;
                 if (this.mode!=MODE_CATALOG && parsed.result['brooklyn.catalog'] &&
                       !parsed.result['services']) {
@@ -233,7 +231,6 @@ define([
                     "    iconUrl: http://www.apache.org/foundation/press/kit/poweredBy/Apache_PoweredBy.png\n"+
                     "    itemType: template\n"+
                     "    item:\n"+
-                    "    - \n"+
                 // indent 6 spaces:
                 this.editor.getValue().replace(/^(.*$)/gm,'      $1');
                 this.mode = MODE_CATALOG;